From 7833aa0a40980d2a378be6abe174128c8eeccad1 Mon Sep 17 00:00:00 2001 From: Magnus Svensson Date: Mon, 27 Oct 2025 12:28:18 +0100 Subject: [PATCH 01/23] Vendoring. --- go.mod | 1 + go.sum | 2 + vendor/go.mongodb.org/mongo-driver/v2/LICENSE | 201 ++ .../mongo-driver/v2/bson/array_codec.go | 42 + .../mongo-driver/v2/bson/bsoncodec.go | 203 ++ .../mongo-driver/v2/bson/buffered_byte_src.go | 128 + .../mongo-driver/v2/bson/byte_slice_codec.go | 97 + .../mongo-driver/v2/bson/codec_cache.go | 166 ++ .../mongo-driver/v2/bson/cond_addr_codec.go | 61 + .../mongo-driver/v2/bson/copier.go | 433 ++++ .../mongo-driver/v2/bson/decimal.go | 339 +++ .../mongo-driver/v2/bson/decoder.go | 136 + .../v2/bson/default_value_decoders.go | 1518 +++++++++++ .../v2/bson/default_value_encoders.go | 517 ++++ .../mongo-driver/v2/bson/doc.go | 141 + .../v2/bson/empty_interface_codec.go | 127 + .../mongo-driver/v2/bson/encoder.go | 130 + .../mongo-driver/v2/bson/extjson_parser.go | 804 ++++++ .../mongo-driver/v2/bson/extjson_reader.go | 606 +++++ .../mongo-driver/v2/bson/extjson_tables.go | 223 ++ .../mongo-driver/v2/bson/extjson_wrappers.go | 489 ++++ .../mongo-driver/v2/bson/extjson_writer.go | 690 +++++ .../mongo-driver/v2/bson/json_scanner.go | 533 ++++ .../mongo-driver/v2/bson/map_codec.go | 292 +++ .../mongo-driver/v2/bson/marshal.go | 191 ++ .../mongo-driver/v2/bson/mgoregistry.go | 209 ++ .../mongo-driver/v2/bson/mode.go | 82 + .../mongo-driver/v2/bson/objectid.go | 207 ++ .../mongo-driver/v2/bson/pointer_codec.go | 88 + .../mongo-driver/v2/bson/primitive.go | 379 +++ .../mongo-driver/v2/bson/primitive_codecs.go | 89 + .../mongo-driver/v2/bson/raw.go | 93 + .../mongo-driver/v2/bson/raw_array.go | 73 + .../mongo-driver/v2/bson/raw_element.go | 48 + .../mongo-driver/v2/bson/raw_value.go | 306 +++ .../mongo-driver/v2/bson/reader.go | 49 + .../mongo-driver/v2/bson/registry.go | 381 +++ .../mongo-driver/v2/bson/slice_codec.go | 173 ++ .../v2/bson/streaming_byte_src.go | 104 + .../mongo-driver/v2/bson/string_codec.go | 107 + .../mongo-driver/v2/bson/struct_codec.go | 695 +++++ .../mongo-driver/v2/bson/struct_tag_parser.go | 123 + .../mongo-driver/v2/bson/time_codec.go | 109 + .../mongo-driver/v2/bson/types.go | 118 + .../mongo-driver/v2/bson/uint_codec.go | 161 ++ .../mongo-driver/v2/bson/unmarshal.go | 90 + .../mongo-driver/v2/bson/value_reader.go | 960 +++++++ .../mongo-driver/v2/bson/value_writer.go | 600 +++++ .../mongo-driver/v2/bson/vector.go | 268 ++ .../mongo-driver/v2/bson/writer.go | 61 + .../mongo-driver/v2/event/description.go | 58 + .../mongo-driver/v2/event/doc.go | 56 + .../mongo-driver/v2/event/monitoring.go | 193 ++ .../v2/internal/aws/awserr/error.go | 60 + .../v2/internal/aws/awserr/types.go | 144 ++ .../aws/credentials/chain_provider.go | 72 + .../internal/aws/credentials/credentials.go | 197 ++ .../v2/internal/aws/signer/v4/header_rules.go | 51 + .../v2/internal/aws/signer/v4/request.go | 80 + .../v2/internal/aws/signer/v4/uri_path.go | 65 + .../v2/internal/aws/signer/v4/v4.go | 421 +++ .../mongo-driver/v2/internal/aws/types.go | 153 ++ .../v2/internal/bsoncoreutil/bsoncoreutil.go | 40 + .../v2/internal/bsonutil/bsonutil.go | 62 + .../v2/internal/codecutil/encoding.go | 64 + .../credproviders/assume_role_provider.go | 148 ++ .../v2/internal/credproviders/ec2_provider.go | 183 ++ .../v2/internal/credproviders/ecs_provider.go | 112 + .../v2/internal/credproviders/env_provider.go | 69 + .../internal/credproviders/imds_provider.go | 103 + .../internal/credproviders/static_provider.go | 59 + .../mongo-driver/v2/internal/csfle/csfle.go | 40 + .../mongo-driver/v2/internal/csot/csot.go | 106 + .../v2/internal/decimal128/decinal128.go | 117 + .../v2/internal/driverutil/description.go | 493 ++++ .../v2/internal/driverutil/hello.go | 128 + .../v2/internal/driverutil/operation.go | 69 + .../v2/internal/handshake/handshake.go | 13 + .../v2/internal/httputil/httputil.go | 38 + .../v2/internal/logger/component.go | 313 +++ .../v2/internal/logger/context.go | 48 + .../v2/internal/logger/io_sink.go | 63 + .../mongo-driver/v2/internal/logger/level.go | 74 + .../mongo-driver/v2/internal/logger/logger.go | 264 ++ .../v2/internal/mongoutil/mongoutil.go | 101 + .../v2/internal/optionsutil/options.go | 45 + .../mongo-driver/v2/internal/ptrutil/int64.go | 39 + .../mongo-driver/v2/internal/ptrutil/ptr.go | 12 + .../mongo-driver/v2/internal/rand/bits.go | 38 + .../mongo-driver/v2/internal/rand/exp.go | 223 ++ .../mongo-driver/v2/internal/rand/normal.go | 158 ++ .../mongo-driver/v2/internal/rand/rand.go | 374 +++ .../mongo-driver/v2/internal/rand/rng.go | 93 + .../v2/internal/randutil/randutil.go | 39 + .../serverselector/server_selector.go | 359 +++ .../mongo-driver/v2/internal/uuid/uuid.go | 68 + .../mongo-driver/v2/mongo/address/addr.go | 53 + .../v2/mongo/background_context.go | 34 + .../mongo-driver/v2/mongo/batch_cursor.go | 70 + .../mongo-driver/v2/mongo/bulk_write.go | 622 +++++ .../v2/mongo/bulk_write_models.go | 342 +++ .../mongo-driver/v2/mongo/change_stream.go | 781 ++++++ .../v2/mongo/change_stream_deployment.go | 58 + .../mongo-driver/v2/mongo/client.go | 998 ++++++++ .../v2/mongo/client_bulk_write.go | 723 ++++++ .../v2/mongo/client_bulk_write_models.go | 318 +++ .../v2/mongo/client_encryption.go | 519 ++++ .../mongo-driver/v2/mongo/collection.go | 2255 ++++++++++++++++ .../mongo-driver/v2/mongo/crypt_retrievers.go | 65 + .../mongo-driver/v2/mongo/cursor.go | 492 ++++ .../mongo-driver/v2/mongo/database.go | 992 ++++++++ .../mongo-driver/v2/mongo/doc.go | 164 ++ .../mongo-driver/v2/mongo/errors.go | 903 +++++++ .../mongo-driver/v2/mongo/gridfs_bucket.go | 585 +++++ .../v2/mongo/gridfs_download_stream.go | 299 +++ .../v2/mongo/gridfs_upload_stream.go | 209 ++ .../mongo-driver/v2/mongo/index_view.go | 554 ++++ .../mongo-driver/v2/mongo/mongo.go | 436 ++++ .../mongo-driver/v2/mongo/mongocryptd.go | 164 ++ .../v2/mongo/options/aggregateoptions.go | 170 ++ .../v2/mongo/options/autoencryptionoptions.go | 176 ++ .../v2/mongo/options/bulkwriteoptions.go | 100 + .../v2/mongo/options/changestreamoptions.go | 183 ++ .../mongo/options/clientbulkwriteoptions.go | 127 + .../mongo/options/clientencryptionoptions.go | 158 ++ .../v2/mongo/options/clientoptions.go | 1334 ++++++++++ .../v2/mongo/options/collectionoptions.go | 105 + .../v2/mongo/options/countoptions.go | 107 + .../mongo/options/createcollectionoptions.go | 413 +++ .../v2/mongo/options/datakeyoptions.go | 107 + .../v2/mongo/options/dboptions.go | 106 + .../v2/mongo/options/deleteoptions.go | 191 ++ .../v2/mongo/options/distinctoptions.go | 85 + .../mongo-driver/v2/mongo/options/doc.go | 8 + .../v2/mongo/options/dropcollectionoptions.go | 45 + .../v2/mongo/options/encryptoptions.go | 205 ++ .../v2/mongo/options/estimatedcountoptions.go | 52 + .../v2/mongo/options/findoptions.go | 910 +++++++ .../v2/mongo/options/gridfsoptions.go | 342 +++ .../v2/mongo/options/indexoptions.go | 486 ++++ .../v2/mongo/options/insertoptions.go | 133 + .../mongo/options/listcollectionsoptions.go | 78 + .../v2/mongo/options/listdatabasesoptions.go | 54 + .../mongo-driver/v2/mongo/options/lister.go | 13 + .../v2/mongo/options/loggeroptions.go | 115 + .../v2/mongo/options/mongooptions.go | 70 + .../v2/mongo/options/replaceoptions.go | 144 ++ .../v2/mongo/options/rewrapdatakeyoptions.go | 57 + .../v2/mongo/options/runcmdoptions.go | 49 + .../v2/mongo/options/searchindexoptions.go | 118 + .../v2/mongo/options/serverapioptions.go | 66 + .../v2/mongo/options/sessionoptions.go | 71 + .../v2/mongo/options/transactionoptions.go | 79 + .../v2/mongo/options/updateoptions.go | 293 +++ .../v2/mongo/readconcern/readconcern.go | 65 + .../mongo-driver/v2/mongo/readpref/mode.go | 88 + .../mongo-driver/v2/mongo/readpref/options.go | 88 + .../v2/mongo/readpref/readpref.go | 137 + .../mongo-driver/v2/mongo/results.go | 286 +++ .../v2/mongo/search_index_view.go | 290 +++ .../mongo-driver/v2/mongo/session.go | 346 +++ .../mongo-driver/v2/mongo/single_result.go | 140 + .../v2/mongo/writeconcern/writeconcern.go | 132 + .../go.mongodb.org/mongo-driver/v2/tag/tag.go | 89 + .../mongo-driver/v2/version/version.go | 14 + .../mongo-driver/v2/x/bsonx/bsoncore/array.go | 208 ++ .../v2/x/bsonx/bsoncore/bson_arraybuilder.go | 198 ++ .../x/bsonx/bsoncore/bson_documentbuilder.go | 184 ++ .../v2/x/bsonx/bsoncore/bsoncore.go | 842 ++++++ .../mongo-driver/v2/x/bsonx/bsoncore/doc.go | 34 + .../v2/x/bsonx/bsoncore/document.go | 429 ++++ .../v2/x/bsonx/bsoncore/element.go | 213 ++ .../v2/x/bsonx/bsoncore/iterator.go | 113 + .../v2/x/bsonx/bsoncore/tables.go | 223 ++ .../mongo-driver/v2/x/bsonx/bsoncore/type.go | 85 + .../mongo-driver/v2/x/bsonx/bsoncore/value.go | 985 +++++++ .../v2/x/mongo/driver/auth/auth.go | 248 ++ .../v2/x/mongo/driver/auth/aws_conv.go | 188 ++ .../v2/x/mongo/driver/auth/conversation.go | 32 + .../v2/x/mongo/driver/auth/cred.go | 14 + .../v2/x/mongo/driver/auth/creds/awscreds.go | 58 + .../x/mongo/driver/auth/creds/azurecreds.go | 40 + .../v2/x/mongo/driver/auth/creds/doc.go | 14 + .../v2/x/mongo/driver/auth/creds/gcpcreds.go | 74 + .../v2/x/mongo/driver/auth/default.go | 80 + .../v2/x/mongo/driver/auth/doc.go | 14 + .../v2/x/mongo/driver/auth/gssapi.go | 66 + .../x/mongo/driver/auth/gssapi_not_enabled.go | 19 + .../mongo/driver/auth/gssapi_not_supported.go | 23 + .../mongo/driver/auth/internal/gssapi/gss.go | 168 ++ .../driver/auth/internal/gssapi/gss_wrapper.c | 254 ++ .../driver/auth/internal/gssapi/gss_wrapper.h | 72 + .../mongo/driver/auth/internal/gssapi/sspi.go | 354 +++ .../auth/internal/gssapi/sspi_wrapper.c | 249 ++ .../auth/internal/gssapi/sspi_wrapper.h | 64 + .../v2/x/mongo/driver/auth/mongodbaws.go | 92 + .../v2/x/mongo/driver/auth/oidc.go | 592 +++++ .../v2/x/mongo/driver/auth/plain.go | 78 + .../v2/x/mongo/driver/auth/sasl.go | 173 ++ .../v2/x/mongo/driver/auth/scram.go | 144 ++ .../v2/x/mongo/driver/auth/util.go | 30 + .../v2/x/mongo/driver/auth/x509.go | 87 + .../v2/x/mongo/driver/batch_cursor.go | 591 +++++ .../mongo-driver/v2/x/mongo/driver/batches.go | 116 + .../v2/x/mongo/driver/compression.go | 194 ++ .../x/mongo/driver/connstring/connstring.go | 1083 ++++++++ .../mongo-driver/v2/x/mongo/driver/crypt.go | 416 +++ .../v2/x/mongo/driver/description/server.go | 144 ++ .../v2/x/mongo/driver/description/topology.go | 60 + .../mongo-driver/v2/x/mongo/driver/dns/dns.go | 156 ++ .../mongo-driver/v2/x/mongo/driver/driver.go | 292 +++ .../mongo-driver/v2/x/mongo/driver/errors.go | 568 +++++ .../mongo-driver/v2/x/mongo/driver/legacy.go | 23 + .../v2/x/mongo/driver/mnet/connection.go | 120 + .../v2/x/mongo/driver/mongocrypt/binary.go | 63 + .../v2/x/mongo/driver/mongocrypt/errors.go | 44 + .../driver/mongocrypt/errors_not_enabled.go | 21 + .../x/mongo/driver/mongocrypt/mongocrypt.go | 537 ++++ .../driver/mongocrypt/mongocrypt_context.go | 115 + .../mongocrypt_context_not_enabled.go | 62 + .../mongocrypt/mongocrypt_kms_context.go | 87 + .../mongocrypt_kms_context_not_enabled.go | 44 + .../mongocrypt/mongocrypt_not_enabled.go | 97 + .../x/mongo/driver/mongocrypt/options/doc.go | 14 + .../options/mongocrypt_context_options.go | 137 + .../mongocrypt/options/mongocrypt_options.go | 81 + .../v2/x/mongo/driver/mongocrypt/state.go | 47 + .../v2/x/mongo/driver/ocsp/cache.go | 121 + .../v2/x/mongo/driver/ocsp/config.go | 68 + .../v2/x/mongo/driver/ocsp/ocsp.go | 328 +++ .../v2/x/mongo/driver/ocsp/options.go | 16 + .../v2/x/mongo/driver/operation.go | 2263 +++++++++++++++++ .../driver/operation/abort_transaction.go | 212 ++ .../v2/x/mongo/driver/operation/aggregate.go | 448 ++++ .../v2/x/mongo/driver/operation/command.go | 237 ++ .../driver/operation/commit_transaction.go | 201 ++ .../v2/x/mongo/driver/operation/count.go | 327 +++ .../v2/x/mongo/driver/operation/create.go | 414 +++ .../mongo/driver/operation/create_indexes.go | 294 +++ .../driver/operation/create_search_indexes.go | 251 ++ .../v2/x/mongo/driver/operation/delete.go | 354 +++ .../v2/x/mongo/driver/operation/distinct.go | 340 +++ .../v2/x/mongo/driver/operation/doc.go | 14 + .../mongo/driver/operation/drop_collection.go | 236 ++ .../x/mongo/driver/operation/drop_database.go | 168 ++ .../x/mongo/driver/operation/drop_indexes.go | 265 ++ .../driver/operation/drop_search_index.go | 225 ++ .../x/mongo/driver/operation/end_sessions.go | 174 ++ .../v2/x/mongo/driver/operation/errors.go | 13 + .../v2/x/mongo/driver/operation/find.go | 592 +++++ .../mongo/driver/operation/find_and_modify.go | 493 ++++ .../v2/x/mongo/driver/operation/hello.go | 718 ++++++ .../v2/x/mongo/driver/operation/insert.go | 335 +++ .../driver/operation/list_collections.go | 292 +++ .../mongo/driver/operation/list_databases.go | 341 +++ .../x/mongo/driver/operation/list_indexes.go | 251 ++ .../v2/x/mongo/driver/operation/update.go | 439 ++++ .../driver/operation/update_search_index.go | 238 ++ .../v2/x/mongo/driver/operation_exhaust.go | 38 + .../v2/x/mongo/driver/serverapioptions.go | 36 + .../x/mongo/driver/session/client_session.go | 533 ++++ .../x/mongo/driver/session/cluster_clock.go | 36 + .../v2/x/mongo/driver/session/doc.go | 14 + .../v2/x/mongo/driver/session/options.go | 55 + .../x/mongo/driver/session/server_session.go | 74 + .../v2/x/mongo/driver/session/session_pool.go | 192 ++ .../v2/x/mongo/driver/topology/DESIGN.md | 45 + .../v2/x/mongo/driver/topology/connection.go | 865 +++++++ .../driver/topology/connection_legacy.go | 7 + .../driver/topology/connection_options.go | 190 ++ .../mongo/driver/topology/context_listener.go | 91 + .../v2/x/mongo/driver/topology/diff.go | 73 + .../v2/x/mongo/driver/topology/errors.go | 137 + .../v2/x/mongo/driver/topology/fsm.go | 495 ++++ .../v2/x/mongo/driver/topology/pool.go | 1553 +++++++++++ .../topology/pool_generation_counter.go | 148 ++ .../v2/x/mongo/driver/topology/rtt_monitor.go | 298 +++ .../v2/x/mongo/driver/topology/server.go | 1244 +++++++++ .../x/mongo/driver/topology/server_options.go | 240 ++ .../v2/x/mongo/driver/topology/stats.go | 33 + .../topology/tls_connection_source_1_16.go | 58 + .../topology/tls_connection_source_1_17.go | 47 + .../v2/x/mongo/driver/topology/topology.go | 1153 +++++++++ .../mongo/driver/topology/topology_options.go | 455 ++++ .../x/mongo/driver/wiremessage/wiremessage.go | 608 +++++ vendor/modules.txt | 50 + 286 files changed, 70698 insertions(+) create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/LICENSE create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/array_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/bsoncodec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/buffered_byte_src.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/byte_slice_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/codec_cache.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/cond_addr_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/copier.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/decimal.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/decoder.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_decoders.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_encoders.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/empty_interface_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/encoder.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_parser.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_reader.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_tables.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_wrappers.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_writer.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/json_scanner.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/map_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/marshal.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/mgoregistry.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/mode.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/objectid.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/pointer_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/primitive.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/primitive_codecs.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/raw.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/raw_array.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/raw_element.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/raw_value.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/reader.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/registry.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/slice_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/streaming_byte_src.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/string_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/struct_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/struct_tag_parser.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/time_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/types.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/uint_codec.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/unmarshal.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/value_reader.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/value_writer.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/vector.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/bson/writer.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/event/description.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/event/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/event/monitoring.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/aws/awserr/error.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/aws/awserr/types.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/chain_provider.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/credentials.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/header_rules.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/request.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/uri_path.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/v4.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/aws/types.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil/bsoncoreutil.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/bsonutil/bsonutil.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/codecutil/encoding.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/assume_role_provider.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ec2_provider.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ecs_provider.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/env_provider.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/imds_provider.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/static_provider.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/csfle/csfle.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/csot/csot.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/decimal128/decinal128.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/description.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/hello.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/operation.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/handshake/handshake.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/httputil/httputil.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/logger/component.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/logger/context.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/logger/io_sink.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/logger/level.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/logger/logger.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/mongoutil/mongoutil.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/optionsutil/options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/int64.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/ptr.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/rand/bits.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/rand/exp.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/rand/normal.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/rand/rand.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/rand/rng.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/randutil/randutil.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/serverselector/server_selector.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/internal/uuid/uuid.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/address/addr.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/background_context.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/batch_cursor.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/bulk_write.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/bulk_write_models.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/change_stream.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/change_stream_deployment.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/client.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/client_bulk_write.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/client_bulk_write_models.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/client_encryption.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/collection.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/crypt_retrievers.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/cursor.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/database.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_bucket.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_download_stream.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/gridfs_upload_stream.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/index_view.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/mongo.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/mongocryptd.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/aggregateoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/autoencryptionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/bulkwriteoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/changestreamoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientbulkwriteoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientencryptionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/clientoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/collectionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/countoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/createcollectionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/datakeyoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/dboptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/deleteoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/distinctoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/dropcollectionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/encryptoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/estimatedcountoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/findoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/gridfsoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/indexoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/insertoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/listcollectionsoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/listdatabasesoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/lister.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/loggeroptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/mongooptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/replaceoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/rewrapdatakeyoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/runcmdoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/searchindexoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/serverapioptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/sessionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/transactionoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/options/updateoptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/readconcern/readconcern.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/mode.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/readpref/readpref.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/results.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/search_index_view.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/session.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/single_result.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/mongo/writeconcern/writeconcern.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/tag/tag.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/version/version.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/array.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bson_arraybuilder.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bson_documentbuilder.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/bsoncore.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/document.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/element.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/iterator.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/tables.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/type.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore/value.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/auth.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/aws_conv.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/conversation.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/cred.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/awscreds.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/azurecreds.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/creds/gcpcreds.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/default.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi_not_enabled.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/gssapi_not_supported.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/gss.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/gss_wrapper.c create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/gss_wrapper.h create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/sspi.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.c create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.h create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongodbaws.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/oidc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/plain.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/sasl.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/scram.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/util.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/x509.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/batch_cursor.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/batches.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/compression.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/connstring/connstring.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/crypt.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/description/server.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/description/topology.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/dns/dns.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/driver.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/legacy.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet/connection.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/binary.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/errors_not_enabled.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_context.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/mongocrypt_context_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/options/mongocrypt_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/mongocrypt/state.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/cache.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/config.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/ocsp.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp/options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/abort_transaction.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/aggregate.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/command.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/commit_transaction.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/count.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create_indexes.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/create_search_indexes.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/delete.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/distinct.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_collection.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_database.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_indexes.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/drop_search_index.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/end_sessions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/find.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/find_and_modify.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/hello.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/insert.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_collections.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_databases.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/list_indexes.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/update.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation/update_search_index.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation_exhaust.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/serverapioptions.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/client_session.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/cluster_clock.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/doc.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/server_session.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/session/session_pool.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/DESIGN.md create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection_legacy.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/connection_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/context_listener.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/diff.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/errors.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/fsm.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/pool.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/pool_generation_counter.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/rtt_monitor.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/server.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/server_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/stats.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/tls_connection_source_1_16.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/tls_connection_source_1_17.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/topology.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology/topology_options.go create mode 100644 vendor/go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage/wiremessage.go diff --git a/go.mod b/go.mod index d4c4285c6..096158b83 100644 --- a/go.mod +++ b/go.mod @@ -35,6 +35,7 @@ require ( github.com/wealdtech/go-merkletree v1.0.0 github.com/xuri/excelize/v2 v2.10.0 go.mongodb.org/mongo-driver v1.17.4 + go.mongodb.org/mongo-driver/v2 v2.3.1 go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 go.opentelemetry.io/otel v1.38.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 diff --git a/go.sum b/go.sum index bdd7fa8f0..6a02fd38d 100644 --- a/go.sum +++ b/go.sum @@ -277,6 +277,8 @@ github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfS github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw= go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= +go.mongodb.org/mongo-driver/v2 v2.3.1 h1:WrCgSzO7dh1/FrePud9dK5fKNZOE97q5EQimGkos7Wo= +go.mongodb.org/mongo-driver/v2 v2.3.1/go.mod h1:jHeEDJHJq7tm6ZF45Issun9dbogjfnPySb1vXA7EeAI= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 h1:nXGeLvT1QtCAhkASkP/ksjkTKZALIaQBIW+JSIw1KIc= diff --git a/vendor/go.mongodb.org/mongo-driver/v2/LICENSE b/vendor/go.mongodb.org/mongo-driver/v2/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/array_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/array_codec.go new file mode 100644 index 000000000..4642fb6ea --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/array_codec.go @@ -0,0 +1,42 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "reflect" + + "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore" +) + +// arrayCodec is the Codec used for bsoncore.Array values. +type arrayCodec struct{} + +// EncodeValue is the ValueEncoder for bsoncore.Array values. +func (ac *arrayCodec) EncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tCoreArray { + return ValueEncoderError{Name: "CoreArrayEncodeValue", Types: []reflect.Type{tCoreArray}, Received: val} + } + + arr := val.Interface().(bsoncore.Array) + return copyArrayFromBytes(vw, arr) +} + +// DecodeValue is the ValueDecoder for bsoncore.Array values. +func (ac *arrayCodec) DecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tCoreArray { + return ValueDecoderError{Name: "CoreArrayDecodeValue", Types: []reflect.Type{tCoreArray}, Received: val} + } + + if val.IsNil() { + val.Set(reflect.MakeSlice(val.Type(), 0, 0)) + } + + val.SetLen(0) + arr, err := appendArrayBytes(val.Interface().(bsoncore.Array), vr) + val.Set(reflect.ValueOf(arr)) + return err +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/bsoncodec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/bsoncodec.go new file mode 100644 index 000000000..78b861a31 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/bsoncodec.go @@ -0,0 +1,203 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "fmt" + "reflect" + "strings" +) + +var ( + emptyValue = reflect.Value{} +) + +// ValueEncoderError is an error returned from a ValueEncoder when the provided value can't be +// encoded by the ValueEncoder. +type ValueEncoderError struct { + Name string + Types []reflect.Type + Kinds []reflect.Kind + Received reflect.Value +} + +func (vee ValueEncoderError) Error() string { + typeKinds := make([]string, 0, len(vee.Types)+len(vee.Kinds)) + for _, t := range vee.Types { + typeKinds = append(typeKinds, t.String()) + } + for _, k := range vee.Kinds { + if k == reflect.Map { + typeKinds = append(typeKinds, "map[string]*") + continue + } + typeKinds = append(typeKinds, k.String()) + } + received := vee.Received.Kind().String() + if vee.Received.IsValid() { + received = vee.Received.Type().String() + } + return fmt.Sprintf("%s can only encode valid %s, but got %s", vee.Name, strings.Join(typeKinds, ", "), received) +} + +// ValueDecoderError is an error returned from a ValueDecoder when the provided value can't be +// decoded by the ValueDecoder. +type ValueDecoderError struct { + Name string + Types []reflect.Type + Kinds []reflect.Kind + Received reflect.Value +} + +func (vde ValueDecoderError) Error() string { + typeKinds := make([]string, 0, len(vde.Types)+len(vde.Kinds)) + for _, t := range vde.Types { + typeKinds = append(typeKinds, t.String()) + } + for _, k := range vde.Kinds { + if k == reflect.Map { + typeKinds = append(typeKinds, "map[string]*") + continue + } + typeKinds = append(typeKinds, k.String()) + } + received := vde.Received.Kind().String() + if vde.Received.IsValid() { + received = vde.Received.Type().String() + } + if !vde.Received.CanSet() { + received = "unsettable " + received + } + return fmt.Sprintf("%s can only decode valid and settable %s, but got %s", vde.Name, strings.Join(typeKinds, ", "), received) +} + +// EncodeContext is the contextual information required for a Codec to encode a +// value. +type EncodeContext struct { + *Registry + + // minSize causes the Encoder to marshal Go integer values (int, int8, int16, int32, int64, + // uint, uint8, uint16, uint32, or uint64) as the minimum BSON int size (either 32 or 64 bits) + // that can represent the integer value. + minSize bool + + errorOnInlineDuplicates bool + stringifyMapKeysWithFmt bool + nilMapAsEmpty bool + nilSliceAsEmpty bool + nilByteSliceAsEmpty bool + omitZeroStruct bool + omitEmpty bool + useJSONStructTags bool +} + +// DecodeContext is the contextual information required for a Codec to decode a +// value. +type DecodeContext struct { + *Registry + + // truncate, if true, instructs decoders to to truncate the fractional part of BSON "double" + // values when attempting to unmarshal them into a Go integer (int, int8, int16, int32, int64, + // uint, uint8, uint16, uint32, or uint64) struct field. The truncation logic does not apply to + // BSON "decimal128" values. + truncate bool + + // defaultDocumentType specifies the Go type to decode top-level and nested BSON documents into. In particular, the + // usage for this field is restricted to data typed as "any" or "map[string]any". If DocumentType is + // set to a type that a BSON document cannot be unmarshaled into (e.g. "string"), unmarshalling will result in an + // error. + defaultDocumentType reflect.Type + + binaryAsSlice bool + + // a false value results in a decoding error. + objectIDAsHexString bool + + useJSONStructTags bool + useLocalTimeZone bool + zeroMaps bool + zeroStructs bool +} + +// ValueEncoder is the interface implemented by types that can encode a provided Go type to BSON. +// The value to encode is provided as a reflect.Value and a bson.ValueWriter is used within the +// EncodeValue method to actually create the BSON representation. For convenience, ValueEncoderFunc +// is provided to allow use of a function with the correct signature as a ValueEncoder. An +// EncodeContext instance is provided to allow implementations to lookup further ValueEncoders and +// to provide configuration information. +type ValueEncoder interface { + EncodeValue(EncodeContext, ValueWriter, reflect.Value) error +} + +// ValueEncoderFunc is an adapter function that allows a function with the correct signature to be +// used as a ValueEncoder. +type ValueEncoderFunc func(EncodeContext, ValueWriter, reflect.Value) error + +// EncodeValue implements the ValueEncoder interface. +func (fn ValueEncoderFunc) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error { + return fn(ec, vw, val) +} + +// ValueDecoder is the interface implemented by types that can decode BSON to a provided Go type. +// Implementations should ensure that the value they receive is settable. Similar to ValueEncoderFunc, +// ValueDecoderFunc is provided to allow the use of a function with the correct signature as a +// ValueDecoder. A DecodeContext instance is provided and serves similar functionality to the +// EncodeContext. +type ValueDecoder interface { + DecodeValue(DecodeContext, ValueReader, reflect.Value) error +} + +// ValueDecoderFunc is an adapter function that allows a function with the correct signature to be +// used as a ValueDecoder. +type ValueDecoderFunc func(DecodeContext, ValueReader, reflect.Value) error + +// DecodeValue implements the ValueDecoder interface. +func (fn ValueDecoderFunc) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + return fn(dc, vr, val) +} + +// typeDecoder is the interface implemented by types that can handle the decoding of a value given its type. +type typeDecoder interface { + decodeType(DecodeContext, ValueReader, reflect.Type) (reflect.Value, error) +} + +// typeDecoderFunc is an adapter function that allows a function with the correct signature to be used as a typeDecoder. +type typeDecoderFunc func(DecodeContext, ValueReader, reflect.Type) (reflect.Value, error) + +func (fn typeDecoderFunc) decodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + return fn(dc, vr, t) +} + +// decodeAdapter allows two functions with the correct signatures to be used as both a ValueDecoder and typeDecoder. +type decodeAdapter struct { + ValueDecoderFunc + typeDecoderFunc +} + +var _ ValueDecoder = decodeAdapter{} +var _ typeDecoder = decodeAdapter{} + +func decodeTypeOrValueWithInfo(vd ValueDecoder, dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if td, _ := vd.(typeDecoder); td != nil { + val, err := td.decodeType(dc, vr, t) + if err == nil && val.Type() != t { + // This conversion step is necessary for slices and maps. If a user declares variables like: + // + // type myBool bool + // var m map[string]myBool + // + // and tries to decode BSON bytes into the map, the decoding will fail if this conversion is not present + // because we'll try to assign a value of type bool to one of type myBool. + val = val.Convert(t) + } + return val, err + } + + val := reflect.New(t).Elem() + err := vd.DecodeValue(dc, vr, val) + return val, err +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/buffered_byte_src.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/buffered_byte_src.go new file mode 100644 index 000000000..eb19e3cb3 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/buffered_byte_src.go @@ -0,0 +1,128 @@ +// Copyright (C) MongoDB, Inc. 2025-present. +// +// 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 + +package bson + +import ( + "bytes" + "io" +) + +// bufferedByteSrc implements the low-level byteSrc interface by reading +// directly from an in-memory byte slice. It provides efficient, zero-copy +// access for parsing BSON when the entire document is buffered in memory. +type bufferedByteSrc struct { + buf []byte // entire BSON document + offset int64 // Current read index into buf +} + +var _ byteSrc = (*bufferedByteSrc)(nil) + +// Read reads up to len(p) bytes from the in-memory buffer, advancing the offset +// by the number of bytes read. +func (b *bufferedByteSrc) readExact(p []byte) (int, error) { + if b.offset >= int64(len(b.buf)) { + return 0, io.EOF + } + n := copy(p, b.buf[b.offset:]) + b.offset += int64(n) + return n, nil +} + +// ReadByte returns the single byte at buf[offset] and advances offset by 1. +func (b *bufferedByteSrc) ReadByte() (byte, error) { + if b.offset >= int64(len(b.buf)) { + return 0, io.EOF + } + b.offset++ + return b.buf[b.offset-1], nil +} + +// peek returns buf[offset:offset+n] without advancing offset. +func (b *bufferedByteSrc) peek(n int) ([]byte, error) { + // Ensure we don't read past the end of the buffer. + if int64(n)+b.offset > int64(len(b.buf)) { + return b.buf[b.offset:], io.EOF + } + + // Return the next n bytes without advancing the offset + return b.buf[b.offset : b.offset+int64(n)], nil +} + +// discard advances offset by n bytes, returning the number of bytes discarded. +func (b *bufferedByteSrc) discard(n int) (int, error) { + // Ensure we don't read past the end of the buffer. + if int64(n)+b.offset > int64(len(b.buf)) { + // If we have exceeded the buffer length, discard only up to the end. + left := len(b.buf) - int(b.offset) + b.offset = int64(len(b.buf)) + + return left, io.EOF + } + + // Advance the read position + b.offset += int64(n) + return n, nil +} + +// readSlice scans buf[offset:] for the first occurrence of delim, returns +// buf[offset:idx+1], and advances offset past it; errors if delim not found. +func (b *bufferedByteSrc) readSlice(delim byte) ([]byte, error) { + // Ensure we don't read past the end of the buffer. + if b.offset >= int64(len(b.buf)) { + return nil, io.EOF + } + + // Look for the delimiter in the remaining bytes + rem := b.buf[b.offset:] + idx := bytes.IndexByte(rem, delim) + if idx < 0 { + return nil, io.EOF + } + + // Build the result slice up through the delimiter. + result := rem[:idx+1] + + // Advance the offset past the delimiter. + b.offset += int64(idx + 1) + + return result, nil +} + +// pos returns the current read position in the buffer. +func (b *bufferedByteSrc) pos() int64 { + return b.offset +} + +// regexLength will return the total byte length of a BSON regex value. +func (b *bufferedByteSrc) regexLength() (int32, error) { + rem := b.buf[b.offset:] + + // Find end of the first C-string (pattern). + i := bytes.IndexByte(rem, 0x00) + if i < 0 { + return 0, io.EOF + } + + // Find end of second C-string (options). + j := bytes.IndexByte(rem[i+1:], 0x00) + if j < 0 { + return 0, io.EOF + } + + // Total length = first C-string length (pattern) + second C-string length + // (options) + 2 null terminators + return int32(i + j + 2), nil +} + +func (*bufferedByteSrc) streamable() bool { + return false +} + +func (b *bufferedByteSrc) reset() { + b.buf = nil + b.offset = 0 +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/byte_slice_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/byte_slice_codec.go new file mode 100644 index 000000000..bd44cf9a8 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/byte_slice_codec.go @@ -0,0 +1,97 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "fmt" + "reflect" +) + +// byteSliceCodec is the Codec used for []byte values. +type byteSliceCodec struct { + // encodeNilAsEmpty causes EncodeValue to marshal nil Go byte slices as empty BSON binary values + // instead of BSON null. + encodeNilAsEmpty bool +} + +// Assert that byteSliceCodec satisfies the typeDecoder interface, which allows it to be +// used by collection type decoders (e.g. map, slice, etc) to set individual values in a +// collection. +var _ typeDecoder = &byteSliceCodec{} + +// EncodeValue is the ValueEncoder for []byte. +func (bsc *byteSliceCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tByteSlice { + return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val} + } + if val.IsNil() && !bsc.encodeNilAsEmpty && !ec.nilByteSliceAsEmpty { + return vw.WriteNull() + } + return vw.WriteBinary(val.Interface().([]byte)) +} + +func (bsc *byteSliceCodec) decodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tByteSlice { + return emptyValue, ValueDecoderError{ + Name: "ByteSliceDecodeValue", + Types: []reflect.Type{tByteSlice}, + Received: reflect.Zero(t), + } + } + + var data []byte + var err error + switch vrType := vr.Type(); vrType { + case TypeString: + str, err := vr.ReadString() + if err != nil { + return emptyValue, err + } + data = []byte(str) + case TypeSymbol: + sym, err := vr.ReadSymbol() + if err != nil { + return emptyValue, err + } + data = []byte(sym) + case TypeBinary: + var subtype byte + data, subtype, err = vr.ReadBinary() + if err != nil { + return emptyValue, err + } + if subtype != TypeBinaryGeneric && subtype != TypeBinaryBinaryOld { + return emptyValue, decodeBinaryError{subtype: subtype, typeName: "[]byte"} + } + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a []byte", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(data), nil +} + +// DecodeValue is the ValueDecoder for []byte. +func (bsc *byteSliceCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tByteSlice { + return ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: val} + } + + elem, err := bsc.decodeType(dc, vr, tByteSlice) + if err != nil { + return err + } + + val.Set(elem) + return nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/codec_cache.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/codec_cache.go new file mode 100644 index 000000000..de97441e1 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/codec_cache.go @@ -0,0 +1,166 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "reflect" + "sync" + "sync/atomic" +) + +// Runtime check that the kind encoder and decoder caches can store any valid +// reflect.Kind constant. +func init() { + if s := reflect.Kind(len(kindEncoderCache{}.entries)).String(); s != "kind27" { + panic("The capacity of kindEncoderCache is too small.\n" + + "This is due to a new type being added to reflect.Kind.") + } +} + +// statically assert array size +var _ = (kindEncoderCache{}).entries[reflect.UnsafePointer] +var _ = (kindDecoderCache{}).entries[reflect.UnsafePointer] + +type typeEncoderCache struct { + cache sync.Map // map[reflect.Type]ValueEncoder +} + +func (c *typeEncoderCache) Store(rt reflect.Type, enc ValueEncoder) { + c.cache.Store(rt, enc) +} + +func (c *typeEncoderCache) Load(rt reflect.Type) (ValueEncoder, bool) { + if v, _ := c.cache.Load(rt); v != nil { + return v.(ValueEncoder), true + } + return nil, false +} + +func (c *typeEncoderCache) LoadOrStore(rt reflect.Type, enc ValueEncoder) ValueEncoder { + if v, loaded := c.cache.LoadOrStore(rt, enc); loaded { + enc = v.(ValueEncoder) + } + return enc +} + +func (c *typeEncoderCache) Clone() *typeEncoderCache { + cc := new(typeEncoderCache) + c.cache.Range(func(k, v any) bool { + if k != nil && v != nil { + cc.cache.Store(k, v) + } + return true + }) + return cc +} + +type typeDecoderCache struct { + cache sync.Map // map[reflect.Type]ValueDecoder +} + +func (c *typeDecoderCache) Store(rt reflect.Type, dec ValueDecoder) { + c.cache.Store(rt, dec) +} + +func (c *typeDecoderCache) Load(rt reflect.Type) (ValueDecoder, bool) { + if v, _ := c.cache.Load(rt); v != nil { + return v.(ValueDecoder), true + } + return nil, false +} + +func (c *typeDecoderCache) LoadOrStore(rt reflect.Type, dec ValueDecoder) ValueDecoder { + if v, loaded := c.cache.LoadOrStore(rt, dec); loaded { + dec = v.(ValueDecoder) + } + return dec +} + +func (c *typeDecoderCache) Clone() *typeDecoderCache { + cc := new(typeDecoderCache) + c.cache.Range(func(k, v any) bool { + if k != nil && v != nil { + cc.cache.Store(k, v) + } + return true + }) + return cc +} + +// atomic.Value requires that all calls to Store() have the same concrete type +// so we wrap the ValueEncoder with a kindEncoderCacheEntry to ensure the type +// is always the same (since different concrete types may implement the +// ValueEncoder interface). +type kindEncoderCacheEntry struct { + enc ValueEncoder +} + +type kindEncoderCache struct { + entries [reflect.UnsafePointer + 1]atomic.Value // *kindEncoderCacheEntry +} + +func (c *kindEncoderCache) Store(rt reflect.Kind, enc ValueEncoder) { + if enc != nil && rt < reflect.Kind(len(c.entries)) { + c.entries[rt].Store(&kindEncoderCacheEntry{enc: enc}) + } +} + +func (c *kindEncoderCache) Load(rt reflect.Kind) (ValueEncoder, bool) { + if rt < reflect.Kind(len(c.entries)) { + if ent, ok := c.entries[rt].Load().(*kindEncoderCacheEntry); ok { + return ent.enc, ent.enc != nil + } + } + return nil, false +} + +func (c *kindEncoderCache) Clone() *kindEncoderCache { + cc := new(kindEncoderCache) + for i, v := range c.entries { + if val := v.Load(); val != nil { + cc.entries[i].Store(val) + } + } + return cc +} + +// atomic.Value requires that all calls to Store() have the same concrete type +// so we wrap the ValueDecoder with a kindDecoderCacheEntry to ensure the type +// is always the same (since different concrete types may implement the +// ValueDecoder interface). +type kindDecoderCacheEntry struct { + dec ValueDecoder +} + +type kindDecoderCache struct { + entries [reflect.UnsafePointer + 1]atomic.Value // *kindDecoderCacheEntry +} + +func (c *kindDecoderCache) Store(rt reflect.Kind, dec ValueDecoder) { + if rt < reflect.Kind(len(c.entries)) { + c.entries[rt].Store(&kindDecoderCacheEntry{dec: dec}) + } +} + +func (c *kindDecoderCache) Load(rt reflect.Kind) (ValueDecoder, bool) { + if rt < reflect.Kind(len(c.entries)) { + if ent, ok := c.entries[rt].Load().(*kindDecoderCacheEntry); ok { + return ent.dec, ent.dec != nil + } + } + return nil, false +} + +func (c *kindDecoderCache) Clone() *kindDecoderCache { + cc := new(kindDecoderCache) + for i, v := range c.entries { + if val := v.Load(); val != nil { + cc.entries[i].Store(val) + } + } + return cc +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/cond_addr_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/cond_addr_codec.go new file mode 100644 index 000000000..fed4d1f8d --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/cond_addr_codec.go @@ -0,0 +1,61 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "reflect" +) + +// condAddrEncoder is the encoder used when a pointer to the encoding value has an encoder. +type condAddrEncoder struct { + canAddrEnc ValueEncoder + elseEnc ValueEncoder +} + +var _ ValueEncoder = &condAddrEncoder{} + +// newCondAddrEncoder returns an condAddrEncoder. +func newCondAddrEncoder(canAddrEnc, elseEnc ValueEncoder) *condAddrEncoder { + encoder := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc} + return &encoder +} + +// EncodeValue is the ValueEncoderFunc for a value that may be addressable. +func (cae *condAddrEncoder) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error { + if val.CanAddr() { + return cae.canAddrEnc.EncodeValue(ec, vw, val) + } + if cae.elseEnc != nil { + return cae.elseEnc.EncodeValue(ec, vw, val) + } + return errNoEncoder{Type: val.Type()} +} + +// condAddrDecoder is the decoder used when a pointer to the value has a decoder. +type condAddrDecoder struct { + canAddrDec ValueDecoder + elseDec ValueDecoder +} + +var _ ValueDecoder = &condAddrDecoder{} + +// newCondAddrDecoder returns an CondAddrDecoder. +func newCondAddrDecoder(canAddrDec, elseDec ValueDecoder) *condAddrDecoder { + decoder := condAddrDecoder{canAddrDec: canAddrDec, elseDec: elseDec} + return &decoder +} + +// DecodeValue is the ValueDecoderFunc for a value that may be addressable. +func (cad *condAddrDecoder) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if val.CanAddr() { + return cad.canAddrDec.DecodeValue(dc, vr, val) + } + if cad.elseDec != nil { + return cad.elseDec.DecodeValue(dc, vr, val) + } + return errNoDecoder{Type: val.Type()} +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/copier.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/copier.go new file mode 100644 index 000000000..c9a37c756 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/copier.go @@ -0,0 +1,433 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "errors" + "fmt" + "io" + + "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore" +) + +// copyDocument handles copying one document from the src to the dst. +func copyDocument(dst ValueWriter, src ValueReader) error { + dr, err := src.ReadDocument() + if err != nil { + return err + } + + dw, err := dst.WriteDocument() + if err != nil { + return err + } + + return copyDocumentCore(dw, dr) +} + +// copyArrayFromBytes copies the values from a BSON array represented as a +// []byte to a ValueWriter. +func copyArrayFromBytes(dst ValueWriter, src []byte) error { + aw, err := dst.WriteArray() + if err != nil { + return err + } + + err = copyBytesToArrayWriter(aw, src) + if err != nil { + return err + } + + return aw.WriteArrayEnd() +} + +// copyDocumentFromBytes copies the values from a BSON document represented as a +// []byte to a ValueWriter. +func copyDocumentFromBytes(dst ValueWriter, src []byte) error { + dw, err := dst.WriteDocument() + if err != nil { + return err + } + + err = copyBytesToDocumentWriter(dw, src) + if err != nil { + return err + } + + return dw.WriteDocumentEnd() +} + +type writeElementFn func(key string) (ValueWriter, error) + +// copyBytesToArrayWriter copies the values from a BSON Array represented as a []byte to an +// ArrayWriter. +func copyBytesToArrayWriter(dst ArrayWriter, src []byte) error { + wef := func(_ string) (ValueWriter, error) { + return dst.WriteArrayElement() + } + + return copyBytesToValueWriter(src, wef) +} + +// copyBytesToDocumentWriter copies the values from a BSON document represented as a []byte to a +// DocumentWriter. +func copyBytesToDocumentWriter(dst DocumentWriter, src []byte) error { + wef := func(key string) (ValueWriter, error) { + return dst.WriteDocumentElement(key) + } + + return copyBytesToValueWriter(src, wef) +} + +func copyBytesToValueWriter(src []byte, wef writeElementFn) error { + // TODO(skriptble): Create errors types here. Anything that is a tag should be a property. + length, rem, ok := bsoncore.ReadLength(src) + if !ok { + return fmt.Errorf("couldn't read length from src, not enough bytes. length=%d", len(src)) + } + if len(src) < int(length) { + return fmt.Errorf("length read exceeds number of bytes available. length=%d bytes=%d", len(src), length) + } + rem = rem[:length-4] + + var t bsoncore.Type + var key string + var val bsoncore.Value + for { + t, rem, ok = bsoncore.ReadType(rem) + if !ok { + return io.EOF + } + if t == bsoncore.Type(0) { + if len(rem) != 0 { + return fmt.Errorf("document end byte found before end of document. remaining bytes=%v", rem) + } + break + } + + key, rem, ok = bsoncore.ReadKey(rem) + if !ok { + return fmt.Errorf("invalid key found. remaining bytes=%v", rem) + } + + // write as either array element or document element using writeElementFn + vw, err := wef(key) + if err != nil { + return err + } + + val, rem, ok = bsoncore.ReadValue(rem, t) + if !ok { + return fmt.Errorf("not enough bytes available to read type. bytes=%d type=%s", len(rem), t) + } + err = copyValueFromBytes(vw, Type(t), val.Data) + if err != nil { + return err + } + } + return nil +} + +// copyDocumentToBytes copies an entire document from the ValueReader and +// returns it as bytes. +func copyDocumentToBytes(src ValueReader) ([]byte, error) { + return appendDocumentBytes(nil, src) +} + +// appendDocumentBytes functions the same as CopyDocumentToBytes, but will +// append the result to dst. +func appendDocumentBytes(dst []byte, src ValueReader) ([]byte, error) { + if br, ok := src.(bytesReader); ok { + _, dst, err := br.readValueBytes(dst) + return dst, err + } + + vw := vwPool.Get().(*valueWriter) + defer putValueWriter(vw) + + vw.reset(dst) + + err := copyDocument(vw, src) + dst = vw.buf + return dst, err +} + +// appendArrayBytes copies an array from the ValueReader to dst. +func appendArrayBytes(dst []byte, src ValueReader) ([]byte, error) { + if br, ok := src.(bytesReader); ok { + _, dst, err := br.readValueBytes(dst) + return dst, err + } + + vw := vwPool.Get().(*valueWriter) + defer putValueWriter(vw) + + vw.reset(dst) + + err := copyArray(vw, src) + dst = vw.buf + return dst, err +} + +// copyValueFromBytes will write the value represtend by t and src to dst. +func copyValueFromBytes(dst ValueWriter, t Type, src []byte) error { + if wvb, ok := dst.(bytesWriter); ok { + return wvb.writeValueBytes(t, src) + } + + vr := newBufferedDocumentReader(src) + vr.advanceFrame() + + vr.stack[vr.frame].mode = mElement + vr.stack[vr.frame].vType = t + + return copyValue(dst, vr) +} + +// copyValueToBytes copies a value from src and returns it as a Type and a +// []byte. +func copyValueToBytes(src ValueReader) (Type, []byte, error) { + if br, ok := src.(bytesReader); ok { + return br.readValueBytes(nil) + } + + vw := vwPool.Get().(*valueWriter) + defer putValueWriter(vw) + + vw.reset(nil) + vw.push(mElement) + + err := copyValue(vw, src) + if err != nil { + return 0, nil, err + } + + return Type(vw.buf[0]), vw.buf[2:], nil +} + +// copyValue will copy a single value from src to dst. +func copyValue(dst ValueWriter, src ValueReader) error { + var err error + switch src.Type() { + case TypeDouble: + var f64 float64 + f64, err = src.ReadDouble() + if err != nil { + break + } + err = dst.WriteDouble(f64) + case TypeString: + var str string + str, err = src.ReadString() + if err != nil { + return err + } + err = dst.WriteString(str) + case TypeEmbeddedDocument: + err = copyDocument(dst, src) + case TypeArray: + err = copyArray(dst, src) + case TypeBinary: + var data []byte + var subtype byte + data, subtype, err = src.ReadBinary() + if err != nil { + break + } + err = dst.WriteBinaryWithSubtype(data, subtype) + case TypeUndefined: + err = src.ReadUndefined() + if err != nil { + break + } + err = dst.WriteUndefined() + case TypeObjectID: + var oid ObjectID + oid, err = src.ReadObjectID() + if err != nil { + break + } + err = dst.WriteObjectID(oid) + case TypeBoolean: + var b bool + b, err = src.ReadBoolean() + if err != nil { + break + } + err = dst.WriteBoolean(b) + case TypeDateTime: + var dt int64 + dt, err = src.ReadDateTime() + if err != nil { + break + } + err = dst.WriteDateTime(dt) + case TypeNull: + err = src.ReadNull() + if err != nil { + break + } + err = dst.WriteNull() + case TypeRegex: + var pattern, options string + pattern, options, err = src.ReadRegex() + if err != nil { + break + } + err = dst.WriteRegex(pattern, options) + case TypeDBPointer: + var ns string + var pointer ObjectID + ns, pointer, err = src.ReadDBPointer() + if err != nil { + break + } + err = dst.WriteDBPointer(ns, pointer) + case TypeJavaScript: + var js string + js, err = src.ReadJavascript() + if err != nil { + break + } + err = dst.WriteJavascript(js) + case TypeSymbol: + var symbol string + symbol, err = src.ReadSymbol() + if err != nil { + break + } + err = dst.WriteSymbol(symbol) + case TypeCodeWithScope: + var code string + var srcScope DocumentReader + code, srcScope, err = src.ReadCodeWithScope() + if err != nil { + break + } + + var dstScope DocumentWriter + dstScope, err = dst.WriteCodeWithScope(code) + if err != nil { + break + } + err = copyDocumentCore(dstScope, srcScope) + case TypeInt32: + var i32 int32 + i32, err = src.ReadInt32() + if err != nil { + break + } + err = dst.WriteInt32(i32) + case TypeTimestamp: + var t, i uint32 + t, i, err = src.ReadTimestamp() + if err != nil { + break + } + err = dst.WriteTimestamp(t, i) + case TypeInt64: + var i64 int64 + i64, err = src.ReadInt64() + if err != nil { + break + } + err = dst.WriteInt64(i64) + case TypeDecimal128: + var d128 Decimal128 + d128, err = src.ReadDecimal128() + if err != nil { + break + } + err = dst.WriteDecimal128(d128) + case TypeMinKey: + err = src.ReadMinKey() + if err != nil { + break + } + err = dst.WriteMinKey() + case TypeMaxKey: + err = src.ReadMaxKey() + if err != nil { + break + } + err = dst.WriteMaxKey() + default: + err = fmt.Errorf("cannot copy unknown BSON type %s", src.Type()) + } + + return err +} + +func copyArray(dst ValueWriter, src ValueReader) error { + ar, err := src.ReadArray() + if err != nil { + return err + } + + aw, err := dst.WriteArray() + if err != nil { + return err + } + + for { + vr, err := ar.ReadValue() + if errors.Is(err, ErrEOA) { + break + } + if err != nil { + return err + } + + vw, err := aw.WriteArrayElement() + if err != nil { + return err + } + + err = copyValue(vw, vr) + if err != nil { + return err + } + } + + return aw.WriteArrayEnd() +} + +func copyDocumentCore(dw DocumentWriter, dr DocumentReader) error { + for { + key, vr, err := dr.ReadElement() + if errors.Is(err, ErrEOD) { + break + } + if err != nil { + return err + } + + vw, err := dw.WriteDocumentElement(key) + if err != nil { + return err + } + + err = copyValue(vw, vr) + if err != nil { + return err + } + } + + return dw.WriteDocumentEnd() +} + +// bytesReader is the interface used to read BSON bytes from a valueReader. +// +// The bytes of the value will be appended to dst. +type bytesReader interface { + readValueBytes(dst []byte) (Type, []byte, error) +} + +// bytesWriter is the interface used to write BSON bytes to a valueWriter. +type bytesWriter interface { + writeValueBytes(t Type, b []byte) error +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/decimal.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/decimal.go new file mode 100644 index 000000000..6241733a1 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/decimal.go @@ -0,0 +1,339 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 +// +// Based on gopkg.in/mgo.v2/bson by Gustavo Niemeyer +// See THIRD-PARTY-NOTICES for original license terms. + +package bson + +import ( + "encoding/json" + "errors" + "fmt" + "math/big" + "regexp" + "strconv" + "strings" + + "go.mongodb.org/mongo-driver/v2/internal/decimal128" +) + +// These constants are the maximum and minimum values for the exponent field in a decimal128 value. +const ( + MaxDecimal128Exp = 6111 + MinDecimal128Exp = -6176 +) + +// These errors are returned when an invalid value is parsed as a big.Int. +var ( + ErrParseNaN = errors.New("cannot parse NaN as a *big.Int") + ErrParseInf = errors.New("cannot parse Infinity as a *big.Int") + ErrParseNegInf = errors.New("cannot parse -Infinity as a *big.Int") +) + +// Decimal128 holds decimal128 BSON values. +type Decimal128 struct { + h, l uint64 +} + +// NewDecimal128 creates a Decimal128 using the provide high and low uint64s. +func NewDecimal128(h, l uint64) Decimal128 { + return Decimal128{h: h, l: l} +} + +// GetBytes returns the underlying bytes of the BSON decimal value as two uint64 values. The first +// contains the most first 8 bytes of the value and the second contains the latter. +func (d Decimal128) GetBytes() (uint64, uint64) { + return d.h, d.l +} + +// String returns a string representation of the decimal value. +func (d Decimal128) String() string { + return decimal128.String(d.h, d.l) +} + +// BigInt returns significand as big.Int and exponent, bi * 10 ^ exp. +func (d Decimal128) BigInt() (*big.Int, int, error) { + high, low := d.GetBytes() + posSign := high>>63&1 == 0 // positive sign + + switch high >> 58 & (1<<5 - 1) { + case 0x1F: + return nil, 0, ErrParseNaN + case 0x1E: + if posSign { + return nil, 0, ErrParseInf + } + return nil, 0, ErrParseNegInf + } + + var exp int + if high>>61&3 == 3 { + // Bits: 1*sign 2*ignored 14*exponent 111*significand. + // Implicit 0b100 prefix in significand. + exp = int(high >> 47 & (1<<14 - 1)) + // Spec says all of these values are out of range. + high, low = 0, 0 + } else { + // Bits: 1*sign 14*exponent 113*significand + exp = int(high >> 49 & (1<<14 - 1)) + high &= (1<<49 - 1) + } + exp += MinDecimal128Exp + + // Would be handled by the logic below, but that's trivial and common. + if high == 0 && low == 0 && exp == 0 { + return new(big.Int), 0, nil + } + + bi := big.NewInt(0) + const host32bit = ^uint(0)>>32 == 0 + if host32bit { + bi.SetBits([]big.Word{big.Word(low), big.Word(low >> 32), big.Word(high), big.Word(high >> 32)}) + } else { + bi.SetBits([]big.Word{big.Word(low), big.Word(high)}) + } + + if !posSign { + return bi.Neg(bi), exp, nil + } + return bi, exp, nil +} + +// IsNaN returns whether d is NaN. +func (d Decimal128) IsNaN() bool { + return d.h>>58&(1<<5-1) == 0x1F +} + +// IsInf returns: +// +// +1 d == Infinity +// 0 other case +// -1 d == -Infinity +func (d Decimal128) IsInf() int { + if d.h>>58&(1<<5-1) != 0x1E { + return 0 + } + + if d.h>>63&1 == 0 { + return 1 + } + return -1 +} + +// IsZero returns true if d is the empty Decimal128. +func (d Decimal128) IsZero() bool { + return d.h == 0 && d.l == 0 +} + +// MarshalJSON returns Decimal128 as a string. +func (d Decimal128) MarshalJSON() ([]byte, error) { + return json.Marshal(d.String()) +} + +// UnmarshalJSON creates a Decimal128 from a JSON string, an extended JSON $numberDecimal value, or the string +// "null". If b is a JSON string or extended JSON value, d will have the value of that string, and if b is "null", d will +// be unchanged. +func (d *Decimal128) UnmarshalJSON(b []byte) error { + // Ignore "null" to keep parity with the standard library. Decoding a JSON null into a non-pointer Decimal128 field + // will leave the field unchanged. For pointer values, encoding/json will set the pointer to nil and will not + // enter the UnmarshalJSON hook. + if string(b) == "null" { + return nil + } + + var res any + err := json.Unmarshal(b, &res) + if err != nil { + return err + } + str, ok := res.(string) + + // Extended JSON + if !ok { + m, ok := res.(map[string]any) + if !ok { + return errors.New("not an extended JSON Decimal128: expected document") + } + d128, ok := m["$numberDecimal"] + if !ok { + return errors.New("not an extended JSON Decimal128: expected key $numberDecimal") + } + str, ok = d128.(string) + if !ok { + return errors.New("not an extended JSON Decimal128: expected decimal to be string") + } + } + + *d, err = ParseDecimal128(str) + return err +} + +var dNaN = Decimal128{0x1F << 58, 0} +var dPosInf = Decimal128{0x1E << 58, 0} +var dNegInf = Decimal128{0x3E << 58, 0} + +func dErr(s string) (Decimal128, error) { + return dNaN, fmt.Errorf("cannot parse %q as a decimal128", s) +} + +// match scientific notation number, example -10.15e-18 +var normalNumber = regexp.MustCompile(`^(?P[-+]?\d*)?(?:\.(?P\d*))?(?:[Ee](?P[-+]?\d+))?$`) + +// ParseDecimal128 takes the given string and attempts to parse it into a valid +// Decimal128 value. +func ParseDecimal128(s string) (Decimal128, error) { + if s == "" { + return dErr(s) + } + + matches := normalNumber.FindStringSubmatch(s) + if len(matches) == 0 { + orig := s + neg := s[0] == '-' + if neg || s[0] == '+' { + s = s[1:] + } + + if s == "NaN" || s == "nan" || strings.EqualFold(s, "nan") { + return dNaN, nil + } + if s == "Inf" || s == "inf" || strings.EqualFold(s, "inf") || strings.EqualFold(s, "infinity") { + if neg { + return dNegInf, nil + } + return dPosInf, nil + } + return dErr(orig) + } + + intPart := matches[1] + decPart := matches[2] + expPart := matches[3] + + var err error + exp := 0 + if expPart != "" { + exp, err = strconv.Atoi(expPart) + if err != nil { + return dErr(s) + } + } + if decPart != "" { + exp -= len(decPart) + } + + if len(strings.Trim(intPart+decPart, "-0")) > 35 { + return dErr(s) + } + + // Parse the significand (i.e. the non-exponent part) as a big.Int. + bi, ok := new(big.Int).SetString(intPart+decPart, 10) + if !ok { + return dErr(s) + } + + d, ok := ParseDecimal128FromBigInt(bi, exp) + if !ok { + return dErr(s) + } + + if bi.Sign() == 0 && s[0] == '-' { + d.h |= 1 << 63 + } + + return d, nil +} + +var ( + ten = big.NewInt(10) + zero = new(big.Int) + + maxS, _ = new(big.Int).SetString("9999999999999999999999999999999999", 10) +) + +// ParseDecimal128FromBigInt attempts to parse the given significand and exponent into a valid Decimal128 value. +func ParseDecimal128FromBigInt(bi *big.Int, exp int) (Decimal128, bool) { + // copy + bi = new(big.Int).Set(bi) + + q := new(big.Int) + r := new(big.Int) + + // If the significand is zero, the logical value will always be zero, independent of the + // exponent. However, the loops for handling out-of-range exponent values below may be extremely + // slow for zero values because the significand never changes. Limit the exponent value to the + // supported range here to prevent entering the loops below. + if bi.Cmp(zero) == 0 { + if exp > MaxDecimal128Exp { + exp = MaxDecimal128Exp + } + if exp < MinDecimal128Exp { + exp = MinDecimal128Exp + } + } + + for bigIntCmpAbs(bi, maxS) == 1 { + bi, _ = q.QuoRem(bi, ten, r) + if r.Cmp(zero) != 0 { + return Decimal128{}, false + } + exp++ + if exp > MaxDecimal128Exp { + return Decimal128{}, false + } + } + + for exp < MinDecimal128Exp { + // Subnormal. + bi, _ = q.QuoRem(bi, ten, r) + if r.Cmp(zero) != 0 { + return Decimal128{}, false + } + exp++ + } + for exp > MaxDecimal128Exp { + // Clamped. + bi.Mul(bi, ten) + if bigIntCmpAbs(bi, maxS) == 1 { + return Decimal128{}, false + } + exp-- + } + + b := bi.Bytes() + var h, l uint64 + for i := 0; i < len(b); i++ { + if i < len(b)-8 { + h = h<<8 | uint64(b[i]) + continue + } + l = l<<8 | uint64(b[i]) + } + + h |= uint64(exp-MinDecimal128Exp) & uint64(1<<14-1) << 49 + if bi.Sign() == -1 { + h |= 1 << 63 + } + + return Decimal128{h: h, l: l}, true +} + +// bigIntCmpAbs computes big.Int.Cmp(absoluteValue(x), absoluteValue(y)). +func bigIntCmpAbs(x, y *big.Int) int { + xAbs := bigIntAbsValue(x) + yAbs := bigIntAbsValue(y) + return xAbs.Cmp(yAbs) +} + +// bigIntAbsValue returns a big.Int containing the absolute value of b. +// If b is already a non-negative number, it is returned without any changes or copies. +func bigIntAbsValue(b *big.Int) *big.Int { + if b.Sign() >= 0 { + return b // already positive + } + return new(big.Int).Abs(b) +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/decoder.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/decoder.go new file mode 100644 index 000000000..4c24dc661 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/decoder.go @@ -0,0 +1,136 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "errors" + "fmt" + "reflect" + "sync" +) + +// ErrDecodeToNil is the error returned when trying to decode to a nil value +var ErrDecodeToNil = errors.New("cannot Decode to nil value") + +// This pool is used to keep the allocations of Decoders down. This is only used for the Marshal* +// methods and is not consumable from outside of this package. The Decoders retrieved from this pool +// must have both Reset and SetRegistry called on them. +var decPool = sync.Pool{ + New: func() any { + return new(Decoder) + }, +} + +// A Decoder reads and decodes BSON documents from a stream. It reads from a ValueReader as +// the source of BSON data. +type Decoder struct { + dc DecodeContext + vr ValueReader +} + +// NewDecoder returns a new decoder that reads from vr. +func NewDecoder(vr ValueReader) *Decoder { + return &Decoder{ + dc: DecodeContext{Registry: defaultRegistry}, + vr: vr, + } +} + +// Decode reads the next BSON document from the stream and decodes it into the +// value pointed to by val. +// +// See [Unmarshal] for details about BSON unmarshaling behavior. +func (d *Decoder) Decode(val any) error { + if unmarshaler, ok := val.(Unmarshaler); ok { + // TODO(skriptble): Reuse a []byte here and use the AppendDocumentBytes method. + buf, err := copyDocumentToBytes(d.vr) + if err != nil { + return err + } + return unmarshaler.UnmarshalBSON(buf) + } + + rval := reflect.ValueOf(val) + switch rval.Kind() { + case reflect.Ptr: + if rval.IsNil() { + return ErrDecodeToNil + } + rval = rval.Elem() + case reflect.Map: + if rval.IsNil() { + return ErrDecodeToNil + } + default: + return fmt.Errorf("argument to Decode must be a pointer or a map, but got %v", rval) + } + decoder, err := d.dc.LookupDecoder(rval.Type()) + if err != nil { + return err + } + + return decoder.DecodeValue(d.dc, d.vr, rval) +} + +// Reset will reset the state of the decoder, using the same *DecodeContext used in +// the original construction but using vr for reading. +func (d *Decoder) Reset(vr ValueReader) { + d.vr = vr +} + +// SetRegistry replaces the current registry of the decoder with r. +func (d *Decoder) SetRegistry(r *Registry) { + d.dc.Registry = r +} + +// DefaultDocumentM causes the Decoder to always unmarshal documents into the bson.M type. This +// behavior is restricted to data typed as "any" or "map[string]any". +func (d *Decoder) DefaultDocumentM() { + d.dc.defaultDocumentType = reflect.TypeOf(M{}) +} + +// AllowTruncatingDoubles causes the Decoder to truncate the fractional part of BSON "double" values +// when attempting to unmarshal them into a Go integer (int, int8, int16, int32, or int64) struct +// field. The truncation logic does not apply to BSON "decimal128" values. +func (d *Decoder) AllowTruncatingDoubles() { + d.dc.truncate = true +} + +// BinaryAsSlice causes the Decoder to unmarshal BSON binary field values that are the "Generic" or +// "Old" BSON binary subtype as a Go byte slice instead of a bson.Binary. +func (d *Decoder) BinaryAsSlice() { + d.dc.binaryAsSlice = true +} + +// ObjectIDAsHexString causes the Decoder to decode object IDs to their hex representation. +func (d *Decoder) ObjectIDAsHexString() { + d.dc.objectIDAsHexString = true +} + +// UseJSONStructTags causes the Decoder to fall back to using the "json" struct tag if a "bson" +// struct tag is not specified. +func (d *Decoder) UseJSONStructTags() { + d.dc.useJSONStructTags = true +} + +// UseLocalTimeZone causes the Decoder to unmarshal time.Time values in the local timezone instead +// of the UTC timezone. +func (d *Decoder) UseLocalTimeZone() { + d.dc.useLocalTimeZone = true +} + +// ZeroMaps causes the Decoder to delete any existing values from Go maps in the destination value +// passed to Decode before unmarshaling BSON documents into them. +func (d *Decoder) ZeroMaps() { + d.dc.zeroMaps = true +} + +// ZeroStructs causes the Decoder to delete any existing values from Go structs in the destination +// value passed to Decode before unmarshaling BSON documents into them. +func (d *Decoder) ZeroStructs() { + d.dc.zeroStructs = true +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_decoders.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_decoders.go new file mode 100644 index 000000000..8ce5954de --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_decoders.go @@ -0,0 +1,1518 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "encoding/json" + "errors" + "fmt" + "math" + "net/url" + "reflect" + "strconv" + + "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore" +) + +var errCannotTruncate = errors.New("float64 can only be truncated to a lower precision type when truncation is enabled") + +type decodeBinaryError struct { + subtype byte + typeName string +} + +func (d decodeBinaryError) Error() string { + return fmt.Sprintf("only binary values with subtype 0x00 or 0x02 can be decoded into %s, but got subtype %v", d.typeName, d.subtype) +} + +// registerDefaultDecoders will register the decoder methods attached to DefaultValueDecoders with +// the provided RegistryBuilder. +// +// There is no support for decoding map[string]any because there is no decoder for +// any, so users must either register this decoder themselves or use the +// EmptyInterfaceDecoder available in the bson package. +func registerDefaultDecoders(reg *Registry) { + intDecoder := decodeAdapter{intDecodeValue, intDecodeType} + floatDecoder := decodeAdapter{floatDecodeValue, floatDecodeType} + uintCodec := &uintCodec{} + + reg.RegisterTypeDecoder(tD, ValueDecoderFunc(dDecodeValue)) + reg.RegisterTypeDecoder(tBinary, decodeAdapter{binaryDecodeValue, binaryDecodeType}) + reg.RegisterTypeDecoder(tVector, decodeAdapter{vectorDecodeValue, vectorDecodeType}) + reg.RegisterTypeDecoder(tUndefined, decodeAdapter{undefinedDecodeValue, undefinedDecodeType}) + reg.RegisterTypeDecoder(tDateTime, decodeAdapter{dateTimeDecodeValue, dateTimeDecodeType}) + reg.RegisterTypeDecoder(tNull, decodeAdapter{nullDecodeValue, nullDecodeType}) + reg.RegisterTypeDecoder(tRegex, decodeAdapter{regexDecodeValue, regexDecodeType}) + reg.RegisterTypeDecoder(tDBPointer, decodeAdapter{dbPointerDecodeValue, dbPointerDecodeType}) + reg.RegisterTypeDecoder(tTimestamp, decodeAdapter{timestampDecodeValue, timestampDecodeType}) + reg.RegisterTypeDecoder(tMinKey, decodeAdapter{minKeyDecodeValue, minKeyDecodeType}) + reg.RegisterTypeDecoder(tMaxKey, decodeAdapter{maxKeyDecodeValue, maxKeyDecodeType}) + reg.RegisterTypeDecoder(tJavaScript, decodeAdapter{javaScriptDecodeValue, javaScriptDecodeType}) + reg.RegisterTypeDecoder(tSymbol, decodeAdapter{symbolDecodeValue, symbolDecodeType}) + reg.RegisterTypeDecoder(tByteSlice, &byteSliceCodec{}) + reg.RegisterTypeDecoder(tTime, &timeCodec{}) + reg.RegisterTypeDecoder(tEmpty, &emptyInterfaceCodec{}) + reg.RegisterTypeDecoder(tCoreArray, &arrayCodec{}) + reg.RegisterTypeDecoder(tOID, decodeAdapter{objectIDDecodeValue, objectIDDecodeType}) + reg.RegisterTypeDecoder(tDecimal, decodeAdapter{decimal128DecodeValue, decimal128DecodeType}) + reg.RegisterTypeDecoder(tJSONNumber, decodeAdapter{jsonNumberDecodeValue, jsonNumberDecodeType}) + reg.RegisterTypeDecoder(tURL, decodeAdapter{urlDecodeValue, urlDecodeType}) + reg.RegisterTypeDecoder(tCoreDocument, ValueDecoderFunc(coreDocumentDecodeValue)) + reg.RegisterTypeDecoder(tCodeWithScope, decodeAdapter{codeWithScopeDecodeValue, codeWithScopeDecodeType}) + reg.RegisterKindDecoder(reflect.Bool, decodeAdapter{booleanDecodeValue, booleanDecodeType}) + reg.RegisterKindDecoder(reflect.Int, intDecoder) + reg.RegisterKindDecoder(reflect.Int8, intDecoder) + reg.RegisterKindDecoder(reflect.Int16, intDecoder) + reg.RegisterKindDecoder(reflect.Int32, intDecoder) + reg.RegisterKindDecoder(reflect.Int64, intDecoder) + reg.RegisterKindDecoder(reflect.Uint, uintCodec) + reg.RegisterKindDecoder(reflect.Uint8, uintCodec) + reg.RegisterKindDecoder(reflect.Uint16, uintCodec) + reg.RegisterKindDecoder(reflect.Uint32, uintCodec) + reg.RegisterKindDecoder(reflect.Uint64, uintCodec) + reg.RegisterKindDecoder(reflect.Float32, floatDecoder) + reg.RegisterKindDecoder(reflect.Float64, floatDecoder) + reg.RegisterKindDecoder(reflect.Array, ValueDecoderFunc(arrayDecodeValue)) + reg.RegisterKindDecoder(reflect.Map, &mapCodec{}) + reg.RegisterKindDecoder(reflect.Slice, &sliceCodec{}) + reg.RegisterKindDecoder(reflect.String, &stringCodec{}) + reg.RegisterKindDecoder(reflect.Struct, newStructCodec(nil)) + reg.RegisterKindDecoder(reflect.Ptr, &pointerCodec{}) + reg.RegisterTypeMapEntry(TypeDouble, tFloat64) + reg.RegisterTypeMapEntry(TypeString, tString) + reg.RegisterTypeMapEntry(TypeArray, tA) + reg.RegisterTypeMapEntry(TypeBinary, tBinary) + reg.RegisterTypeMapEntry(TypeUndefined, tUndefined) + reg.RegisterTypeMapEntry(TypeObjectID, tOID) + reg.RegisterTypeMapEntry(TypeBoolean, tBool) + reg.RegisterTypeMapEntry(TypeDateTime, tDateTime) + reg.RegisterTypeMapEntry(TypeRegex, tRegex) + reg.RegisterTypeMapEntry(TypeDBPointer, tDBPointer) + reg.RegisterTypeMapEntry(TypeJavaScript, tJavaScript) + reg.RegisterTypeMapEntry(TypeSymbol, tSymbol) + reg.RegisterTypeMapEntry(TypeCodeWithScope, tCodeWithScope) + reg.RegisterTypeMapEntry(TypeInt32, tInt32) + reg.RegisterTypeMapEntry(TypeInt64, tInt64) + reg.RegisterTypeMapEntry(TypeTimestamp, tTimestamp) + reg.RegisterTypeMapEntry(TypeDecimal128, tDecimal) + reg.RegisterTypeMapEntry(TypeMinKey, tMinKey) + reg.RegisterTypeMapEntry(TypeMaxKey, tMaxKey) + reg.RegisterTypeMapEntry(Type(0), tD) + reg.RegisterTypeMapEntry(TypeEmbeddedDocument, tD) + reg.RegisterInterfaceDecoder(tValueUnmarshaler, ValueDecoderFunc(valueUnmarshalerDecodeValue)) + reg.RegisterInterfaceDecoder(tUnmarshaler, ValueDecoderFunc(unmarshalerDecodeValue)) +} + +// dDecodeValue is the ValueDecoderFunc for D instances. +func dDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.IsValid() || !val.CanSet() || val.Type() != tD { + return ValueDecoderError{Name: "DDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} + } + + switch vrType := vr.Type(); vrType { + case Type(0), TypeEmbeddedDocument: + break + case TypeNull: + val.Set(reflect.Zero(val.Type())) + return vr.ReadNull() + default: + return fmt.Errorf("cannot decode %v into a D", vrType) + } + + dr, err := vr.ReadDocument() + if err != nil { + return err + } + + decoder, err := dc.LookupDecoder(tEmpty) + if err != nil { + return err + } + + // Use the elements in the provided value if it's non nil. Otherwise, allocate a new D instance. + var elems D + if !val.IsNil() { + val.SetLen(0) + elems = val.Interface().(D) + } else { + elems = make(D, 0) + } + + for { + key, elemVr, err := dr.ReadElement() + if errors.Is(err, ErrEOD) { + break + } else if err != nil { + return err + } + + var v any + err = decoder.DecodeValue(dc, elemVr, reflect.ValueOf(&v).Elem()) + if err != nil { + return err + } + + elems = append(elems, E{Key: key, Value: v}) + } + + val.Set(reflect.ValueOf(elems)) + return nil +} + +func booleanDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t.Kind() != reflect.Bool { + return emptyValue, ValueDecoderError{ + Name: "BooleanDecodeValue", + Kinds: []reflect.Kind{reflect.Bool}, + Received: reflect.Zero(t), + } + } + + var b bool + var err error + switch vrType := vr.Type(); vrType { + case TypeInt32: + i32, err := vr.ReadInt32() + if err != nil { + return emptyValue, err + } + b = (i32 != 0) + case TypeInt64: + i64, err := vr.ReadInt64() + if err != nil { + return emptyValue, err + } + b = (i64 != 0) + case TypeDouble: + f64, err := vr.ReadDouble() + if err != nil { + return emptyValue, err + } + b = (f64 != 0) + case TypeBoolean: + b, err = vr.ReadBoolean() + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a boolean", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(b), nil +} + +// booleanDecodeValue is the ValueDecoderFunc for bool types. +func booleanDecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.IsValid() || !val.CanSet() || val.Kind() != reflect.Bool { + return ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val} + } + + elem, err := booleanDecodeType(dctx, vr, val.Type()) + if err != nil { + return err + } + + val.SetBool(elem.Bool()) + return nil +} + +func intDecodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + var i64 int64 + var err error + switch vrType := vr.Type(); vrType { + case TypeInt32: + i32, err := vr.ReadInt32() + if err != nil { + return emptyValue, err + } + i64 = int64(i32) + case TypeInt64: + i64, err = vr.ReadInt64() + if err != nil { + return emptyValue, err + } + case TypeDouble: + f64, err := vr.ReadDouble() + if err != nil { + return emptyValue, err + } + if !dc.truncate && math.Floor(f64) != f64 { + return emptyValue, errCannotTruncate + } + if f64 > float64(math.MaxInt64) { + return emptyValue, fmt.Errorf("%g overflows int64", f64) + } + i64 = int64(f64) + case TypeBoolean: + b, err := vr.ReadBoolean() + if err != nil { + return emptyValue, err + } + if b { + i64 = 1 + } + case TypeNull: + if err = vr.ReadNull(); err != nil { + return emptyValue, err + } + case TypeUndefined: + if err = vr.ReadUndefined(); err != nil { + return emptyValue, err + } + default: + return emptyValue, fmt.Errorf("cannot decode %v into an integer type", vrType) + } + + switch t.Kind() { + case reflect.Int8: + if i64 < math.MinInt8 || i64 > math.MaxInt8 { + return emptyValue, fmt.Errorf("%d overflows int8", i64) + } + + return reflect.ValueOf(int8(i64)), nil + case reflect.Int16: + if i64 < math.MinInt16 || i64 > math.MaxInt16 { + return emptyValue, fmt.Errorf("%d overflows int16", i64) + } + + return reflect.ValueOf(int16(i64)), nil + case reflect.Int32: + if i64 < math.MinInt32 || i64 > math.MaxInt32 { + return emptyValue, fmt.Errorf("%d overflows int32", i64) + } + + return reflect.ValueOf(int32(i64)), nil + case reflect.Int64: + return reflect.ValueOf(i64), nil + case reflect.Int: + if i64 > math.MaxInt { // Can we fit this inside of an int + return emptyValue, fmt.Errorf("%d overflows int", i64) + } + + return reflect.ValueOf(int(i64)), nil + default: + return emptyValue, ValueDecoderError{ + Name: "IntDecodeValue", + Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int}, + Received: reflect.Zero(t), + } + } +} + +// intDecodeValue is the ValueDecoderFunc for int types. +func intDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() { + return ValueDecoderError{ + Name: "IntDecodeValue", + Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int}, + Received: val, + } + } + + elem, err := intDecodeType(dc, vr, val.Type()) + if err != nil { + return err + } + + val.SetInt(elem.Int()) + return nil +} + +func floatDecodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + var f float64 + var err error + switch vrType := vr.Type(); vrType { + case TypeInt32: + i32, err := vr.ReadInt32() + if err != nil { + return emptyValue, err + } + f = float64(i32) + case TypeInt64: + i64, err := vr.ReadInt64() + if err != nil { + return emptyValue, err + } + f = float64(i64) + case TypeDouble: + f, err = vr.ReadDouble() + if err != nil { + return emptyValue, err + } + case TypeBoolean: + b, err := vr.ReadBoolean() + if err != nil { + return emptyValue, err + } + if b { + f = 1 + } + case TypeNull: + if err = vr.ReadNull(); err != nil { + return emptyValue, err + } + case TypeUndefined: + if err = vr.ReadUndefined(); err != nil { + return emptyValue, err + } + default: + return emptyValue, fmt.Errorf("cannot decode %v into a float32 or float64 type", vrType) + } + + switch t.Kind() { + case reflect.Float32: + if !dc.truncate && float64(float32(f)) != f { + return emptyValue, errCannotTruncate + } + + return reflect.ValueOf(float32(f)), nil + case reflect.Float64: + return reflect.ValueOf(f), nil + default: + return emptyValue, ValueDecoderError{ + Name: "FloatDecodeValue", + Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, + Received: reflect.Zero(t), + } + } +} + +// floatDecodeValue is the ValueDecoderFunc for float types. +func floatDecodeValue(ec DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() { + return ValueDecoderError{ + Name: "FloatDecodeValue", + Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, + Received: val, + } + } + + elem, err := floatDecodeType(ec, vr, val.Type()) + if err != nil { + return err + } + + val.SetFloat(elem.Float()) + return nil +} + +func javaScriptDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tJavaScript { + return emptyValue, ValueDecoderError{ + Name: "JavaScriptDecodeValue", + Types: []reflect.Type{tJavaScript}, + Received: reflect.Zero(t), + } + } + + var js string + var err error + switch vrType := vr.Type(); vrType { + case TypeJavaScript: + js, err = vr.ReadJavascript() + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a JavaScript", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(JavaScript(js)), nil +} + +// javaScriptDecodeValue is the ValueDecoderFunc for the JavaScript type. +func javaScriptDecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tJavaScript { + return ValueDecoderError{Name: "JavaScriptDecodeValue", Types: []reflect.Type{tJavaScript}, Received: val} + } + + elem, err := javaScriptDecodeType(dctx, vr, tJavaScript) + if err != nil { + return err + } + + val.SetString(elem.String()) + return nil +} + +func symbolDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tSymbol { + return emptyValue, ValueDecoderError{ + Name: "SymbolDecodeValue", + Types: []reflect.Type{tSymbol}, + Received: reflect.Zero(t), + } + } + + var symbol string + var err error + switch vrType := vr.Type(); vrType { + case TypeString: + symbol, err = vr.ReadString() + case TypeSymbol: + symbol, err = vr.ReadSymbol() + case TypeBinary: + data, subtype, err := vr.ReadBinary() + if err != nil { + return emptyValue, err + } + + if subtype != TypeBinaryGeneric && subtype != TypeBinaryBinaryOld { + return emptyValue, decodeBinaryError{subtype: subtype, typeName: "Symbol"} + } + symbol = string(data) + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a Symbol", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(Symbol(symbol)), nil +} + +// symbolDecodeValue is the ValueDecoderFunc for the Symbol type. +func symbolDecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tSymbol { + return ValueDecoderError{Name: "SymbolDecodeValue", Types: []reflect.Type{tSymbol}, Received: val} + } + + elem, err := symbolDecodeType(dctx, vr, tSymbol) + if err != nil { + return err + } + + val.SetString(elem.String()) + return nil +} + +func binaryDecode(vr ValueReader) (Binary, error) { + var b Binary + + var data []byte + var subtype byte + var err error + switch vrType := vr.Type(); vrType { + case TypeBinary: + data, subtype, err = vr.ReadBinary() + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return b, fmt.Errorf("cannot decode %v into a Binary", vrType) + } + if err != nil { + return b, err + } + b.Subtype = subtype + b.Data = data + + return b, nil +} + +func binaryDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tBinary { + return emptyValue, ValueDecoderError{ + Name: "BinaryDecodeValue", + Types: []reflect.Type{tBinary}, + Received: reflect.Zero(t), + } + } + + b, err := binaryDecode(vr) + if err != nil { + return emptyValue, err + } + return reflect.ValueOf(b), nil +} + +// binaryDecodeValue is the ValueDecoderFunc for Binary. +func binaryDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tBinary { + return ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tBinary}, Received: val} + } + + elem, err := binaryDecodeType(dc, vr, tBinary) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func vectorDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tVector { + return emptyValue, ValueDecoderError{ + Name: "VectorDecodeValue", + Types: []reflect.Type{tVector}, + Received: reflect.Zero(t), + } + } + + b, err := binaryDecode(vr) + if err != nil { + return emptyValue, err + } + + v, err := NewVectorFromBinary(b) + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(v), nil +} + +// vectorDecodeValue is the ValueDecoderFunc for Vector. +func vectorDecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error { + t := val.Type() + if !val.CanSet() || t != tVector { + return ValueDecoderError{ + Name: "VectorDecodeValue", + Types: []reflect.Type{tVector}, + Received: val, + } + } + + elem, err := vectorDecodeType(dctx, vr, t) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func undefinedDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tUndefined { + return emptyValue, ValueDecoderError{ + Name: "UndefinedDecodeValue", + Types: []reflect.Type{tUndefined}, + Received: reflect.Zero(t), + } + } + + var err error + switch vrType := vr.Type(); vrType { + case TypeUndefined: + err = vr.ReadUndefined() + case TypeNull: + err = vr.ReadNull() + default: + return emptyValue, fmt.Errorf("cannot decode %v into an Undefined", vr.Type()) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(Undefined{}), nil +} + +// undefinedDecodeValue is the ValueDecoderFunc for Undefined. +func undefinedDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tUndefined { + return ValueDecoderError{Name: "UndefinedDecodeValue", Types: []reflect.Type{tUndefined}, Received: val} + } + + elem, err := undefinedDecodeType(dc, vr, tUndefined) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +// Accept both 12-byte string and pretty-printed 24-byte hex string formats. +func objectIDDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tOID { + return emptyValue, ValueDecoderError{ + Name: "ObjectIDDecodeValue", + Types: []reflect.Type{tOID}, + Received: reflect.Zero(t), + } + } + + var oid ObjectID + var err error + switch vrType := vr.Type(); vrType { + case TypeObjectID: + oid, err = vr.ReadObjectID() + if err != nil { + return emptyValue, err + } + case TypeString: + str, err := vr.ReadString() + if err != nil { + return emptyValue, err + } + if oid, err = ObjectIDFromHex(str); err == nil { + break + } + if len(str) != 12 { + return emptyValue, fmt.Errorf("an ObjectID string must be exactly 12 bytes long (got %v)", len(str)) + } + byteArr := []byte(str) + copy(oid[:], byteArr) + case TypeNull: + if err = vr.ReadNull(); err != nil { + return emptyValue, err + } + case TypeUndefined: + if err = vr.ReadUndefined(); err != nil { + return emptyValue, err + } + default: + return emptyValue, fmt.Errorf("cannot decode %v into an ObjectID", vrType) + } + + return reflect.ValueOf(oid), nil +} + +// objectIDDecodeValue is the ValueDecoderFunc for ObjectID. +func objectIDDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tOID { + return ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}, Received: val} + } + + elem, err := objectIDDecodeType(dc, vr, tOID) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func dateTimeDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tDateTime { + return emptyValue, ValueDecoderError{ + Name: "DateTimeDecodeValue", + Types: []reflect.Type{tDateTime}, + Received: reflect.Zero(t), + } + } + + var dt int64 + var err error + switch vrType := vr.Type(); vrType { + case TypeDateTime: + dt, err = vr.ReadDateTime() + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a DateTime", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(DateTime(dt)), nil +} + +// dateTimeDecodeValue is the ValueDecoderFunc for DateTime. +func dateTimeDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tDateTime { + return ValueDecoderError{Name: "DateTimeDecodeValue", Types: []reflect.Type{tDateTime}, Received: val} + } + + elem, err := dateTimeDecodeType(dc, vr, tDateTime) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func nullDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tNull { + return emptyValue, ValueDecoderError{ + Name: "NullDecodeValue", + Types: []reflect.Type{tNull}, + Received: reflect.Zero(t), + } + } + + var err error + switch vrType := vr.Type(); vrType { + case TypeUndefined: + err = vr.ReadUndefined() + case TypeNull: + err = vr.ReadNull() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a Null", vr.Type()) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(Null{}), nil +} + +// nullDecodeValue is the ValueDecoderFunc for Null. +func nullDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tNull { + return ValueDecoderError{Name: "NullDecodeValue", Types: []reflect.Type{tNull}, Received: val} + } + + elem, err := nullDecodeType(dc, vr, tNull) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func regexDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tRegex { + return emptyValue, ValueDecoderError{ + Name: "RegexDecodeValue", + Types: []reflect.Type{tRegex}, + Received: reflect.Zero(t), + } + } + + var pattern, options string + var err error + switch vrType := vr.Type(); vrType { + case TypeRegex: + pattern, options, err = vr.ReadRegex() + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a Regex", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(Regex{Pattern: pattern, Options: options}), nil +} + +// regexDecodeValue is the ValueDecoderFunc for Regex. +func regexDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tRegex { + return ValueDecoderError{Name: "RegexDecodeValue", Types: []reflect.Type{tRegex}, Received: val} + } + + elem, err := regexDecodeType(dc, vr, tRegex) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func dbPointerDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tDBPointer { + return emptyValue, ValueDecoderError{ + Name: "DBPointerDecodeValue", + Types: []reflect.Type{tDBPointer}, + Received: reflect.Zero(t), + } + } + + var ns string + var pointer ObjectID + var err error + switch vrType := vr.Type(); vrType { + case TypeDBPointer: + ns, pointer, err = vr.ReadDBPointer() + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a DBPointer", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(DBPointer{DB: ns, Pointer: pointer}), nil +} + +// dbPointerDecodeValue is the ValueDecoderFunc for DBPointer. +func dbPointerDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tDBPointer { + return ValueDecoderError{Name: "DBPointerDecodeValue", Types: []reflect.Type{tDBPointer}, Received: val} + } + + elem, err := dbPointerDecodeType(dc, vr, tDBPointer) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func timestampDecodeType(_ DecodeContext, vr ValueReader, reflectType reflect.Type) (reflect.Value, error) { + if reflectType != tTimestamp { + return emptyValue, ValueDecoderError{ + Name: "TimestampDecodeValue", + Types: []reflect.Type{tTimestamp}, + Received: reflect.Zero(reflectType), + } + } + + var t, incr uint32 + var err error + switch vrType := vr.Type(); vrType { + case TypeTimestamp: + t, incr, err = vr.ReadTimestamp() + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a Timestamp", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(Timestamp{T: t, I: incr}), nil +} + +// timestampDecodeValue is the ValueDecoderFunc for Timestamp. +func timestampDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tTimestamp { + return ValueDecoderError{Name: "TimestampDecodeValue", Types: []reflect.Type{tTimestamp}, Received: val} + } + + elem, err := timestampDecodeType(dc, vr, tTimestamp) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func minKeyDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tMinKey { + return emptyValue, ValueDecoderError{ + Name: "MinKeyDecodeValue", + Types: []reflect.Type{tMinKey}, + Received: reflect.Zero(t), + } + } + + var err error + switch vrType := vr.Type(); vrType { + case TypeMinKey: + err = vr.ReadMinKey() + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a MinKey", vr.Type()) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(MinKey{}), nil +} + +// minKeyDecodeValue is the ValueDecoderFunc for MinKey. +func minKeyDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tMinKey { + return ValueDecoderError{Name: "MinKeyDecodeValue", Types: []reflect.Type{tMinKey}, Received: val} + } + + elem, err := minKeyDecodeType(dc, vr, tMinKey) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func maxKeyDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tMaxKey { + return emptyValue, ValueDecoderError{ + Name: "MaxKeyDecodeValue", + Types: []reflect.Type{tMaxKey}, + Received: reflect.Zero(t), + } + } + + var err error + switch vrType := vr.Type(); vrType { + case TypeMaxKey: + err = vr.ReadMaxKey() + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a MaxKey", vr.Type()) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(MaxKey{}), nil +} + +// maxKeyDecodeValue is the ValueDecoderFunc for MaxKey. +func maxKeyDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tMaxKey { + return ValueDecoderError{Name: "MaxKeyDecodeValue", Types: []reflect.Type{tMaxKey}, Received: val} + } + + elem, err := maxKeyDecodeType(dc, vr, tMaxKey) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func decimal128DecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tDecimal { + return emptyValue, ValueDecoderError{ + Name: "Decimal128DecodeValue", + Types: []reflect.Type{tDecimal}, + Received: reflect.Zero(t), + } + } + + var d128 Decimal128 + var err error + switch vrType := vr.Type(); vrType { + case TypeDecimal128: + d128, err = vr.ReadDecimal128() + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a Decimal128", vr.Type()) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(d128), nil +} + +// decimal128DecodeValue is the ValueDecoderFunc for Decimal128. +func decimal128DecodeValue(dctx DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tDecimal { + return ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}, Received: val} + } + + elem, err := decimal128DecodeType(dctx, vr, tDecimal) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func jsonNumberDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tJSONNumber { + return emptyValue, ValueDecoderError{ + Name: "JSONNumberDecodeValue", + Types: []reflect.Type{tJSONNumber}, + Received: reflect.Zero(t), + } + } + + var jsonNum json.Number + var err error + switch vrType := vr.Type(); vrType { + case TypeDouble: + f64, err := vr.ReadDouble() + if err != nil { + return emptyValue, err + } + jsonNum = json.Number(strconv.FormatFloat(f64, 'f', -1, 64)) + case TypeInt32: + i32, err := vr.ReadInt32() + if err != nil { + return emptyValue, err + } + jsonNum = json.Number(strconv.FormatInt(int64(i32), 10)) + case TypeInt64: + i64, err := vr.ReadInt64() + if err != nil { + return emptyValue, err + } + jsonNum = json.Number(strconv.FormatInt(i64, 10)) + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a json.Number", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(jsonNum), nil +} + +// jsonNumberDecodeValue is the ValueDecoderFunc for json.Number. +func jsonNumberDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tJSONNumber { + return ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}, Received: val} + } + + elem, err := jsonNumberDecodeType(dc, vr, tJSONNumber) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func urlDecodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tURL { + return emptyValue, ValueDecoderError{ + Name: "URLDecodeValue", + Types: []reflect.Type{tURL}, + Received: reflect.Zero(t), + } + } + + urlPtr := &url.URL{} + var err error + switch vrType := vr.Type(); vrType { + case TypeString: + var str string // Declare str here to avoid shadowing err during the ReadString call. + str, err = vr.ReadString() + if err != nil { + return emptyValue, err + } + + urlPtr, err = url.Parse(str) + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a *url.URL", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(urlPtr).Elem(), nil +} + +// urlDecodeValue is the ValueDecoderFunc for url.URL. +func urlDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tURL { + return ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}, Received: val} + } + + elem, err := urlDecodeType(dc, vr, tURL) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +// arrayDecodeValue is the ValueDecoderFunc for array types. +func arrayDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Array { + return ValueDecoderError{Name: "ArrayDecodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val} + } + + switch vrType := vr.Type(); vrType { + case TypeArray: + case Type(0), TypeEmbeddedDocument: + if val.Type().Elem() != tE { + return fmt.Errorf("cannot decode document into %s", val.Type()) + } + case TypeBinary: + if val.Type().Elem() != tByte { + return fmt.Errorf("ArrayDecodeValue can only be used to decode binary into a byte array, got %v", vrType) + } + data, subtype, err := vr.ReadBinary() + if err != nil { + return err + } + if subtype != TypeBinaryGeneric && subtype != TypeBinaryBinaryOld { + return fmt.Errorf("ArrayDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", TypeBinary, subtype) + } + + if len(data) > val.Len() { + return fmt.Errorf("more elements returned in array than can fit inside %s", val.Type()) + } + + for idx, elem := range data { + val.Index(idx).Set(reflect.ValueOf(elem)) + } + return nil + case TypeNull: + val.Set(reflect.Zero(val.Type())) + return vr.ReadNull() + case TypeUndefined: + val.Set(reflect.Zero(val.Type())) + return vr.ReadUndefined() + default: + return fmt.Errorf("cannot decode %v into an array", vrType) + } + + var elemsFunc func(DecodeContext, ValueReader, reflect.Value) ([]reflect.Value, error) + switch val.Type().Elem() { + case tE: + elemsFunc = decodeD + default: + elemsFunc = decodeDefault + } + + elems, err := elemsFunc(dc, vr, val) + if err != nil { + return err + } + + if len(elems) > val.Len() { + return fmt.Errorf("more elements returned in array than can fit inside %s, got %v elements", val.Type(), len(elems)) + } + + for idx, elem := range elems { + val.Index(idx).Set(elem) + } + + return nil +} + +// valueUnmarshalerDecodeValue is the ValueDecoderFunc for ValueUnmarshaler implementations. +func valueUnmarshalerDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.IsValid() || (!val.Type().Implements(tValueUnmarshaler) && !reflect.PtrTo(val.Type()).Implements(tValueUnmarshaler)) { + return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val} + } + + // If BSON value is null and the go value is a pointer, then don't call + // UnmarshalBSONValue. Even if the Go pointer is already initialized (i.e., + // non-nil), encountering null in BSON will result in the pointer being + // directly set to nil here. Since the pointer is being replaced with nil, + // there is no opportunity (or reason) for the custom UnmarshalBSONValue logic + // to be called. + if vr.Type() == TypeNull && val.Kind() == reflect.Ptr { + val.Set(reflect.Zero(val.Type())) + + return vr.ReadNull() + } + + if val.Kind() == reflect.Ptr && val.IsNil() { + if !val.CanSet() { + return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val} + } + val.Set(reflect.New(val.Type().Elem())) + } + + if !val.Type().Implements(tValueUnmarshaler) { + if !val.CanAddr() { + return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val} + } + val = val.Addr() // If the type doesn't implement the interface, a pointer to it must. + } + + t, src, err := copyValueToBytes(vr) + if err != nil { + return err + } + + m, ok := val.Interface().(ValueUnmarshaler) + if !ok { + // NB: this error should be unreachable due to the above checks + return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val} + } + return m.UnmarshalBSONValue(byte(t), src) +} + +// unmarshalerDecodeValue is the ValueDecoderFunc for Unmarshaler implementations. +func unmarshalerDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.IsValid() || (!val.Type().Implements(tUnmarshaler) && !reflect.PtrTo(val.Type()).Implements(tUnmarshaler)) { + return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val} + } + + if val.Kind() == reflect.Ptr && val.IsNil() { + if !val.CanSet() { + return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val} + } + val.Set(reflect.New(val.Type().Elem())) + } + + _, src, err := copyValueToBytes(vr) + if err != nil { + return err + } + + // If the target Go value is a pointer and the BSON field value is empty, set the value to the + // zero value of the pointer (nil) and don't call UnmarshalBSON. UnmarshalBSON has no way to + // change the pointer value from within the function (only the value at the pointer address), + // so it can't set the pointer to "nil" itself. Since the most common Go value for an empty BSON + // field value is "nil", we set "nil" here and don't call UnmarshalBSON. This behavior matches + // the behavior of the Go "encoding/json" unmarshaler when the target Go value is a pointer and + // the JSON field value is "null". + if val.Kind() == reflect.Ptr && len(src) == 0 { + val.Set(reflect.Zero(val.Type())) + return nil + } + + if !val.Type().Implements(tUnmarshaler) { + if !val.CanAddr() { + return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val} + } + val = val.Addr() // If the type doesn't implement the interface, a pointer to it must. + } + + m, ok := val.Interface().(Unmarshaler) + if !ok { + // NB: this error should be unreachable due to the above checks + return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val} + } + return m.UnmarshalBSON(src) +} + +// coreDocumentDecodeValue is the ValueDecoderFunc for bsoncore.Document. +func coreDocumentDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tCoreDocument { + return ValueDecoderError{Name: "CoreDocumentDecodeValue", Types: []reflect.Type{tCoreDocument}, Received: val} + } + + if val.IsNil() { + val.Set(reflect.MakeSlice(val.Type(), 0, 0)) + } + + val.SetLen(0) + + cdoc, err := appendDocumentBytes(val.Interface().(bsoncore.Document), vr) + val.Set(reflect.ValueOf(cdoc)) + return err +} + +func decodeDefault(dc DecodeContext, vr ValueReader, val reflect.Value) ([]reflect.Value, error) { + elems := make([]reflect.Value, 0) + + ar, err := vr.ReadArray() + if err != nil { + return nil, err + } + + eType := val.Type().Elem() + + isInterfaceSlice := eType.Kind() == reflect.Interface && val.Len() > 0 + + // If this is not an interface slice with pre-populated elements, we can look up + // the decoder for eType once. + var vDecoder ValueDecoder + if !isInterfaceSlice { + vDecoder, err = dc.LookupDecoder(eType) + if err != nil { + return nil, err + } + } + + idx := 0 + for { + vr, err := ar.ReadValue() + if errors.Is(err, ErrEOA) { + break + } + if err != nil { + return nil, err + } + + var elem reflect.Value + if isInterfaceSlice && idx < val.Len() { + // Decode into an existing any slot. + + elem = val.Index(idx).Elem() + switch { + case elem.Kind() != reflect.Ptr || elem.IsNil(): + valueDecoder, err := dc.LookupDecoder(elem.Type()) + if err != nil { + return nil, err + } + + // If an element is allocated and unsettable, it must be overwritten. + if !elem.CanSet() { + elem = reflect.New(elem.Type()).Elem() + } + + err = valueDecoder.DecodeValue(dc, vr, elem) + if err != nil { + return nil, newDecodeError(strconv.Itoa(idx), err) + } + case vr.Type() == TypeNull: + if err = vr.ReadNull(); err != nil { + return nil, err + } + elem = reflect.Zero(val.Index(idx).Type()) + default: + e := elem.Elem() + valueDecoder, err := dc.LookupDecoder(e.Type()) + if err != nil { + return nil, err + } + err = valueDecoder.DecodeValue(dc, vr, e) + if err != nil { + return nil, newDecodeError(strconv.Itoa(idx), err) + } + } + } else { + // For non-interface slices, or if we've exhausted the pre-populated + // slots, we create a fresh value. + + if vDecoder == nil { + vDecoder, err = dc.LookupDecoder(eType) + if err != nil { + return nil, err + } + } + elem, err = decodeTypeOrValueWithInfo(vDecoder, dc, vr, eType) + if err != nil { + return nil, newDecodeError(strconv.Itoa(idx), err) + } + } + + elems = append(elems, elem) + idx++ + } + + return elems, nil +} + +func codeWithScopeDecodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tCodeWithScope { + return emptyValue, ValueDecoderError{ + Name: "CodeWithScopeDecodeValue", + Types: []reflect.Type{tCodeWithScope}, + Received: reflect.Zero(t), + } + } + + var cws CodeWithScope + var err error + switch vrType := vr.Type(); vrType { + case TypeCodeWithScope: + code, dr, err := vr.ReadCodeWithScope() + if err != nil { + return emptyValue, err + } + + scope := reflect.New(tD).Elem() + elems, err := decodeElemsFromDocumentReader(dc, dr) + if err != nil { + return emptyValue, err + } + + scope.Set(reflect.MakeSlice(tD, 0, len(elems))) + scope.Set(reflect.Append(scope, elems...)) + + cws = CodeWithScope{ + Code: JavaScript(code), + Scope: scope.Interface().(D), + } + case TypeNull: + err = vr.ReadNull() + case TypeUndefined: + err = vr.ReadUndefined() + default: + return emptyValue, fmt.Errorf("cannot decode %v into a CodeWithScope", vrType) + } + if err != nil { + return emptyValue, err + } + + return reflect.ValueOf(cws), nil +} + +// codeWithScopeDecodeValue is the ValueDecoderFunc for CodeWithScope. +func codeWithScopeDecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tCodeWithScope { + return ValueDecoderError{Name: "CodeWithScopeDecodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val} + } + + elem, err := codeWithScopeDecodeType(dc, vr, tCodeWithScope) + if err != nil { + return err + } + + val.Set(elem) + return nil +} + +func decodeD(dc DecodeContext, vr ValueReader, _ reflect.Value) ([]reflect.Value, error) { + switch vr.Type() { + case Type(0), TypeEmbeddedDocument: + default: + return nil, fmt.Errorf("cannot decode %v into a D", vr.Type()) + } + + dr, err := vr.ReadDocument() + if err != nil { + return nil, err + } + + return decodeElemsFromDocumentReader(dc, dr) +} + +func decodeElemsFromDocumentReader(dc DecodeContext, dr DocumentReader) ([]reflect.Value, error) { + decoder, err := dc.LookupDecoder(tEmpty) + if err != nil { + return nil, err + } + + elems := make([]reflect.Value, 0) + for { + key, vr, err := dr.ReadElement() + if errors.Is(err, ErrEOD) { + break + } + if err != nil { + return nil, err + } + + val := reflect.New(tEmpty).Elem() + err = decoder.DecodeValue(dc, vr, val) + if err != nil { + return nil, newDecodeError(key, err) + } + + elems = append(elems, reflect.ValueOf(E{Key: key, Value: val.Interface()})) + } + + return elems, nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_encoders.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_encoders.go new file mode 100644 index 000000000..67d464cb8 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/default_value_encoders.go @@ -0,0 +1,517 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "encoding/json" + "errors" + "math" + "net/url" + "reflect" + "sync" + + "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore" +) + +var bvwPool = sync.Pool{ + New: func() any { + return new(valueWriter) + }, +} + +var errInvalidValue = errors.New("cannot encode invalid element") + +var sliceWriterPool = sync.Pool{ + New: func() any { + sw := make(sliceWriter, 0) + return &sw + }, +} + +func encodeElement(ec EncodeContext, dw DocumentWriter, e E) error { + vw, err := dw.WriteDocumentElement(e.Key) + if err != nil { + return err + } + + if e.Value == nil { + return vw.WriteNull() + } + encoder, err := ec.LookupEncoder(reflect.TypeOf(e.Value)) + if err != nil { + return err + } + + err = encoder.EncodeValue(ec, vw, reflect.ValueOf(e.Value)) + if err != nil { + return err + } + return nil +} + +// registerDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with +// the provided RegistryBuilder. +func registerDefaultEncoders(reg *Registry) { + mapEncoder := &mapCodec{} + uintCodec := &uintCodec{} + + reg.RegisterTypeEncoder(tByteSlice, &byteSliceCodec{}) + reg.RegisterTypeEncoder(tTime, &timeCodec{}) + reg.RegisterTypeEncoder(tEmpty, &emptyInterfaceCodec{}) + reg.RegisterTypeEncoder(tCoreArray, &arrayCodec{}) + reg.RegisterTypeEncoder(tOID, ValueEncoderFunc(objectIDEncodeValue)) + reg.RegisterTypeEncoder(tDecimal, ValueEncoderFunc(decimal128EncodeValue)) + reg.RegisterTypeEncoder(tJSONNumber, ValueEncoderFunc(jsonNumberEncodeValue)) + reg.RegisterTypeEncoder(tURL, ValueEncoderFunc(urlEncodeValue)) + reg.RegisterTypeEncoder(tJavaScript, ValueEncoderFunc(javaScriptEncodeValue)) + reg.RegisterTypeEncoder(tSymbol, ValueEncoderFunc(symbolEncodeValue)) + reg.RegisterTypeEncoder(tBinary, ValueEncoderFunc(binaryEncodeValue)) + reg.RegisterTypeEncoder(tVector, ValueEncoderFunc(vectorEncodeValue)) + reg.RegisterTypeEncoder(tUndefined, ValueEncoderFunc(undefinedEncodeValue)) + reg.RegisterTypeEncoder(tDateTime, ValueEncoderFunc(dateTimeEncodeValue)) + reg.RegisterTypeEncoder(tNull, ValueEncoderFunc(nullEncodeValue)) + reg.RegisterTypeEncoder(tRegex, ValueEncoderFunc(regexEncodeValue)) + reg.RegisterTypeEncoder(tDBPointer, ValueEncoderFunc(dbPointerEncodeValue)) + reg.RegisterTypeEncoder(tTimestamp, ValueEncoderFunc(timestampEncodeValue)) + reg.RegisterTypeEncoder(tMinKey, ValueEncoderFunc(minKeyEncodeValue)) + reg.RegisterTypeEncoder(tMaxKey, ValueEncoderFunc(maxKeyEncodeValue)) + reg.RegisterTypeEncoder(tCoreDocument, ValueEncoderFunc(coreDocumentEncodeValue)) + reg.RegisterTypeEncoder(tCodeWithScope, ValueEncoderFunc(codeWithScopeEncodeValue)) + reg.RegisterKindEncoder(reflect.Bool, ValueEncoderFunc(booleanEncodeValue)) + reg.RegisterKindEncoder(reflect.Int, ValueEncoderFunc(intEncodeValue)) + reg.RegisterKindEncoder(reflect.Int8, ValueEncoderFunc(intEncodeValue)) + reg.RegisterKindEncoder(reflect.Int16, ValueEncoderFunc(intEncodeValue)) + reg.RegisterKindEncoder(reflect.Int32, ValueEncoderFunc(intEncodeValue)) + reg.RegisterKindEncoder(reflect.Int64, ValueEncoderFunc(intEncodeValue)) + reg.RegisterKindEncoder(reflect.Uint, uintCodec) + reg.RegisterKindEncoder(reflect.Uint8, uintCodec) + reg.RegisterKindEncoder(reflect.Uint16, uintCodec) + reg.RegisterKindEncoder(reflect.Uint32, uintCodec) + reg.RegisterKindEncoder(reflect.Uint64, uintCodec) + reg.RegisterKindEncoder(reflect.Float32, ValueEncoderFunc(floatEncodeValue)) + reg.RegisterKindEncoder(reflect.Float64, ValueEncoderFunc(floatEncodeValue)) + reg.RegisterKindEncoder(reflect.Array, ValueEncoderFunc(arrayEncodeValue)) + reg.RegisterKindEncoder(reflect.Map, mapEncoder) + reg.RegisterKindEncoder(reflect.Slice, &sliceCodec{}) + reg.RegisterKindEncoder(reflect.String, &stringCodec{}) + reg.RegisterKindEncoder(reflect.Struct, newStructCodec(mapEncoder)) + reg.RegisterKindEncoder(reflect.Ptr, &pointerCodec{}) + reg.RegisterInterfaceEncoder(tValueMarshaler, ValueEncoderFunc(valueMarshalerEncodeValue)) + reg.RegisterInterfaceEncoder(tMarshaler, ValueEncoderFunc(marshalerEncodeValue)) +} + +// booleanEncodeValue is the ValueEncoderFunc for bool types. +func booleanEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Bool { + return ValueEncoderError{Name: "BooleanEncodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val} + } + return vw.WriteBoolean(val.Bool()) +} + +func fitsIn32Bits(i int64) bool { + return math.MinInt32 <= i && i <= math.MaxInt32 +} + +// intEncodeValue is the ValueEncoderFunc for int types. +func intEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error { + switch val.Kind() { + case reflect.Int8, reflect.Int16, reflect.Int32: + return vw.WriteInt32(int32(val.Int())) + case reflect.Int: + i64 := val.Int() + if fitsIn32Bits(i64) { + return vw.WriteInt32(int32(i64)) + } + return vw.WriteInt64(i64) + case reflect.Int64: + i64 := val.Int() + if ec.minSize && fitsIn32Bits(i64) { + return vw.WriteInt32(int32(i64)) + } + return vw.WriteInt64(i64) + } + + return ValueEncoderError{ + Name: "IntEncodeValue", + Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int}, + Received: val, + } +} + +// floatEncodeValue is the ValueEncoderFunc for float types. +func floatEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + switch val.Kind() { + case reflect.Float32, reflect.Float64: + return vw.WriteDouble(val.Float()) + } + + return ValueEncoderError{Name: "FloatEncodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val} +} + +// objectIDEncodeValue is the ValueEncoderFunc for ObjectID. +func objectIDEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tOID { + return ValueEncoderError{Name: "ObjectIDEncodeValue", Types: []reflect.Type{tOID}, Received: val} + } + return vw.WriteObjectID(val.Interface().(ObjectID)) +} + +// decimal128EncodeValue is the ValueEncoderFunc for Decimal128. +func decimal128EncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tDecimal { + return ValueEncoderError{Name: "Decimal128EncodeValue", Types: []reflect.Type{tDecimal}, Received: val} + } + return vw.WriteDecimal128(val.Interface().(Decimal128)) +} + +// jsonNumberEncodeValue is the ValueEncoderFunc for json.Number. +func jsonNumberEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tJSONNumber { + return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: val} + } + jsnum := val.Interface().(json.Number) + + // Attempt int first, then float64 + if i64, err := jsnum.Int64(); err == nil { + return intEncodeValue(ec, vw, reflect.ValueOf(i64)) + } + + f64, err := jsnum.Float64() + if err != nil { + return err + } + + return floatEncodeValue(ec, vw, reflect.ValueOf(f64)) +} + +// urlEncodeValue is the ValueEncoderFunc for url.URL. +func urlEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tURL { + return ValueEncoderError{Name: "URLEncodeValue", Types: []reflect.Type{tURL}, Received: val} + } + u := val.Interface().(url.URL) + return vw.WriteString(u.String()) +} + +// arrayEncodeValue is the ValueEncoderFunc for array types. +func arrayEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Kind() != reflect.Array { + return ValueEncoderError{Name: "ArrayEncodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val} + } + + // If we have a []E we want to treat it as a document instead of as an array. + if val.Type().Elem() == tE { + dw, err := vw.WriteDocument() + if err != nil { + return err + } + + for idx := 0; idx < val.Len(); idx++ { + e := val.Index(idx).Interface().(E) + err = encodeElement(ec, dw, e) + if err != nil { + return err + } + } + + return dw.WriteDocumentEnd() + } + + // If we have a []byte we want to treat it as a binary instead of as an array. + if val.Type().Elem() == tByte { + var byteSlice []byte + for idx := 0; idx < val.Len(); idx++ { + byteSlice = append(byteSlice, val.Index(idx).Interface().(byte)) + } + return vw.WriteBinary(byteSlice) + } + + aw, err := vw.WriteArray() + if err != nil { + return err + } + + elemType := val.Type().Elem() + encoder, err := ec.LookupEncoder(elemType) + if err != nil && elemType.Kind() != reflect.Interface { + return err + } + + for idx := 0; idx < val.Len(); idx++ { + currEncoder, currVal, lookupErr := lookupElementEncoder(ec, encoder, val.Index(idx)) + if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) { + return lookupErr + } + + vw, err := aw.WriteArrayElement() + if err != nil { + return err + } + + if errors.Is(lookupErr, errInvalidValue) { + err = vw.WriteNull() + if err != nil { + return err + } + continue + } + + err = currEncoder.EncodeValue(ec, vw, currVal) + if err != nil { + return err + } + } + return aw.WriteArrayEnd() +} + +func lookupElementEncoder(ec EncodeContext, origEncoder ValueEncoder, currVal reflect.Value) (ValueEncoder, reflect.Value, error) { + if origEncoder != nil || (currVal.Kind() != reflect.Interface) { + return origEncoder, currVal, nil + } + currVal = currVal.Elem() + if !currVal.IsValid() { + return nil, currVal, errInvalidValue + } + currEncoder, err := ec.LookupEncoder(currVal.Type()) + + return currEncoder, currVal, err +} + +// valueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations. +func valueMarshalerEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + // Either val or a pointer to val must implement ValueMarshaler + switch { + case !val.IsValid(): + return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val} + case val.Type().Implements(tValueMarshaler): + // If ValueMarshaler is implemented on a concrete type, make sure that val isn't a nil pointer + if isImplementationNil(val, tValueMarshaler) { + return vw.WriteNull() + } + case reflect.PtrTo(val.Type()).Implements(tValueMarshaler) && val.CanAddr(): + val = val.Addr() + default: + return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val} + } + + m, ok := val.Interface().(ValueMarshaler) + if !ok { + return vw.WriteNull() + } + t, data, err := m.MarshalBSONValue() + if err != nil { + return err + } + return copyValueFromBytes(vw, Type(t), data) +} + +// marshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations. +func marshalerEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + // Either val or a pointer to val must implement Marshaler + switch { + case !val.IsValid(): + return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val} + case val.Type().Implements(tMarshaler): + // If Marshaler is implemented on a concrete type, make sure that val isn't a nil pointer + if isImplementationNil(val, tMarshaler) { + return vw.WriteNull() + } + case reflect.PtrTo(val.Type()).Implements(tMarshaler) && val.CanAddr(): + val = val.Addr() + default: + return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val} + } + + m, ok := val.Interface().(Marshaler) + if !ok { + return vw.WriteNull() + } + data, err := m.MarshalBSON() + if err != nil { + return err + } + return copyValueFromBytes(vw, TypeEmbeddedDocument, data) +} + +// javaScriptEncodeValue is the ValueEncoderFunc for the JavaScript type. +func javaScriptEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tJavaScript { + return ValueEncoderError{Name: "JavaScriptEncodeValue", Types: []reflect.Type{tJavaScript}, Received: val} + } + + return vw.WriteJavascript(val.String()) +} + +// symbolEncodeValue is the ValueEncoderFunc for the Symbol type. +func symbolEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tSymbol { + return ValueEncoderError{Name: "SymbolEncodeValue", Types: []reflect.Type{tSymbol}, Received: val} + } + + return vw.WriteSymbol(val.String()) +} + +// binaryEncodeValue is the ValueEncoderFunc for Binary. +func binaryEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tBinary { + return ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val} + } + b := val.Interface().(Binary) + + return vw.WriteBinaryWithSubtype(b.Data, b.Subtype) +} + +// vectorEncodeValue is the ValueEncoderFunc for Vector. +func vectorEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + t := val.Type() + if !val.IsValid() || t != tVector { + return ValueEncoderError{Name: "VectorEncodeValue", + Types: []reflect.Type{tVector}, + Received: val, + } + } + v := val.Interface().(Vector) + b := v.Binary() + return vw.WriteBinaryWithSubtype(b.Data, b.Subtype) +} + +// undefinedEncodeValue is the ValueEncoderFunc for Undefined. +func undefinedEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tUndefined { + return ValueEncoderError{Name: "UndefinedEncodeValue", Types: []reflect.Type{tUndefined}, Received: val} + } + + return vw.WriteUndefined() +} + +// dateTimeEncodeValue is the ValueEncoderFunc for DateTime. +func dateTimeEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tDateTime { + return ValueEncoderError{Name: "DateTimeEncodeValue", Types: []reflect.Type{tDateTime}, Received: val} + } + + return vw.WriteDateTime(val.Int()) +} + +// nullEncodeValue is the ValueEncoderFunc for Null. +func nullEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tNull { + return ValueEncoderError{Name: "NullEncodeValue", Types: []reflect.Type{tNull}, Received: val} + } + + return vw.WriteNull() +} + +// regexEncodeValue is the ValueEncoderFunc for Regex. +func regexEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tRegex { + return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val} + } + + regex := val.Interface().(Regex) + + return vw.WriteRegex(regex.Pattern, regex.Options) +} + +// dbPointerEncodeValue is the ValueEncoderFunc for DBPointer. +func dbPointerEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tDBPointer { + return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val} + } + + dbp := val.Interface().(DBPointer) + + return vw.WriteDBPointer(dbp.DB, dbp.Pointer) +} + +// timestampEncodeValue is the ValueEncoderFunc for Timestamp. +func timestampEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tTimestamp { + return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val} + } + + ts := val.Interface().(Timestamp) + + return vw.WriteTimestamp(ts.T, ts.I) +} + +// minKeyEncodeValue is the ValueEncoderFunc for MinKey. +func minKeyEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tMinKey { + return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: val} + } + + return vw.WriteMinKey() +} + +// maxKeyEncodeValue is the ValueEncoderFunc for MaxKey. +func maxKeyEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tMaxKey { + return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: val} + } + + return vw.WriteMaxKey() +} + +// coreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document. +func coreDocumentEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tCoreDocument { + return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: val} + } + + cdoc := val.Interface().(bsoncore.Document) + + return copyDocumentFromBytes(vw, cdoc) +} + +// codeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope. +func codeWithScopeEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tCodeWithScope { + return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val} + } + + cws := val.Interface().(CodeWithScope) + + dw, err := vw.WriteCodeWithScope(string(cws.Code)) + if err != nil { + return err + } + + sw := sliceWriterPool.Get().(*sliceWriter) + defer sliceWriterPool.Put(sw) + *sw = (*sw)[:0] + + scopeVW := bvwPool.Get().(*valueWriter) + scopeVW.reset(scopeVW.buf[:0]) + scopeVW.w = sw + defer bvwPool.Put(scopeVW) + + encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope)) + if err != nil { + return err + } + + err = encoder.EncodeValue(ec, scopeVW, reflect.ValueOf(cws.Scope)) + if err != nil { + return err + } + + err = copyBytesToDocumentWriter(dw, *sw) + if err != nil { + return err + } + return dw.WriteDocumentEnd() +} + +// isImplementationNil returns if val is a nil pointer and inter is implemented on a concrete type +func isImplementationNil(val reflect.Value, inter reflect.Type) bool { + vt := val.Type() + for vt.Kind() == reflect.Ptr { + vt = vt.Elem() + } + return vt.Implements(inter) && val.Kind() == reflect.Ptr && val.IsNil() +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/doc.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/doc.go new file mode 100644 index 000000000..b346f71f0 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/doc.go @@ -0,0 +1,141 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +// Package bson is a library for reading, writing, and manipulating BSON. BSON is a binary serialization +// format used to store documents and make remote procedure calls in MongoDB. For more information about +// the Go BSON library, including usage examples, check out the [Work with BSON] page in the Go Driver +// docs site. For more information about BSON, see https://bsonspec.org. +// +// # Native Go Types +// +// The [D] and [M] types defined in this package can be used to build representations of BSON using native Go types. D is a +// slice and M is a map. For more information about the use cases for these types, see the documentation on the type +// definitions. +// +// Note that a D should not be constructed with duplicate key names, as that can cause undefined server behavior. +// +// Example: +// +// bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}} +// bson.M{"foo": "bar", "hello": "world", "pi": 3.14159} +// +// When decoding BSON to a D or M, the following type mappings apply when unmarshaling: +// +// 1. BSON int32 unmarshals to an int32. +// 2. BSON int64 unmarshals to an int64. +// 3. BSON double unmarshals to a float64. +// 4. BSON string unmarshals to a string. +// 5. BSON boolean unmarshals to a bool. +// 6. BSON embedded document unmarshals to the parent type (i.e. D for a D, M for an M). +// 7. BSON array unmarshals to a bson.A. +// 8. BSON ObjectId unmarshals to a bson.ObjectID. +// 9. BSON datetime unmarshals to a bson.DateTime. +// 10. BSON binary unmarshals to a bson.Binary. +// 11. BSON regular expression unmarshals to a bson.Regex. +// 12. BSON JavaScript unmarshals to a bson.JavaScript. +// 13. BSON code with scope unmarshals to a bson.CodeWithScope. +// 14. BSON timestamp unmarshals to an bson.Timestamp. +// 15. BSON 128-bit decimal unmarshals to an bson.Decimal128. +// 16. BSON min key unmarshals to an bson.MinKey. +// 17. BSON max key unmarshals to an bson.MaxKey. +// 18. BSON undefined unmarshals to a bson.Undefined. +// 19. BSON null unmarshals to nil. +// 20. BSON DBPointer unmarshals to a bson.DBPointer. +// 21. BSON symbol unmarshals to a bson.Symbol. +// +// The above mappings also apply when marshaling a D or M to BSON. Some other useful marshaling mappings are: +// +// 1. time.Time marshals to a BSON datetime. +// 2. int8, int16, and int32 marshal to a BSON int32. +// 3. int marshals to a BSON int32 if the value is between math.MinInt32 and math.MaxInt32, inclusive, and a BSON int64 +// otherwise. +// 4. int64 marshals to BSON int64 (unless [Encoder.IntMinSize] is set). +// 5. uint8 and uint16 marshal to a BSON int32. +// 6. uint, uint32, and uint64 marshal to a BSON int64 (unless [Encoder.IntMinSize] is set). +// 7. BSON null and undefined values will unmarshal into the zero value of a field (e.g. unmarshaling a BSON null or +// undefined value into a string will yield the empty string.). +// +// # Structs +// +// Structs can be marshaled/unmarshaled to/from BSON or Extended JSON. When transforming structs to/from BSON or Extended +// JSON, the following rules apply: +// +// 1. Only exported fields in structs will be marshaled or unmarshaled. +// +// 2. When marshaling a struct, each field will be lowercased to generate the key for the corresponding BSON element. +// For example, a struct field named "Foo" will generate key "foo". This can be overridden via a struct tag (e.g. +// `bson:"fooField"` to generate key "fooField" instead). +// +// 3. An embedded struct field is marshaled as a subdocument. The key will be the lowercased name of the field's type. +// +// 4. A pointer field is marshaled as the underlying type if the pointer is non-nil. If the pointer is nil, it is +// marshaled as a BSON null value. +// +// 5. When unmarshaling, a field of type any will follow the D/M type mappings listed above. BSON documents +// unmarshaled into an any field will be unmarshaled as a D. +// +// The encoding of each struct field can be customized by the "bson" struct tag. The "bson" tag gives the name of the +// field, followed by a comma-separated list of options. The name may be omitted in order to specify options without +// overriding the default field name. The following options can be used to configure behavior: +// +// 1. omitempty: If the "omitempty" struct tag is specified on a field, the field will not be marshaled if it is set to +// an "empty" value. Numbers, booleans, and strings are considered empty if their value is equal to the zero value for +// the type (i.e. 0 for numbers, false for booleans, and "" for strings). Slices, maps, and arrays are considered +// empty if they are of length zero. Interfaces and pointers are considered empty if their value is nil. By default, +// structs are only considered empty if the struct type implements [Zeroer] and the "IsZero" +// method returns true. Struct types that do not implement [Zeroer] are never considered empty and will be +// marshaled as embedded documents. NOTE: It is recommended that this tag be used for all slice and map fields. +// +// 2. minsize: If the minsize struct tag is specified on a field of type int64, uint, uint32, or uint64 and the value of +// the field can fit in a signed int32, the field will be serialized as a BSON int32 rather than a BSON int64. For +// other types, this tag is ignored. +// +// 3. truncate: If the truncate struct tag is specified on a field with a non-float numeric type, BSON doubles +// unmarshaled into that field will be truncated at the decimal point. For example, if 3.14 is unmarshaled into a +// field of type int, it will be unmarshaled as 3. If this tag is not specified, the decoder will throw an error if +// the value cannot be decoded without losing precision. For float64 or non-numeric types, this tag is ignored. +// +// 4. inline: If the inline struct tag is specified for a struct or map field, the field will be "flattened" when +// marshaling and "un-flattened" when unmarshaling. This means that all of the fields in that struct/map will be +// pulled up one level and will become top-level fields rather than being fields in a nested document. For example, +// if a map field named "Map" with value map[string]any{"foo": "bar"} is inlined, the resulting document will +// be {"foo": "bar"} instead of {"map": {"foo": "bar"}}. There can only be one inlined map field in a struct. If +// there are duplicated fields in the resulting document when an inlined struct is marshaled, the inlined field will +// be overwritten. If there are duplicated fields in the resulting document when an inlined map is marshaled, an +// error will be returned. This tag can be used with fields that are pointers to structs. If an inlined pointer field +// is nil, it will not be marshaled. For fields that are not maps or structs, this tag is ignored. +// +// # Raw BSON +// +// The Raw family of types is used to validate and retrieve elements from a slice of bytes. This +// type is most useful when you want do lookups on BSON bytes without unmarshaling it into another +// type. +// +// Example: +// +// var raw bson.Raw = ... // bytes from somewhere +// err := raw.Validate() +// if err != nil { return err } +// val := raw.Lookup("foo") +// i32, ok := val.Int32OK() +// // do something with i32... +// +// # Custom Registry +// +// The Go BSON library uses a [Registry] to define encoding and decoding behavior for different data types. +// The default encoding and decoding behavior can be customized or extended by using a modified Registry. +// The custom registry system is composed of two parts: +// +// 1) [ValueEncoder] and [ValueDecoder] that handle encoding and decoding Go values to and from BSON +// representations. +// +// 2) A [Registry] that holds these ValueEncoders and ValueDecoders and provides methods for +// retrieving them. +// +// To use a custom Registry, use [Encoder.SetRegistry] or [Decoder.SetRegistry]. +// +// [Work with BSON]: https://www.mongodb.com/docs/drivers/go/current/fundamentals/bson/ +package bson diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/empty_interface_codec.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/empty_interface_codec.go new file mode 100644 index 000000000..ae1db53f9 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/empty_interface_codec.go @@ -0,0 +1,127 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "reflect" +) + +// emptyInterfaceCodec is the Codec used for any values. +type emptyInterfaceCodec struct { + // decodeBinaryAsSlice causes DecodeValue to unmarshal BSON binary field values that are the + // "Generic" or "Old" BSON binary subtype as a Go byte slice instead of a Binary. + decodeBinaryAsSlice bool +} + +// Assert that emptyInterfaceCodec satisfies the typeDecoder interface, which allows it +// to be used by collection type decoders (e.g. map, slice, etc) to set individual values in a +// collection. +var _ typeDecoder = &emptyInterfaceCodec{} + +// EncodeValue is the ValueEncoderFunc for any. +func (eic *emptyInterfaceCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error { + if !val.IsValid() || val.Type() != tEmpty { + return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val} + } + + if val.IsNil() { + return vw.WriteNull() + } + encoder, err := ec.LookupEncoder(val.Elem().Type()) + if err != nil { + return err + } + + return encoder.EncodeValue(ec, vw, val.Elem()) +} + +func (eic *emptyInterfaceCodec) getEmptyInterfaceDecodeType(dc DecodeContext, valueType Type) (reflect.Type, error) { + isDocument := valueType == Type(0) || valueType == TypeEmbeddedDocument + if isDocument { + if dc.defaultDocumentType != nil { + // If the bsontype is an embedded document and the DocumentType is set on the DecodeContext, then return + // that type. + return dc.defaultDocumentType, nil + } + } + + rtype, err := dc.LookupTypeMapEntry(valueType) + if err == nil { + return rtype, nil + } + + if isDocument { + // For documents, fallback to looking up a type map entry for Type(0) or TypeEmbeddedDocument, + // depending on the original valueType. + var lookupType Type + switch valueType { + case Type(0): + lookupType = TypeEmbeddedDocument + case TypeEmbeddedDocument: + lookupType = Type(0) + } + + rtype, err = dc.LookupTypeMapEntry(lookupType) + if err == nil { + return rtype, nil + } + // fallback to bson.D + return tD, nil + } + + return nil, err +} + +func (eic *emptyInterfaceCodec) decodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) { + if t != tEmpty { + return emptyValue, ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: reflect.Zero(t)} + } + + rtype, err := eic.getEmptyInterfaceDecodeType(dc, vr.Type()) + if err != nil { + switch vr.Type() { + case TypeNull: + return reflect.Zero(t), vr.ReadNull() + default: + return emptyValue, err + } + } + + decoder, err := dc.LookupDecoder(rtype) + if err != nil { + return emptyValue, err + } + + elem, err := decodeTypeOrValueWithInfo(decoder, dc, vr, rtype) + if err != nil { + return emptyValue, err + } + + if (eic.decodeBinaryAsSlice || dc.binaryAsSlice) && rtype == tBinary { + binElem := elem.Interface().(Binary) + if binElem.Subtype == TypeBinaryGeneric || binElem.Subtype == TypeBinaryBinaryOld { + elem = reflect.ValueOf(binElem.Data) + } + } + + return elem, nil +} + +// DecodeValue is the ValueDecoderFunc for any. +func (eic *emptyInterfaceCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error { + if !val.CanSet() || val.Type() != tEmpty { + return ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: val} + } + + elem, err := eic.decodeType(dc, vr, val.Type()) + if err != nil { + return err + } + + val.Set(elem) + return nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/encoder.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/encoder.go new file mode 100644 index 000000000..d27bb7b59 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/encoder.go @@ -0,0 +1,130 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "reflect" + "sync" +) + +// This pool is used to keep the allocations of Encoders down. This is only used for the Marshal* +// methods and is not consumable from outside of this package. The Encoders retrieved from this pool +// must have both Reset and SetRegistry called on them. +var encPool = sync.Pool{ + New: func() any { + return new(Encoder) + }, +} + +// An Encoder writes a serialization format to an output stream. It writes to a ValueWriter +// as the destination of BSON data. +type Encoder struct { + ec EncodeContext + vw ValueWriter +} + +// NewEncoder returns a new encoder that writes to vw. +func NewEncoder(vw ValueWriter) *Encoder { + return &Encoder{ + ec: EncodeContext{Registry: defaultRegistry}, + vw: vw, + } +} + +// Encode writes the BSON encoding of val to the stream. +// +// See [Marshal] for details about BSON marshaling behavior. +func (e *Encoder) Encode(val any) error { + if marshaler, ok := val.(Marshaler); ok { + // TODO(skriptble): Should we have a MarshalAppender interface so that we can have []byte reuse? + buf, err := marshaler.MarshalBSON() + if err != nil { + return err + } + return copyDocumentFromBytes(e.vw, buf) + } + + encoder, err := e.ec.LookupEncoder(reflect.TypeOf(val)) + if err != nil { + return err + } + + return encoder.EncodeValue(e.ec, e.vw, reflect.ValueOf(val)) +} + +// Reset will reset the state of the Encoder, using the same *EncodeContext used in +// the original construction but using vw. +func (e *Encoder) Reset(vw ValueWriter) { + e.vw = vw +} + +// SetRegistry replaces the current registry of the Encoder with r. +func (e *Encoder) SetRegistry(r *Registry) { + e.ec.Registry = r +} + +// ErrorOnInlineDuplicates causes the Encoder to return an error if there is a duplicate field in +// the marshaled BSON when the "inline" struct tag option is set. +func (e *Encoder) ErrorOnInlineDuplicates() { + e.ec.errorOnInlineDuplicates = true +} + +// IntMinSize causes the Encoder to marshal Go integer values (int, int8, int16, int32, int64, uint, +// uint8, uint16, uint32, or uint64) as the minimum BSON int size (either 32 or 64 bits) that can +// represent the integer value. +func (e *Encoder) IntMinSize() { + e.ec.minSize = true +} + +// StringifyMapKeysWithFmt causes the Encoder to convert Go map keys to BSON document field name +// strings using fmt.Sprint instead of the default string conversion logic. +func (e *Encoder) StringifyMapKeysWithFmt() { + e.ec.stringifyMapKeysWithFmt = true +} + +// NilMapAsEmpty causes the Encoder to marshal nil Go maps as empty BSON documents instead of BSON +// null. +func (e *Encoder) NilMapAsEmpty() { + e.ec.nilMapAsEmpty = true +} + +// NilSliceAsEmpty causes the Encoder to marshal nil Go slices as empty BSON arrays instead of BSON +// null. +func (e *Encoder) NilSliceAsEmpty() { + e.ec.nilSliceAsEmpty = true +} + +// NilByteSliceAsEmpty causes the Encoder to marshal nil Go byte slices as empty BSON binary values +// instead of BSON null. +func (e *Encoder) NilByteSliceAsEmpty() { + e.ec.nilByteSliceAsEmpty = true +} + +// TODO(GODRIVER-2820): Update the description to remove the note about only examining exported +// TODO struct fields once the logic is updated to also inspect private struct fields. + +// OmitZeroStruct causes the Encoder to consider the zero value for a struct (e.g. MyStruct{}) +// as empty and omit it from the marshaled BSON when the "omitempty" struct tag option is set +// or the OmitEmpty() method is called. +// +// Note that the Encoder only examines exported struct fields when determining if a struct is the +// zero value. It considers pointers to a zero struct value (e.g. &MyStruct{}) not empty. +func (e *Encoder) OmitZeroStruct() { + e.ec.omitZeroStruct = true +} + +// OmitEmpty causes the Encoder to omit empty values from the marshaled BSON as the "omitempty" +// struct tag option is set. +func (e *Encoder) OmitEmpty() { + e.ec.omitEmpty = true +} + +// UseJSONStructTags causes the Encoder to fall back to using the "json" struct tag if a "bson" +// struct tag is not specified. +func (e *Encoder) UseJSONStructTags() { + e.ec.useJSONStructTags = true +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_parser.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_parser.go new file mode 100644 index 000000000..eb536a675 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_parser.go @@ -0,0 +1,804 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "encoding/base64" + "encoding/hex" + "errors" + "fmt" + "io" + "strings" +) + +const maxNestingDepth = 200 + +// ErrInvalidJSON indicates the JSON input is invalid +var ErrInvalidJSON = errors.New("invalid JSON input") + +type jsonParseState byte + +const ( + jpsStartState jsonParseState = iota + jpsSawBeginObject + jpsSawEndObject + jpsSawBeginArray + jpsSawEndArray + jpsSawColon + jpsSawComma + jpsSawKey + jpsSawValue + jpsDoneState + jpsInvalidState +) + +type jsonParseMode byte + +const ( + jpmInvalidMode jsonParseMode = iota + jpmObjectMode + jpmArrayMode +) + +type extJSONValue struct { + t Type + v any +} + +type extJSONObject struct { + keys []string + values []*extJSONValue +} + +type extJSONParser struct { + js *jsonScanner + s jsonParseState + m []jsonParseMode + k string + v *extJSONValue + + err error + canonicalOnly bool + depth int + maxDepth int + + emptyObject bool + relaxedUUID bool +} + +// newExtJSONParser returns a new extended JSON parser, ready to to begin +// parsing from the first character of the argued json input. It will not +// perform any read-ahead and will therefore not report any errors about +// malformed JSON at this point. +func newExtJSONParser(r io.Reader, canonicalOnly bool) *extJSONParser { + return &extJSONParser{ + js: &jsonScanner{r: r}, + s: jpsStartState, + m: []jsonParseMode{}, + canonicalOnly: canonicalOnly, + maxDepth: maxNestingDepth, + } +} + +// peekType examines the next value and returns its BSON Type +func (ejp *extJSONParser) peekType() (Type, error) { + var t Type + var err error + initialState := ejp.s + + ejp.advanceState() + switch ejp.s { + case jpsSawValue: + t = ejp.v.t + case jpsSawBeginArray: + t = TypeArray + case jpsInvalidState: + err = ejp.err + case jpsSawComma: + // in array mode, seeing a comma means we need to progress again to actually observe a type + if ejp.peekMode() == jpmArrayMode { + return ejp.peekType() + } + case jpsSawEndArray: + // this would only be a valid state if we were in array mode, so return end-of-array error + err = ErrEOA + case jpsSawBeginObject: + // peek key to determine type + ejp.advanceState() + switch ejp.s { + case jpsSawEndObject: // empty embedded document + t = TypeEmbeddedDocument + ejp.emptyObject = true + case jpsInvalidState: + err = ejp.err + case jpsSawKey: + if initialState == jpsStartState { + return TypeEmbeddedDocument, nil + } + t = wrapperKeyBSONType(ejp.k) + + // if $uuid is encountered, parse as binary subtype 4 + if ejp.k == "$uuid" { + ejp.relaxedUUID = true + t = TypeBinary + } + + switch t { + case TypeJavaScript: + // just saw $code, need to check for $scope at same level + _, err = ejp.readValue(TypeJavaScript) + if err != nil { + break + } + + switch ejp.s { + case jpsSawEndObject: // type is TypeJavaScript + case jpsSawComma: + ejp.advanceState() + + if ejp.s == jpsSawKey && ejp.k == "$scope" { + t = TypeCodeWithScope + } else { + err = fmt.Errorf("invalid extended JSON: unexpected key %s in CodeWithScope object", ejp.k) + } + case jpsInvalidState: + err = ejp.err + default: + err = ErrInvalidJSON + } + case TypeCodeWithScope: + err = errors.New("invalid extended JSON: code with $scope must contain $code before $scope") + } + } + } + + return t, err +} + +// readKey parses the next key and its type and returns them +func (ejp *extJSONParser) readKey() (string, Type, error) { + if ejp.emptyObject { + ejp.emptyObject = false + return "", 0, ErrEOD + } + + // advance to key (or return with error) + switch ejp.s { + case jpsStartState: + ejp.advanceState() + if ejp.s == jpsSawBeginObject { + ejp.advanceState() + } + case jpsSawBeginObject: + ejp.advanceState() + case jpsSawValue, jpsSawEndObject, jpsSawEndArray: + ejp.advanceState() + switch ejp.s { + case jpsSawBeginObject, jpsSawComma: + ejp.advanceState() + case jpsSawEndObject: + return "", 0, ErrEOD + case jpsDoneState: + return "", 0, io.EOF + case jpsInvalidState: + return "", 0, ejp.err + default: + return "", 0, ErrInvalidJSON + } + case jpsSawKey: // do nothing (key was peeked before) + default: + return "", 0, invalidRequestError("key") + } + + // read key + var key string + + switch ejp.s { + case jpsSawKey: + key = ejp.k + case jpsSawEndObject: + return "", 0, ErrEOD + case jpsInvalidState: + return "", 0, ejp.err + default: + return "", 0, invalidRequestError("key") + } + + // check for colon + ejp.advanceState() + if err := ensureColon(ejp.s, key); err != nil { + return "", 0, err + } + + // peek at the value to determine type + t, err := ejp.peekType() + if err != nil { + return "", 0, err + } + + return key, t, nil +} + +// readValue returns the value corresponding to the Type returned by peekType +func (ejp *extJSONParser) readValue(t Type) (*extJSONValue, error) { + if ejp.s == jpsInvalidState { + return nil, ejp.err + } + + var v *extJSONValue + + switch t { + case TypeNull, TypeBoolean, TypeString: + if ejp.s != jpsSawValue { + return nil, invalidRequestError(t.String()) + } + v = ejp.v + case TypeInt32, TypeInt64, TypeDouble: + // relaxed version allows these to be literal number values + if ejp.s == jpsSawValue { + v = ejp.v + break + } + fallthrough + case TypeDecimal128, TypeSymbol, TypeObjectID, TypeMinKey, TypeMaxKey, TypeUndefined: + switch ejp.s { + case jpsSawKey: + // read colon + ejp.advanceState() + if err := ensureColon(ejp.s, ejp.k); err != nil { + return nil, err + } + + // read value + ejp.advanceState() + if ejp.s != jpsSawValue || !ejp.ensureExtValueType(t) { + return nil, invalidJSONErrorForType("value", t) + } + + v = ejp.v + + // read end object + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, invalidJSONErrorForType("} after value", t) + } + default: + return nil, invalidRequestError(t.String()) + } + case TypeBinary, TypeRegex, TypeTimestamp, TypeDBPointer: + if ejp.s != jpsSawKey { + return nil, invalidRequestError(t.String()) + } + // read colon + ejp.advanceState() + if err := ensureColon(ejp.s, ejp.k); err != nil { + return nil, err + } + + ejp.advanceState() + if t == TypeBinary && ejp.s == jpsSawValue { + // convert relaxed $uuid format + if ejp.relaxedUUID { + defer func() { ejp.relaxedUUID = false }() + uuid, err := ejp.v.parseSymbol() + if err != nil { + return nil, err + } + + // RFC 4122 defines the length of a UUID as 36 and the hyphens in a UUID as appearing + // in the 8th, 13th, 18th, and 23rd characters. + // + // See https://tools.ietf.org/html/rfc4122#section-3 + valid := len(uuid) == 36 && + string(uuid[8]) == "-" && + string(uuid[13]) == "-" && + string(uuid[18]) == "-" && + string(uuid[23]) == "-" + if !valid { + return nil, fmt.Errorf("$uuid value does not follow RFC 4122 format regarding length and hyphens") + } + + // remove hyphens + uuidNoHyphens := strings.ReplaceAll(uuid, "-", "") + if len(uuidNoHyphens) != 32 { + return nil, fmt.Errorf("$uuid value does not follow RFC 4122 format regarding length and hyphens") + } + + // convert hex to bytes + bytes, err := hex.DecodeString(uuidNoHyphens) + if err != nil { + return nil, fmt.Errorf("$uuid value does not follow RFC 4122 format regarding hex bytes: %w", err) + } + + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, invalidJSONErrorForType("$uuid and value and then }", TypeBinary) + } + + base64 := &extJSONValue{ + t: TypeString, + v: base64.StdEncoding.EncodeToString(bytes), + } + subType := &extJSONValue{ + t: TypeString, + v: "04", + } + + v = &extJSONValue{ + t: TypeEmbeddedDocument, + v: &extJSONObject{ + keys: []string{"base64", "subType"}, + values: []*extJSONValue{base64, subType}, + }, + } + + break + } + + // convert legacy $binary format + base64 := ejp.v + + ejp.advanceState() + if ejp.s != jpsSawComma { + return nil, invalidJSONErrorForType(",", TypeBinary) + } + + ejp.advanceState() + key, t, err := ejp.readKey() + if err != nil { + return nil, err + } + if key != "$type" { + return nil, invalidJSONErrorForType("$type", TypeBinary) + } + + subType, err := ejp.readValue(t) + if err != nil { + return nil, err + } + + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, invalidJSONErrorForType("2 key-value pairs and then }", TypeBinary) + } + + v = &extJSONValue{ + t: TypeEmbeddedDocument, + v: &extJSONObject{ + keys: []string{"base64", "subType"}, + values: []*extJSONValue{base64, subType}, + }, + } + break + } + + // read KV pairs + if ejp.s != jpsSawBeginObject { + return nil, invalidJSONErrorForType("{", t) + } + + keys, vals, err := ejp.readObject(2, true) + if err != nil { + return nil, err + } + + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, invalidJSONErrorForType("2 key-value pairs and then }", t) + } + + v = &extJSONValue{t: TypeEmbeddedDocument, v: &extJSONObject{keys: keys, values: vals}} + + case TypeDateTime: + switch ejp.s { + case jpsSawValue: + v = ejp.v + case jpsSawKey: + // read colon + ejp.advanceState() + if err := ensureColon(ejp.s, ejp.k); err != nil { + return nil, err + } + + ejp.advanceState() + switch ejp.s { + case jpsSawBeginObject: + keys, vals, err := ejp.readObject(1, true) + if err != nil { + return nil, err + } + v = &extJSONValue{t: TypeEmbeddedDocument, v: &extJSONObject{keys: keys, values: vals}} + case jpsSawValue: + if ejp.canonicalOnly { + return nil, invalidJSONError("{") + } + v = ejp.v + default: + if ejp.canonicalOnly { + return nil, invalidJSONErrorForType("object", t) + } + return nil, invalidJSONErrorForType("ISO-8601 Internet Date/Time Format as described in RFC-3339", t) + } + + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, invalidJSONErrorForType("value and then }", t) + } + default: + return nil, invalidRequestError(t.String()) + } + case TypeJavaScript: + switch ejp.s { + case jpsSawKey: + // read colon + ejp.advanceState() + if err := ensureColon(ejp.s, ejp.k); err != nil { + return nil, err + } + + // read value + ejp.advanceState() + if ejp.s != jpsSawValue { + return nil, invalidJSONErrorForType("value", t) + } + v = ejp.v + + // read end object or comma and just return + ejp.advanceState() + case jpsSawEndObject: + v = ejp.v + default: + return nil, invalidRequestError(t.String()) + } + case TypeCodeWithScope: + if ejp.s == jpsSawKey && ejp.k == "$scope" { + v = ejp.v // this is the $code string from earlier + + // read colon + ejp.advanceState() + if err := ensureColon(ejp.s, ejp.k); err != nil { + return nil, err + } + + // read { + ejp.advanceState() + if ejp.s != jpsSawBeginObject { + return nil, invalidJSONError("$scope to be embedded document") + } + } else { + return nil, invalidRequestError(t.String()) + } + case TypeEmbeddedDocument, TypeArray: + return nil, invalidRequestError(t.String()) + } + + return v, nil +} + +// readObject is a utility method for reading full objects of known (or expected) size +// it is useful for extended JSON types such as binary, datetime, regex, and timestamp +func (ejp *extJSONParser) readObject(numKeys int, started bool) ([]string, []*extJSONValue, error) { + keys := make([]string, numKeys) + vals := make([]*extJSONValue, numKeys) + + if !started { + ejp.advanceState() + if ejp.s != jpsSawBeginObject { + return nil, nil, invalidJSONError("{") + } + } + + for i := 0; i < numKeys; i++ { + key, t, err := ejp.readKey() + if err != nil { + return nil, nil, err + } + + switch ejp.s { + case jpsSawKey: + v, err := ejp.readValue(t) + if err != nil { + return nil, nil, err + } + + keys[i] = key + vals[i] = v + case jpsSawValue: + keys[i] = key + vals[i] = ejp.v + default: + return nil, nil, invalidJSONError("value") + } + } + + ejp.advanceState() + if ejp.s != jpsSawEndObject { + return nil, nil, invalidJSONError("}") + } + + return keys, vals, nil +} + +// advanceState reads the next JSON token from the scanner and transitions +// from the current state based on that token's type +func (ejp *extJSONParser) advanceState() { + if ejp.s == jpsDoneState || ejp.s == jpsInvalidState { + return + } + + jt, err := ejp.js.nextToken() + + if err != nil { + ejp.err = err + ejp.s = jpsInvalidState + return + } + + valid := ejp.validateToken(jt.t) + if !valid { + ejp.err = unexpectedTokenError(jt) + ejp.s = jpsInvalidState + return + } + + switch jt.t { + case jttBeginObject: + ejp.s = jpsSawBeginObject + ejp.pushMode(jpmObjectMode) + ejp.depth++ + + if ejp.depth > ejp.maxDepth { + ejp.err = nestingDepthError(jt.p, ejp.depth) + ejp.s = jpsInvalidState + } + case jttEndObject: + ejp.s = jpsSawEndObject + ejp.depth-- + + if ejp.popMode() != jpmObjectMode { + ejp.err = unexpectedTokenError(jt) + ejp.s = jpsInvalidState + } + case jttBeginArray: + ejp.s = jpsSawBeginArray + ejp.pushMode(jpmArrayMode) + case jttEndArray: + ejp.s = jpsSawEndArray + + if ejp.popMode() != jpmArrayMode { + ejp.err = unexpectedTokenError(jt) + ejp.s = jpsInvalidState + } + case jttColon: + ejp.s = jpsSawColon + case jttComma: + ejp.s = jpsSawComma + case jttEOF: + ejp.s = jpsDoneState + if len(ejp.m) != 0 { + ejp.err = unexpectedTokenError(jt) + ejp.s = jpsInvalidState + } + case jttString: + switch ejp.s { + case jpsSawComma: + if ejp.peekMode() == jpmArrayMode { + ejp.s = jpsSawValue + ejp.v = extendJSONToken(jt) + return + } + fallthrough + case jpsSawBeginObject: + ejp.s = jpsSawKey + ejp.k = jt.v.(string) + return + } + fallthrough + default: + ejp.s = jpsSawValue + ejp.v = extendJSONToken(jt) + } +} + +var jpsValidTransitionTokens = map[jsonParseState]map[jsonTokenType]bool{ + jpsStartState: { + jttBeginObject: true, + jttBeginArray: true, + jttInt32: true, + jttInt64: true, + jttDouble: true, + jttString: true, + jttBool: true, + jttNull: true, + jttEOF: true, + }, + jpsSawBeginObject: { + jttEndObject: true, + jttString: true, + }, + jpsSawEndObject: { + jttEndObject: true, + jttEndArray: true, + jttComma: true, + jttEOF: true, + }, + jpsSawBeginArray: { + jttBeginObject: true, + jttBeginArray: true, + jttEndArray: true, + jttInt32: true, + jttInt64: true, + jttDouble: true, + jttString: true, + jttBool: true, + jttNull: true, + }, + jpsSawEndArray: { + jttEndObject: true, + jttEndArray: true, + jttComma: true, + jttEOF: true, + }, + jpsSawColon: { + jttBeginObject: true, + jttBeginArray: true, + jttInt32: true, + jttInt64: true, + jttDouble: true, + jttString: true, + jttBool: true, + jttNull: true, + }, + jpsSawComma: { + jttBeginObject: true, + jttBeginArray: true, + jttInt32: true, + jttInt64: true, + jttDouble: true, + jttString: true, + jttBool: true, + jttNull: true, + }, + jpsSawKey: { + jttColon: true, + }, + jpsSawValue: { + jttEndObject: true, + jttEndArray: true, + jttComma: true, + jttEOF: true, + }, + jpsDoneState: {}, + jpsInvalidState: {}, +} + +func (ejp *extJSONParser) validateToken(jtt jsonTokenType) bool { + switch ejp.s { + case jpsSawEndObject: + // if we are at depth zero and the next token is a '{', + // we can consider it valid only if we are not in array mode. + if jtt == jttBeginObject && ejp.depth == 0 { + return ejp.peekMode() != jpmArrayMode + } + case jpsSawComma: + switch ejp.peekMode() { + // the only valid next token after a comma inside a document is a string (a key) + case jpmObjectMode: + return jtt == jttString + case jpmInvalidMode: + return false + } + } + + _, ok := jpsValidTransitionTokens[ejp.s][jtt] + return ok +} + +// ensureExtValueType returns true if the current value has the expected +// value type for single-key extended JSON types. For example, +// {"$numberInt": v} v must be TypeString +func (ejp *extJSONParser) ensureExtValueType(t Type) bool { + switch t { + case TypeMinKey, TypeMaxKey: + return ejp.v.t == TypeInt32 + case TypeUndefined: + return ejp.v.t == TypeBoolean + case TypeInt32, TypeInt64, TypeDouble, TypeDecimal128, TypeSymbol, TypeObjectID: + return ejp.v.t == TypeString + default: + return false + } +} + +func (ejp *extJSONParser) pushMode(m jsonParseMode) { + ejp.m = append(ejp.m, m) +} + +func (ejp *extJSONParser) popMode() jsonParseMode { + l := len(ejp.m) + if l == 0 { + return jpmInvalidMode + } + + m := ejp.m[l-1] + ejp.m = ejp.m[:l-1] + + return m +} + +func (ejp *extJSONParser) peekMode() jsonParseMode { + l := len(ejp.m) + if l == 0 { + return jpmInvalidMode + } + + return ejp.m[l-1] +} + +func extendJSONToken(jt *jsonToken) *extJSONValue { + var t Type + + switch jt.t { + case jttInt32: + t = TypeInt32 + case jttInt64: + t = TypeInt64 + case jttDouble: + t = TypeDouble + case jttString: + t = TypeString + case jttBool: + t = TypeBoolean + case jttNull: + t = TypeNull + default: + return nil + } + + return &extJSONValue{t: t, v: jt.v} +} + +func ensureColon(s jsonParseState, key string) error { + if s != jpsSawColon { + return fmt.Errorf("invalid JSON input: missing colon after key \"%s\"", key) + } + + return nil +} + +func invalidRequestError(s string) error { + return fmt.Errorf("invalid request to read %s", s) +} + +func invalidJSONError(expected string) error { + return fmt.Errorf("invalid JSON input; expected %s", expected) +} + +func invalidJSONErrorForType(expected string, t Type) error { + return fmt.Errorf("invalid JSON input; expected %s for %s", expected, t) +} + +func unexpectedTokenError(jt *jsonToken) error { + switch jt.t { + case jttInt32, jttInt64, jttDouble: + return fmt.Errorf("invalid JSON input; unexpected number (%v) at position %d", jt.v, jt.p) + case jttString: + return fmt.Errorf("invalid JSON input; unexpected string (\"%v\") at position %d", jt.v, jt.p) + case jttBool: + return fmt.Errorf("invalid JSON input; unexpected boolean literal (%v) at position %d", jt.v, jt.p) + case jttNull: + return fmt.Errorf("invalid JSON input; unexpected null literal at position %d", jt.p) + case jttEOF: + return fmt.Errorf("invalid JSON input; unexpected end of input at position %d", jt.p) + default: + return fmt.Errorf("invalid JSON input; unexpected %c at position %d", jt.v.(byte), jt.p) + } +} + +func nestingDepthError(p, depth int) error { + return fmt.Errorf("invalid JSON input; nesting too deep (%d levels) at position %d", depth, p) +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_reader.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_reader.go new file mode 100644 index 000000000..4bee3efc2 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_reader.go @@ -0,0 +1,606 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +package bson + +import ( + "errors" + "fmt" + "io" +) + +type ejvrState struct { + mode mode + vType Type + depth int +} + +// extJSONValueReader is for reading extended JSON. +type extJSONValueReader struct { + p *extJSONParser + + stack []ejvrState + frame int +} + +// NewExtJSONValueReader returns a ValueReader that reads Extended JSON values +// from r. If canonicalOnly is true, reading values from the ValueReader returns +// an error if the Extended JSON was not marshaled in canonical mode. +func NewExtJSONValueReader(r io.Reader, canonicalOnly bool) (ValueReader, error) { + return newExtJSONValueReader(r, canonicalOnly) +} + +func newExtJSONValueReader(r io.Reader, canonicalOnly bool) (*extJSONValueReader, error) { + ejvr := new(extJSONValueReader) + return ejvr.reset(r, canonicalOnly) +} + +func (ejvr *extJSONValueReader) reset(r io.Reader, canonicalOnly bool) (*extJSONValueReader, error) { + p := newExtJSONParser(r, canonicalOnly) + typ, err := p.peekType() + + if err != nil { + return nil, ErrInvalidJSON + } + + var m mode + switch typ { + case TypeEmbeddedDocument: + m = mTopLevel + case TypeArray: + m = mArray + default: + m = mValue + } + + stack := make([]ejvrState, 1, 5) + stack[0] = ejvrState{ + mode: m, + vType: typ, + } + return &extJSONValueReader{ + p: p, + stack: stack, + }, nil +} + +func (ejvr *extJSONValueReader) advanceFrame() { + if ejvr.frame+1 >= len(ejvr.stack) { // We need to grow the stack + length := len(ejvr.stack) + if length+1 >= cap(ejvr.stack) { + // double it + buf := make([]ejvrState, 2*cap(ejvr.stack)+1) + copy(buf, ejvr.stack) + ejvr.stack = buf + } + ejvr.stack = ejvr.stack[:length+1] + } + ejvr.frame++ + + // Clean the stack + ejvr.stack[ejvr.frame].mode = 0 + ejvr.stack[ejvr.frame].vType = 0 + ejvr.stack[ejvr.frame].depth = 0 +} + +func (ejvr *extJSONValueReader) pushDocument() { + ejvr.advanceFrame() + + ejvr.stack[ejvr.frame].mode = mDocument + ejvr.stack[ejvr.frame].depth = ejvr.p.depth +} + +func (ejvr *extJSONValueReader) pushCodeWithScope() { + ejvr.advanceFrame() + + ejvr.stack[ejvr.frame].mode = mCodeWithScope +} + +func (ejvr *extJSONValueReader) pushArray() { + ejvr.advanceFrame() + + ejvr.stack[ejvr.frame].mode = mArray +} + +func (ejvr *extJSONValueReader) push(m mode, t Type) { + ejvr.advanceFrame() + + ejvr.stack[ejvr.frame].mode = m + ejvr.stack[ejvr.frame].vType = t +} + +func (ejvr *extJSONValueReader) pop() { + switch ejvr.stack[ejvr.frame].mode { + case mElement, mValue: + ejvr.frame-- + case mDocument, mArray, mCodeWithScope: + ejvr.frame -= 2 // we pop twice to jump over the vrElement: vrDocument -> vrElement -> vrDocument/TopLevel/etc... + } +} + +func (ejvr *extJSONValueReader) skipObject() { + // read entire object until depth returns to 0 (last ending } or ] seen) + depth := 1 + for depth > 0 { + ejvr.p.advanceState() + + // If object is empty, raise depth and continue. When emptyObject is true, the + // parser has already read both the opening and closing brackets of an empty + // object ("{}"), so the next valid token will be part of the parent document, + // not part of the nested document. + // + // If there is a comma, there are remaining fields, emptyObject must be set back + // to false, and comma must be skipped with advanceState(). + if ejvr.p.emptyObject { + if ejvr.p.s == jpsSawComma { + ejvr.p.emptyObject = false + ejvr.p.advanceState() + } + depth-- + continue + } + + switch ejvr.p.s { + case jpsSawBeginObject, jpsSawBeginArray: + depth++ + case jpsSawEndObject, jpsSawEndArray: + depth-- + } + } +} + +func (ejvr *extJSONValueReader) invalidTransitionErr(destination mode, name string, modes []mode) error { + te := TransitionError{ + name: name, + current: ejvr.stack[ejvr.frame].mode, + destination: destination, + modes: modes, + action: "read", + } + if ejvr.frame != 0 { + te.parent = ejvr.stack[ejvr.frame-1].mode + } + return te +} + +func (ejvr *extJSONValueReader) typeError(t Type) error { + return fmt.Errorf("positioned on %s, but attempted to read %s", ejvr.stack[ejvr.frame].vType, t) +} + +func (ejvr *extJSONValueReader) ensureElementValue(t Type, destination mode, callerName string, addModes ...mode) error { + switch ejvr.stack[ejvr.frame].mode { + case mElement, mValue: + if ejvr.stack[ejvr.frame].vType != t { + return ejvr.typeError(t) + } + default: + modes := []mode{mElement, mValue} + if addModes != nil { + modes = append(modes, addModes...) + } + return ejvr.invalidTransitionErr(destination, callerName, modes) + } + + return nil +} + +func (ejvr *extJSONValueReader) Type() Type { + return ejvr.stack[ejvr.frame].vType +} + +func (ejvr *extJSONValueReader) Skip() error { + switch ejvr.stack[ejvr.frame].mode { + case mElement, mValue: + default: + return ejvr.invalidTransitionErr(0, "Skip", []mode{mElement, mValue}) + } + + defer ejvr.pop() + + t := ejvr.stack[ejvr.frame].vType + switch t { + case TypeArray, TypeEmbeddedDocument, TypeCodeWithScope: + // read entire array, doc or CodeWithScope + ejvr.skipObject() + default: + _, err := ejvr.p.readValue(t) + if err != nil { + return err + } + } + + return nil +} + +func (ejvr *extJSONValueReader) ReadArray() (ArrayReader, error) { + switch ejvr.stack[ejvr.frame].mode { + case mTopLevel: // allow reading array from top level + case mArray: + return ejvr, nil + default: + if err := ejvr.ensureElementValue(TypeArray, mArray, "ReadArray", mTopLevel, mArray); err != nil { + return nil, err + } + } + + ejvr.pushArray() + + return ejvr, nil +} + +func (ejvr *extJSONValueReader) ReadBinary() (b []byte, btype byte, err error) { + if err := ejvr.ensureElementValue(TypeBinary, 0, "ReadBinary"); err != nil { + return nil, 0, err + } + + v, err := ejvr.p.readValue(TypeBinary) + if err != nil { + return nil, 0, err + } + + b, btype, err = v.parseBinary() + + ejvr.pop() + return b, btype, err +} + +func (ejvr *extJSONValueReader) ReadBoolean() (bool, error) { + if err := ejvr.ensureElementValue(TypeBoolean, 0, "ReadBoolean"); err != nil { + return false, err + } + + v, err := ejvr.p.readValue(TypeBoolean) + if err != nil { + return false, err + } + + if v.t != TypeBoolean { + return false, fmt.Errorf("expected type bool, but got type %s", v.t) + } + + ejvr.pop() + return v.v.(bool), nil +} + +func (ejvr *extJSONValueReader) ReadDocument() (DocumentReader, error) { + switch ejvr.stack[ejvr.frame].mode { + case mTopLevel: + return ejvr, nil + case mElement, mValue: + if ejvr.stack[ejvr.frame].vType != TypeEmbeddedDocument { + return nil, ejvr.typeError(TypeEmbeddedDocument) + } + + ejvr.pushDocument() + return ejvr, nil + default: + return nil, ejvr.invalidTransitionErr(mDocument, "ReadDocument", []mode{mTopLevel, mElement, mValue}) + } +} + +func (ejvr *extJSONValueReader) ReadCodeWithScope() (code string, dr DocumentReader, err error) { + if err = ejvr.ensureElementValue(TypeCodeWithScope, 0, "ReadCodeWithScope"); err != nil { + return "", nil, err + } + + v, err := ejvr.p.readValue(TypeCodeWithScope) + if err != nil { + return "", nil, err + } + + code, err = v.parseJavascript() + + ejvr.pushCodeWithScope() + return code, ejvr, err +} + +func (ejvr *extJSONValueReader) ReadDBPointer() (ns string, oid ObjectID, err error) { + if err = ejvr.ensureElementValue(TypeDBPointer, 0, "ReadDBPointer"); err != nil { + return "", NilObjectID, err + } + + v, err := ejvr.p.readValue(TypeDBPointer) + if err != nil { + return "", NilObjectID, err + } + + ns, oid, err = v.parseDBPointer() + + ejvr.pop() + return ns, oid, err +} + +func (ejvr *extJSONValueReader) ReadDateTime() (int64, error) { + if err := ejvr.ensureElementValue(TypeDateTime, 0, "ReadDateTime"); err != nil { + return 0, err + } + + v, err := ejvr.p.readValue(TypeDateTime) + if err != nil { + return 0, err + } + + d, err := v.parseDateTime() + + ejvr.pop() + return d, err +} + +func (ejvr *extJSONValueReader) ReadDecimal128() (Decimal128, error) { + if err := ejvr.ensureElementValue(TypeDecimal128, 0, "ReadDecimal128"); err != nil { + return Decimal128{}, err + } + + v, err := ejvr.p.readValue(TypeDecimal128) + if err != nil { + return Decimal128{}, err + } + + d, err := v.parseDecimal128() + + ejvr.pop() + return d, err +} + +func (ejvr *extJSONValueReader) ReadDouble() (float64, error) { + if err := ejvr.ensureElementValue(TypeDouble, 0, "ReadDouble"); err != nil { + return 0, err + } + + v, err := ejvr.p.readValue(TypeDouble) + if err != nil { + return 0, err + } + + d, err := v.parseDouble() + + ejvr.pop() + return d, err +} + +func (ejvr *extJSONValueReader) ReadInt32() (int32, error) { + if err := ejvr.ensureElementValue(TypeInt32, 0, "ReadInt32"); err != nil { + return 0, err + } + + v, err := ejvr.p.readValue(TypeInt32) + if err != nil { + return 0, err + } + + i, err := v.parseInt32() + + ejvr.pop() + return i, err +} + +func (ejvr *extJSONValueReader) ReadInt64() (int64, error) { + if err := ejvr.ensureElementValue(TypeInt64, 0, "ReadInt64"); err != nil { + return 0, err + } + + v, err := ejvr.p.readValue(TypeInt64) + if err != nil { + return 0, err + } + + i, err := v.parseInt64() + + ejvr.pop() + return i, err +} + +func (ejvr *extJSONValueReader) ReadJavascript() (code string, err error) { + if err = ejvr.ensureElementValue(TypeJavaScript, 0, "ReadJavascript"); err != nil { + return "", err + } + + v, err := ejvr.p.readValue(TypeJavaScript) + if err != nil { + return "", err + } + + code, err = v.parseJavascript() + + ejvr.pop() + return code, err +} + +func (ejvr *extJSONValueReader) ReadMaxKey() error { + if err := ejvr.ensureElementValue(TypeMaxKey, 0, "ReadMaxKey"); err != nil { + return err + } + + v, err := ejvr.p.readValue(TypeMaxKey) + if err != nil { + return err + } + + err = v.parseMinMaxKey("max") + + ejvr.pop() + return err +} + +func (ejvr *extJSONValueReader) ReadMinKey() error { + if err := ejvr.ensureElementValue(TypeMinKey, 0, "ReadMinKey"); err != nil { + return err + } + + v, err := ejvr.p.readValue(TypeMinKey) + if err != nil { + return err + } + + err = v.parseMinMaxKey("min") + + ejvr.pop() + return err +} + +func (ejvr *extJSONValueReader) ReadNull() error { + if err := ejvr.ensureElementValue(TypeNull, 0, "ReadNull"); err != nil { + return err + } + + v, err := ejvr.p.readValue(TypeNull) + if err != nil { + return err + } + + if v.t != TypeNull { + return fmt.Errorf("expected type null but got type %s", v.t) + } + + ejvr.pop() + return nil +} + +func (ejvr *extJSONValueReader) ReadObjectID() (ObjectID, error) { + if err := ejvr.ensureElementValue(TypeObjectID, 0, "ReadObjectID"); err != nil { + return ObjectID{}, err + } + + v, err := ejvr.p.readValue(TypeObjectID) + if err != nil { + return ObjectID{}, err + } + + oid, err := v.parseObjectID() + + ejvr.pop() + return oid, err +} + +func (ejvr *extJSONValueReader) ReadRegex() (pattern string, options string, err error) { + if err = ejvr.ensureElementValue(TypeRegex, 0, "ReadRegex"); err != nil { + return "", "", err + } + + v, err := ejvr.p.readValue(TypeRegex) + if err != nil { + return "", "", err + } + + pattern, options, err = v.parseRegex() + + ejvr.pop() + return pattern, options, err +} + +func (ejvr *extJSONValueReader) ReadString() (string, error) { + if err := ejvr.ensureElementValue(TypeString, 0, "ReadString"); err != nil { + return "", err + } + + v, err := ejvr.p.readValue(TypeString) + if err != nil { + return "", err + } + + if v.t != TypeString { + return "", fmt.Errorf("expected type string but got type %s", v.t) + } + + ejvr.pop() + return v.v.(string), nil +} + +func (ejvr *extJSONValueReader) ReadSymbol() (symbol string, err error) { + if err = ejvr.ensureElementValue(TypeSymbol, 0, "ReadSymbol"); err != nil { + return "", err + } + + v, err := ejvr.p.readValue(TypeSymbol) + if err != nil { + return "", err + } + + symbol, err = v.parseSymbol() + + ejvr.pop() + return symbol, err +} + +func (ejvr *extJSONValueReader) ReadTimestamp() (t uint32, i uint32, err error) { + if err = ejvr.ensureElementValue(TypeTimestamp, 0, "ReadTimestamp"); err != nil { + return 0, 0, err + } + + v, err := ejvr.p.readValue(TypeTimestamp) + if err != nil { + return 0, 0, err + } + + t, i, err = v.parseTimestamp() + + ejvr.pop() + return t, i, err +} + +func (ejvr *extJSONValueReader) ReadUndefined() error { + if err := ejvr.ensureElementValue(TypeUndefined, 0, "ReadUndefined"); err != nil { + return err + } + + v, err := ejvr.p.readValue(TypeUndefined) + if err != nil { + return err + } + + err = v.parseUndefined() + + ejvr.pop() + return err +} + +func (ejvr *extJSONValueReader) ReadElement() (string, ValueReader, error) { + switch ejvr.stack[ejvr.frame].mode { + case mTopLevel, mDocument, mCodeWithScope: + default: + return "", nil, ejvr.invalidTransitionErr(mElement, "ReadElement", []mode{mTopLevel, mDocument, mCodeWithScope}) + } + + name, t, err := ejvr.p.readKey() + + if err != nil { + if errors.Is(err, ErrEOD) { + if ejvr.stack[ejvr.frame].mode == mCodeWithScope { + _, err := ejvr.p.peekType() + if err != nil { + return "", nil, err + } + } + + ejvr.pop() + } + + return "", nil, err + } + + ejvr.push(mElement, t) + return name, ejvr, nil +} + +func (ejvr *extJSONValueReader) ReadValue() (ValueReader, error) { + switch ejvr.stack[ejvr.frame].mode { + case mArray: + default: + return nil, ejvr.invalidTransitionErr(mValue, "ReadValue", []mode{mArray}) + } + + t, err := ejvr.p.peekType() + if err != nil { + if errors.Is(err, ErrEOA) { + ejvr.pop() + } + + return nil, err + } + + ejvr.push(mValue, t) + return ejvr, nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_tables.go b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_tables.go new file mode 100644 index 000000000..5384db225 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/v2/bson/extjson_tables.go @@ -0,0 +1,223 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 +// +// Based on github.com/golang/go by The Go Authors +// See THIRD-PARTY-NOTICES for original license terms. + +package bson + +import "unicode/utf8" + +// safeSet holds the value true if the ASCII character with the given array +// position can be represented inside a JSON string without any further +// escaping. +// +// All values are true except for the ASCII control characters (0-31), the +// double quote ("), and the backslash character ("\"). +var safeSet = [utf8.RuneSelf]bool{ + ' ': true, + '!': true, + '"': false, + '#': true, + '$': true, + '%': true, + '&': true, + '\'': true, + '(': true, + ')': true, + '*': true, + '+': true, + ',': true, + '-': true, + '.': true, + '/': true, + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + ':': true, + ';': true, + '<': true, + '=': true, + '>': true, + '?': true, + '@': true, + 'A': true, + 'B': true, + 'C': true, + 'D': true, + 'E': true, + 'F': true, + 'G': true, + 'H': true, + 'I': true, + 'J': true, + 'K': true, + 'L': true, + 'M': true, + 'N': true, + 'O': true, + 'P': true, + 'Q': true, + 'R': true, + 'S': true, + 'T': true, + 'U': true, + 'V': true, + 'W': true, + 'X': true, + 'Y': true, + 'Z': true, + '[': true, + '\\': false, + ']': true, + '^': true, + '_': true, + '`': true, + 'a': true, + 'b': true, + 'c': true, + 'd': true, + 'e': true, + 'f': true, + 'g': true, + 'h': true, + 'i': true, + 'j': true, + 'k': true, + 'l': true, + 'm': true, + 'n': true, + 'o': true, + 'p': true, + 'q': true, + 'r': true, + 's': true, + 't': true, + 'u': true, + 'v': true, + 'w': true, + 'x': true, + 'y': true, + 'z': true, + '{': true, + '|': true, + '}': true, + '~': true, + '\u007f': true, +} + +// htmlSafeSet holds the value true if the ASCII character with the given +// array position can be safely represented inside a JSON string, embedded +// inside of HTML