diff options
| author | 2024-03-06 09:05:45 -0800 | |
|---|---|---|
| committer | 2024-03-06 18:05:45 +0100 | |
| commit | fc3741365c27f1d703e8a736af95b95ff811cc45 (patch) | |
| tree | 929f1d5e20d1469d63a3dfe81d38d89f9a073c5a /vendor/go.mongodb.org/mongo-driver/bson/bsoncodec | |
| parent | [chore/bugfix] Little DB fixes (#2726) (diff) | |
| download | gotosocial-fc3741365c27f1d703e8a736af95b95ff811cc45.tar.xz | |
[bugfix] Fix Swagger spec and add test script (#2698)
* Add Swagger spec test script
* Fix Swagger spec errors not related to statuses with polls
* Add API tests that post a status with a poll
* Fix creating a status with a poll from form params
* Fix Swagger spec errors related to statuses with polls (this is the last error)
* Fix Swagger spec warnings not related to unused definitions
* Suppress a duplicate list update params definition that was somehow causing wrong param names
* Add Swagger test to CI
- updates Drone config
- vendorizes go-swagger
- fixes a file extension issue that caused the test script to generate JSON instead of YAML with the vendorized version
* Put `Sample: ` on its own line everywhere
* Remove unused id param from emojiCategoriesGet
* Add 5 more pairs of profile fields to account update API Swagger
* Remove Swagger prefix from dummy fields
It makes the generated code look weird
* Manually annotate params for statusCreate operation
* Fix all remaining Swagger spec warnings
- Change some models into operation parameters
- Ignore models that already correspond to manually documented operation parameters but can't be trivially changed (those with file fields)
* Documented that creating a status with scheduled_at isn't implemented yet
* sign drone.yml
* Fix filter API Swagger errors
* fixup! Fix filter API Swagger errors
---------
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Diffstat (limited to 'vendor/go.mongodb.org/mongo-driver/bson/bsoncodec')
20 files changed, 5638 insertions, 0 deletions
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go new file mode 100644 index 000000000..4e24f9eed --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go @@ -0,0 +1,50 @@ +// 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 bsoncodec + +import ( +	"reflect" + +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore" +) + +// ArrayCodec is the Codec used for bsoncore.Array values. +type ArrayCodec struct{} + +var defaultArrayCodec = NewArrayCodec() + +// NewArrayCodec returns an ArrayCodec. +func NewArrayCodec() *ArrayCodec { +	return &ArrayCodec{} +} + +// EncodeValue is the ValueEncoder for bsoncore.Array values. +func (ac *ArrayCodec) EncodeValue(ec EncodeContext, vw bsonrw.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 bsonrw.Copier{}.CopyArrayFromBytes(vw, arr) +} + +// DecodeValue is the ValueDecoder for bsoncore.Array values. +func (ac *ArrayCodec) DecodeValue(dc DecodeContext, vr bsonrw.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 := bsonrw.Copier{}.AppendArrayBytes(val.Interface().(bsoncore.Array), vr) +	val.Set(reflect.ValueOf(arr)) +	return err +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go new file mode 100644 index 000000000..098ed69f9 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go @@ -0,0 +1,238 @@ +// 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 bsoncodec // import "go.mongodb.org/mongo-driver/bson/bsoncodec" + +import ( +	"fmt" +	"reflect" +	"strings" + +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +	"go.mongodb.org/mongo-driver/bson/primitive" +) + +var ( +	emptyValue = reflect.Value{} +) + +// Marshaler is an interface implemented by types that can marshal themselves +// into a BSON document represented as bytes. The bytes returned must be a valid +// BSON document if the error is nil. +type Marshaler interface { +	MarshalBSON() ([]byte, error) +} + +// ValueMarshaler is an interface implemented by types that can marshal +// themselves into a BSON value as bytes. The type must be the valid type for +// the bytes returned. The bytes and byte type together must be valid if the +// error is nil. +type ValueMarshaler interface { +	MarshalBSONValue() (bsontype.Type, []byte, error) +} + +// Unmarshaler is an interface implemented by types that can unmarshal a BSON +// document representation of themselves. The BSON bytes can be assumed to be +// valid. UnmarshalBSON must copy the BSON bytes if it wishes to retain the data +// after returning. +type Unmarshaler interface { +	UnmarshalBSON([]byte) error +} + +// ValueUnmarshaler is an interface implemented by types that can unmarshal a +// BSON value representation of themselves. The BSON bytes and type can be +// assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it +// wishes to retain the data after returning. +type ValueUnmarshaler interface { +	UnmarshalBSONValue(bsontype.Type, []byte) error +} + +// 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() +	} +	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 bool +} + +// DecodeContext is the contextual information required for a Codec to decode a +// value. +type DecodeContext struct { +	*Registry +	Truncate bool + +	// Ancestor is the type of a containing document. This is mainly used to determine what type +	// should be used when decoding an embedded document into an empty interface. For example, if +	// Ancestor is a bson.M, BSON embedded document values being decoded into an empty interface +	// will be decoded into a bson.M. +	// +	// Deprecated: Use DefaultDocumentM or DefaultDocumentD instead. +	Ancestor reflect.Type + +	// 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 "interface{}" or "map[string]interface{}". If DocumentType is +	// set to a type that a BSON document cannot be unmarshaled into (e.g. "string"), unmarshalling will result in an +	// error. DocumentType overrides the Ancestor field. +	defaultDocumentType reflect.Type +} + +// DefaultDocumentM will decode empty documents using the primitive.M type. This behavior is restricted to data typed as +// "interface{}" or "map[string]interface{}". +func (dc *DecodeContext) DefaultDocumentM() { +	dc.defaultDocumentType = reflect.TypeOf(primitive.M{}) +} + +// DefaultDocumentD will decode empty documents using the primitive.D type. This behavior is restricted to data typed as +// "interface{}" or "map[string]interface{}". +func (dc *DecodeContext) DefaultDocumentD() { +	dc.defaultDocumentType = reflect.TypeOf(primitive.D{}) +} + +// ValueCodec is the interface that groups the methods to encode and decode +// values. +type ValueCodec interface { +	ValueEncoder +	ValueDecoder +} + +// ValueEncoder is the interface implemented by types that can handle the encoding of a value. +type ValueEncoder interface { +	EncodeValue(EncodeContext, bsonrw.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, bsonrw.ValueWriter, reflect.Value) error + +// EncodeValue implements the ValueEncoder interface. +func (fn ValueEncoderFunc) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	return fn(ec, vw, val) +} + +// ValueDecoder is the interface implemented by types that can handle the decoding of a value. +type ValueDecoder interface { +	DecodeValue(DecodeContext, bsonrw.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, bsonrw.ValueReader, reflect.Value) error + +// DecodeValue implements the ValueDecoder interface. +func (fn ValueDecoderFunc) DecodeValue(dc DecodeContext, vr bsonrw.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, bsonrw.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, bsonrw.ValueReader, reflect.Type) (reflect.Value, error) + +func (fn typeDecoderFunc) decodeType(dc DecodeContext, vr bsonrw.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{} + +// decodeTypeOrValue calls decoder.decodeType is decoder is a typeDecoder. Otherwise, it allocates a new element of type +// t and calls decoder.DecodeValue on it. +func decodeTypeOrValue(decoder ValueDecoder, dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { +	td, _ := decoder.(typeDecoder) +	return decodeTypeOrValueWithInfo(decoder, td, dc, vr, t, true) +} + +func decodeTypeOrValueWithInfo(vd ValueDecoder, td typeDecoder, dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type, convert bool) (reflect.Value, error) { +	if td != nil { +		val, err := td.decodeType(dc, vr, t) +		if err == nil && convert && 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 +} + +// CodecZeroer is the interface implemented by Codecs that can also determine if +// a value of the type that would be encoded is zero. +type CodecZeroer interface { +	IsTypeZero(interface{}) bool +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go new file mode 100644 index 000000000..5a916cc15 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go @@ -0,0 +1,111 @@ +// 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 bsoncodec + +import ( +	"fmt" +	"reflect" + +	"go.mongodb.org/mongo-driver/bson/bsonoptions" +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +) + +// ByteSliceCodec is the Codec used for []byte values. +type ByteSliceCodec struct { +	EncodeNilAsEmpty bool +} + +var ( +	defaultByteSliceCodec = NewByteSliceCodec() + +	_ ValueCodec  = defaultByteSliceCodec +	_ typeDecoder = defaultByteSliceCodec +) + +// NewByteSliceCodec returns a StringCodec with options opts. +func NewByteSliceCodec(opts ...*bsonoptions.ByteSliceCodecOptions) *ByteSliceCodec { +	byteSliceOpt := bsonoptions.MergeByteSliceCodecOptions(opts...) +	codec := ByteSliceCodec{} +	if byteSliceOpt.EncodeNilAsEmpty != nil { +		codec.EncodeNilAsEmpty = *byteSliceOpt.EncodeNilAsEmpty +	} +	return &codec +} + +// EncodeValue is the ValueEncoder for []byte. +func (bsc *ByteSliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.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 { +		return vw.WriteNull() +	} +	return vw.WriteBinary(val.Interface().([]byte)) +} + +func (bsc *ByteSliceCodec) decodeType(dc DecodeContext, vr bsonrw.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 bsontype.String: +		str, err := vr.ReadString() +		if err != nil { +			return emptyValue, err +		} +		data = []byte(str) +	case bsontype.Symbol: +		sym, err := vr.ReadSymbol() +		if err != nil { +			return emptyValue, err +		} +		data = []byte(sym) +	case bsontype.Binary: +		var subtype byte +		data, subtype, err = vr.ReadBinary() +		if err != nil { +			return emptyValue, err +		} +		if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld { +			return emptyValue, decodeBinaryError{subtype: subtype, typeName: "[]byte"} +		} +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		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 bsonrw.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/bson/bsoncodec/cond_addr_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go new file mode 100644 index 000000000..cb8180f25 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go @@ -0,0 +1,63 @@ +// 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 bsoncodec + +import ( +	"reflect" + +	"go.mongodb.org/mongo-driver/bson/bsonrw" +) + +// 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)(nil) + +// 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 bsonrw.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)(nil) + +// 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 bsonrw.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/bson/bsoncodec/default_value_decoders.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go new file mode 100644 index 000000000..e95cab585 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go @@ -0,0 +1,1729 @@ +// 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 bsoncodec + +import ( +	"encoding/json" +	"errors" +	"fmt" +	"math" +	"net/url" +	"reflect" +	"strconv" +	"time" + +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +	"go.mongodb.org/mongo-driver/bson/primitive" +	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore" +) + +var ( +	defaultValueDecoders DefaultValueDecoders +	errCannotTruncate    = errors.New("float64 can only be truncated to an integer 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) +} + +func newDefaultStructCodec() *StructCodec { +	codec, err := NewStructCodec(DefaultStructTagParser) +	if err != nil { +		// This function is called from the codec registration path, so errors can't be propagated. If there's an error +		// constructing the StructCodec, we panic to avoid losing it. +		panic(fmt.Errorf("error creating default StructCodec: %v", err)) +	} +	return codec +} + +// DefaultValueDecoders is a namespace type for the default ValueDecoders used +// when creating a registry. +type DefaultValueDecoders struct{} + +// RegisterDefaultDecoders will register the decoder methods attached to DefaultValueDecoders with +// the provided RegistryBuilder. +// +// There is no support for decoding map[string]interface{} because there is no decoder for +// interface{}, so users must either register this decoder themselves or use the +// EmptyInterfaceDecoder available in the bson package. +func (dvd DefaultValueDecoders) RegisterDefaultDecoders(rb *RegistryBuilder) { +	if rb == nil { +		panic(errors.New("argument to RegisterDefaultDecoders must not be nil")) +	} + +	intDecoder := decodeAdapter{dvd.IntDecodeValue, dvd.intDecodeType} +	floatDecoder := decodeAdapter{dvd.FloatDecodeValue, dvd.floatDecodeType} + +	rb. +		RegisterTypeDecoder(tD, ValueDecoderFunc(dvd.DDecodeValue)). +		RegisterTypeDecoder(tBinary, decodeAdapter{dvd.BinaryDecodeValue, dvd.binaryDecodeType}). +		RegisterTypeDecoder(tUndefined, decodeAdapter{dvd.UndefinedDecodeValue, dvd.undefinedDecodeType}). +		RegisterTypeDecoder(tDateTime, decodeAdapter{dvd.DateTimeDecodeValue, dvd.dateTimeDecodeType}). +		RegisterTypeDecoder(tNull, decodeAdapter{dvd.NullDecodeValue, dvd.nullDecodeType}). +		RegisterTypeDecoder(tRegex, decodeAdapter{dvd.RegexDecodeValue, dvd.regexDecodeType}). +		RegisterTypeDecoder(tDBPointer, decodeAdapter{dvd.DBPointerDecodeValue, dvd.dBPointerDecodeType}). +		RegisterTypeDecoder(tTimestamp, decodeAdapter{dvd.TimestampDecodeValue, dvd.timestampDecodeType}). +		RegisterTypeDecoder(tMinKey, decodeAdapter{dvd.MinKeyDecodeValue, dvd.minKeyDecodeType}). +		RegisterTypeDecoder(tMaxKey, decodeAdapter{dvd.MaxKeyDecodeValue, dvd.maxKeyDecodeType}). +		RegisterTypeDecoder(tJavaScript, decodeAdapter{dvd.JavaScriptDecodeValue, dvd.javaScriptDecodeType}). +		RegisterTypeDecoder(tSymbol, decodeAdapter{dvd.SymbolDecodeValue, dvd.symbolDecodeType}). +		RegisterTypeDecoder(tByteSlice, defaultByteSliceCodec). +		RegisterTypeDecoder(tTime, defaultTimeCodec). +		RegisterTypeDecoder(tEmpty, defaultEmptyInterfaceCodec). +		RegisterTypeDecoder(tCoreArray, defaultArrayCodec). +		RegisterTypeDecoder(tOID, decodeAdapter{dvd.ObjectIDDecodeValue, dvd.objectIDDecodeType}). +		RegisterTypeDecoder(tDecimal, decodeAdapter{dvd.Decimal128DecodeValue, dvd.decimal128DecodeType}). +		RegisterTypeDecoder(tJSONNumber, decodeAdapter{dvd.JSONNumberDecodeValue, dvd.jsonNumberDecodeType}). +		RegisterTypeDecoder(tURL, decodeAdapter{dvd.URLDecodeValue, dvd.urlDecodeType}). +		RegisterTypeDecoder(tCoreDocument, ValueDecoderFunc(dvd.CoreDocumentDecodeValue)). +		RegisterTypeDecoder(tCodeWithScope, decodeAdapter{dvd.CodeWithScopeDecodeValue, dvd.codeWithScopeDecodeType}). +		RegisterDefaultDecoder(reflect.Bool, decodeAdapter{dvd.BooleanDecodeValue, dvd.booleanDecodeType}). +		RegisterDefaultDecoder(reflect.Int, intDecoder). +		RegisterDefaultDecoder(reflect.Int8, intDecoder). +		RegisterDefaultDecoder(reflect.Int16, intDecoder). +		RegisterDefaultDecoder(reflect.Int32, intDecoder). +		RegisterDefaultDecoder(reflect.Int64, intDecoder). +		RegisterDefaultDecoder(reflect.Uint, defaultUIntCodec). +		RegisterDefaultDecoder(reflect.Uint8, defaultUIntCodec). +		RegisterDefaultDecoder(reflect.Uint16, defaultUIntCodec). +		RegisterDefaultDecoder(reflect.Uint32, defaultUIntCodec). +		RegisterDefaultDecoder(reflect.Uint64, defaultUIntCodec). +		RegisterDefaultDecoder(reflect.Float32, floatDecoder). +		RegisterDefaultDecoder(reflect.Float64, floatDecoder). +		RegisterDefaultDecoder(reflect.Array, ValueDecoderFunc(dvd.ArrayDecodeValue)). +		RegisterDefaultDecoder(reflect.Map, defaultMapCodec). +		RegisterDefaultDecoder(reflect.Slice, defaultSliceCodec). +		RegisterDefaultDecoder(reflect.String, defaultStringCodec). +		RegisterDefaultDecoder(reflect.Struct, newDefaultStructCodec()). +		RegisterDefaultDecoder(reflect.Ptr, NewPointerCodec()). +		RegisterTypeMapEntry(bsontype.Double, tFloat64). +		RegisterTypeMapEntry(bsontype.String, tString). +		RegisterTypeMapEntry(bsontype.Array, tA). +		RegisterTypeMapEntry(bsontype.Binary, tBinary). +		RegisterTypeMapEntry(bsontype.Undefined, tUndefined). +		RegisterTypeMapEntry(bsontype.ObjectID, tOID). +		RegisterTypeMapEntry(bsontype.Boolean, tBool). +		RegisterTypeMapEntry(bsontype.DateTime, tDateTime). +		RegisterTypeMapEntry(bsontype.Regex, tRegex). +		RegisterTypeMapEntry(bsontype.DBPointer, tDBPointer). +		RegisterTypeMapEntry(bsontype.JavaScript, tJavaScript). +		RegisterTypeMapEntry(bsontype.Symbol, tSymbol). +		RegisterTypeMapEntry(bsontype.CodeWithScope, tCodeWithScope). +		RegisterTypeMapEntry(bsontype.Int32, tInt32). +		RegisterTypeMapEntry(bsontype.Int64, tInt64). +		RegisterTypeMapEntry(bsontype.Timestamp, tTimestamp). +		RegisterTypeMapEntry(bsontype.Decimal128, tDecimal). +		RegisterTypeMapEntry(bsontype.MinKey, tMinKey). +		RegisterTypeMapEntry(bsontype.MaxKey, tMaxKey). +		RegisterTypeMapEntry(bsontype.Type(0), tD). +		RegisterTypeMapEntry(bsontype.EmbeddedDocument, tD). +		RegisterHookDecoder(tValueUnmarshaler, ValueDecoderFunc(dvd.ValueUnmarshalerDecodeValue)). +		RegisterHookDecoder(tUnmarshaler, ValueDecoderFunc(dvd.UnmarshalerDecodeValue)) +} + +// DDecodeValue is the ValueDecoderFunc for primitive.D instances. +func (dvd DefaultValueDecoders) DDecodeValue(dc DecodeContext, vr bsonrw.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 bsontype.Type(0), bsontype.EmbeddedDocument: +		dc.Ancestor = tD +	case bsontype.Null: +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadNull() +	default: +		return fmt.Errorf("cannot decode %v into a primitive.D", vrType) +	} + +	dr, err := vr.ReadDocument() +	if err != nil { +		return err +	} + +	decoder, err := dc.LookupDecoder(tEmpty) +	if err != nil { +		return err +	} +	tEmptyTypeDecoder, _ := decoder.(typeDecoder) + +	// Use the elements in the provided value if it's non nil. Otherwise, allocate a new D instance. +	var elems primitive.D +	if !val.IsNil() { +		val.SetLen(0) +		elems = val.Interface().(primitive.D) +	} else { +		elems = make(primitive.D, 0) +	} + +	for { +		key, elemVr, err := dr.ReadElement() +		if err == bsonrw.ErrEOD { +			break +		} else if err != nil { +			return err +		} + +		// Pass false for convert because we don't need to call reflect.Value.Convert for tEmpty. +		elem, err := decodeTypeOrValueWithInfo(decoder, tEmptyTypeDecoder, dc, elemVr, tEmpty, false) +		if err != nil { +			return err +		} + +		elems = append(elems, primitive.E{Key: key, Value: elem.Interface()}) +	} + +	val.Set(reflect.ValueOf(elems)) +	return nil +} + +func (dvd DefaultValueDecoders) booleanDecodeType(dctx DecodeContext, vr bsonrw.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 bsontype.Int32: +		i32, err := vr.ReadInt32() +		if err != nil { +			return emptyValue, err +		} +		b = (i32 != 0) +	case bsontype.Int64: +		i64, err := vr.ReadInt64() +		if err != nil { +			return emptyValue, err +		} +		b = (i64 != 0) +	case bsontype.Double: +		f64, err := vr.ReadDouble() +		if err != nil { +			return emptyValue, err +		} +		b = (f64 != 0) +	case bsontype.Boolean: +		b, err = vr.ReadBoolean() +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		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 (dvd DefaultValueDecoders) BooleanDecodeValue(dctx DecodeContext, vr bsonrw.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 := dvd.booleanDecodeType(dctx, vr, val.Type()) +	if err != nil { +		return err +	} + +	val.SetBool(elem.Bool()) +	return nil +} + +func (DefaultValueDecoders) intDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { +	var i64 int64 +	var err error +	switch vrType := vr.Type(); vrType { +	case bsontype.Int32: +		i32, err := vr.ReadInt32() +		if err != nil { +			return emptyValue, err +		} +		i64 = int64(i32) +	case bsontype.Int64: +		i64, err = vr.ReadInt64() +		if err != nil { +			return emptyValue, err +		} +	case bsontype.Double: +		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 bsontype.Boolean: +		b, err := vr.ReadBoolean() +		if err != nil { +			return emptyValue, err +		} +		if b { +			i64 = 1 +		} +	case bsontype.Null: +		if err = vr.ReadNull(); err != nil { +			return emptyValue, err +		} +	case bsontype.Undefined: +		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 int64(int(i64)) != i64 { // 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 (dvd DefaultValueDecoders) IntDecodeValue(dc DecodeContext, vr bsonrw.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 := dvd.intDecodeType(dc, vr, val.Type()) +	if err != nil { +		return err +	} + +	val.SetInt(elem.Int()) +	return nil +} + +// UintDecodeValue is the ValueDecoderFunc for uint types. +// +// Deprecated: UintDecodeValue is not registered by default. Use UintCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) UintDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	var i64 int64 +	var err error +	switch vr.Type() { +	case bsontype.Int32: +		i32, err := vr.ReadInt32() +		if err != nil { +			return err +		} +		i64 = int64(i32) +	case bsontype.Int64: +		i64, err = vr.ReadInt64() +		if err != nil { +			return err +		} +	case bsontype.Double: +		f64, err := vr.ReadDouble() +		if err != nil { +			return err +		} +		if !dc.Truncate && math.Floor(f64) != f64 { +			return errors.New("UintDecodeValue can only truncate float64 to an integer type when truncation is enabled") +		} +		if f64 > float64(math.MaxInt64) { +			return fmt.Errorf("%g overflows int64", f64) +		} +		i64 = int64(f64) +	case bsontype.Boolean: +		b, err := vr.ReadBoolean() +		if err != nil { +			return err +		} +		if b { +			i64 = 1 +		} +	default: +		return fmt.Errorf("cannot decode %v into an integer type", vr.Type()) +	} + +	if !val.CanSet() { +		return ValueDecoderError{ +			Name:     "UintDecodeValue", +			Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, +			Received: val, +		} +	} + +	switch val.Kind() { +	case reflect.Uint8: +		if i64 < 0 || i64 > math.MaxUint8 { +			return fmt.Errorf("%d overflows uint8", i64) +		} +	case reflect.Uint16: +		if i64 < 0 || i64 > math.MaxUint16 { +			return fmt.Errorf("%d overflows uint16", i64) +		} +	case reflect.Uint32: +		if i64 < 0 || i64 > math.MaxUint32 { +			return fmt.Errorf("%d overflows uint32", i64) +		} +	case reflect.Uint64: +		if i64 < 0 { +			return fmt.Errorf("%d overflows uint64", i64) +		} +	case reflect.Uint: +		if i64 < 0 || int64(uint(i64)) != i64 { // Can we fit this inside of an uint +			return fmt.Errorf("%d overflows uint", i64) +		} +	default: +		return ValueDecoderError{ +			Name:     "UintDecodeValue", +			Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, +			Received: val, +		} +	} + +	val.SetUint(uint64(i64)) +	return nil +} + +func (dvd DefaultValueDecoders) floatDecodeType(ec DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { +	var f float64 +	var err error +	switch vrType := vr.Type(); vrType { +	case bsontype.Int32: +		i32, err := vr.ReadInt32() +		if err != nil { +			return emptyValue, err +		} +		f = float64(i32) +	case bsontype.Int64: +		i64, err := vr.ReadInt64() +		if err != nil { +			return emptyValue, err +		} +		f = float64(i64) +	case bsontype.Double: +		f, err = vr.ReadDouble() +		if err != nil { +			return emptyValue, err +		} +	case bsontype.Boolean: +		b, err := vr.ReadBoolean() +		if err != nil { +			return emptyValue, err +		} +		if b { +			f = 1 +		} +	case bsontype.Null: +		if err = vr.ReadNull(); err != nil { +			return emptyValue, err +		} +	case bsontype.Undefined: +		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 !ec.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 (dvd DefaultValueDecoders) FloatDecodeValue(ec DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() { +		return ValueDecoderError{ +			Name:     "FloatDecodeValue", +			Kinds:    []reflect.Kind{reflect.Float32, reflect.Float64}, +			Received: val, +		} +	} + +	elem, err := dvd.floatDecodeType(ec, vr, val.Type()) +	if err != nil { +		return err +	} + +	val.SetFloat(elem.Float()) +	return nil +} + +// StringDecodeValue is the ValueDecoderFunc for string types. +// +// Deprecated: StringDecodeValue is not registered by default. Use StringCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) StringDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	var str string +	var err error +	switch vr.Type() { +	// TODO(GODRIVER-577): Handle JavaScript and Symbol BSON types when allowed. +	case bsontype.String: +		str, err = vr.ReadString() +		if err != nil { +			return err +		} +	default: +		return fmt.Errorf("cannot decode %v into a string type", vr.Type()) +	} +	if !val.CanSet() || val.Kind() != reflect.String { +		return ValueDecoderError{Name: "StringDecodeValue", Kinds: []reflect.Kind{reflect.String}, Received: val} +	} + +	val.SetString(str) +	return nil +} + +func (DefaultValueDecoders) javaScriptDecodeType(dctx DecodeContext, vr bsonrw.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 bsontype.JavaScript: +		js, err = vr.ReadJavascript() +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		err = vr.ReadUndefined() +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a primitive.JavaScript", vrType) +	} +	if err != nil { +		return emptyValue, err +	} + +	return reflect.ValueOf(primitive.JavaScript(js)), nil +} + +// JavaScriptDecodeValue is the ValueDecoderFunc for the primitive.JavaScript type. +func (dvd DefaultValueDecoders) JavaScriptDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tJavaScript { +		return ValueDecoderError{Name: "JavaScriptDecodeValue", Types: []reflect.Type{tJavaScript}, Received: val} +	} + +	elem, err := dvd.javaScriptDecodeType(dctx, vr, tJavaScript) +	if err != nil { +		return err +	} + +	val.SetString(elem.String()) +	return nil +} + +func (DefaultValueDecoders) symbolDecodeType(dctx DecodeContext, vr bsonrw.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 bsontype.String: +		symbol, err = vr.ReadString() +	case bsontype.Symbol: +		symbol, err = vr.ReadSymbol() +	case bsontype.Binary: +		data, subtype, err := vr.ReadBinary() +		if err != nil { +			return emptyValue, err +		} + +		if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld { +			return emptyValue, decodeBinaryError{subtype: subtype, typeName: "primitive.Symbol"} +		} +		symbol = string(data) +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		err = vr.ReadUndefined() +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a primitive.Symbol", vrType) +	} +	if err != nil { +		return emptyValue, err +	} + +	return reflect.ValueOf(primitive.Symbol(symbol)), nil +} + +// SymbolDecodeValue is the ValueDecoderFunc for the primitive.Symbol type. +func (dvd DefaultValueDecoders) SymbolDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tSymbol { +		return ValueDecoderError{Name: "SymbolDecodeValue", Types: []reflect.Type{tSymbol}, Received: val} +	} + +	elem, err := dvd.symbolDecodeType(dctx, vr, tSymbol) +	if err != nil { +		return err +	} + +	val.SetString(elem.String()) +	return nil +} + +func (DefaultValueDecoders) binaryDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { +	if t != tBinary { +		return emptyValue, ValueDecoderError{ +			Name:     "BinaryDecodeValue", +			Types:    []reflect.Type{tBinary}, +			Received: reflect.Zero(t), +		} +	} + +	var data []byte +	var subtype byte +	var err error +	switch vrType := vr.Type(); vrType { +	case bsontype.Binary: +		data, subtype, err = vr.ReadBinary() +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		err = vr.ReadUndefined() +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a Binary", vrType) +	} +	if err != nil { +		return emptyValue, err +	} + +	return reflect.ValueOf(primitive.Binary{Subtype: subtype, Data: data}), nil +} + +// BinaryDecodeValue is the ValueDecoderFunc for Binary. +func (dvd DefaultValueDecoders) BinaryDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tBinary { +		return ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tBinary}, Received: val} +	} + +	elem, err := dvd.binaryDecodeType(dc, vr, tBinary) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (DefaultValueDecoders) undefinedDecodeType(dc DecodeContext, vr bsonrw.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 bsontype.Undefined: +		err = vr.ReadUndefined() +	case bsontype.Null: +		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(primitive.Undefined{}), nil +} + +// UndefinedDecodeValue is the ValueDecoderFunc for Undefined. +func (dvd DefaultValueDecoders) UndefinedDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tUndefined { +		return ValueDecoderError{Name: "UndefinedDecodeValue", Types: []reflect.Type{tUndefined}, Received: val} +	} + +	elem, err := dvd.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 (dvd DefaultValueDecoders) objectIDDecodeType(dc DecodeContext, vr bsonrw.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 primitive.ObjectID +	var err error +	switch vrType := vr.Type(); vrType { +	case bsontype.ObjectID: +		oid, err = vr.ReadObjectID() +		if err != nil { +			return emptyValue, err +		} +	case bsontype.String: +		str, err := vr.ReadString() +		if err != nil { +			return emptyValue, err +		} +		if oid, err = primitive.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 bsontype.Null: +		if err = vr.ReadNull(); err != nil { +			return emptyValue, err +		} +	case bsontype.Undefined: +		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 primitive.ObjectID. +func (dvd DefaultValueDecoders) ObjectIDDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tOID { +		return ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}, Received: val} +	} + +	elem, err := dvd.objectIDDecodeType(dc, vr, tOID) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (DefaultValueDecoders) dateTimeDecodeType(dc DecodeContext, vr bsonrw.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 bsontype.DateTime: +		dt, err = vr.ReadDateTime() +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		err = vr.ReadUndefined() +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a DateTime", vrType) +	} +	if err != nil { +		return emptyValue, err +	} + +	return reflect.ValueOf(primitive.DateTime(dt)), nil +} + +// DateTimeDecodeValue is the ValueDecoderFunc for DateTime. +func (dvd DefaultValueDecoders) DateTimeDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tDateTime { +		return ValueDecoderError{Name: "DateTimeDecodeValue", Types: []reflect.Type{tDateTime}, Received: val} +	} + +	elem, err := dvd.dateTimeDecodeType(dc, vr, tDateTime) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (DefaultValueDecoders) nullDecodeType(dc DecodeContext, vr bsonrw.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 bsontype.Undefined: +		err = vr.ReadUndefined() +	case bsontype.Null: +		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(primitive.Null{}), nil +} + +// NullDecodeValue is the ValueDecoderFunc for Null. +func (dvd DefaultValueDecoders) NullDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tNull { +		return ValueDecoderError{Name: "NullDecodeValue", Types: []reflect.Type{tNull}, Received: val} +	} + +	elem, err := dvd.nullDecodeType(dc, vr, tNull) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (DefaultValueDecoders) regexDecodeType(dc DecodeContext, vr bsonrw.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 bsontype.Regex: +		pattern, options, err = vr.ReadRegex() +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		err = vr.ReadUndefined() +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a Regex", vrType) +	} +	if err != nil { +		return emptyValue, err +	} + +	return reflect.ValueOf(primitive.Regex{Pattern: pattern, Options: options}), nil +} + +// RegexDecodeValue is the ValueDecoderFunc for Regex. +func (dvd DefaultValueDecoders) RegexDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tRegex { +		return ValueDecoderError{Name: "RegexDecodeValue", Types: []reflect.Type{tRegex}, Received: val} +	} + +	elem, err := dvd.regexDecodeType(dc, vr, tRegex) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (DefaultValueDecoders) dBPointerDecodeType(dc DecodeContext, vr bsonrw.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 primitive.ObjectID +	var err error +	switch vrType := vr.Type(); vrType { +	case bsontype.DBPointer: +		ns, pointer, err = vr.ReadDBPointer() +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		err = vr.ReadUndefined() +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a DBPointer", vrType) +	} +	if err != nil { +		return emptyValue, err +	} + +	return reflect.ValueOf(primitive.DBPointer{DB: ns, Pointer: pointer}), nil +} + +// DBPointerDecodeValue is the ValueDecoderFunc for DBPointer. +func (dvd DefaultValueDecoders) DBPointerDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tDBPointer { +		return ValueDecoderError{Name: "DBPointerDecodeValue", Types: []reflect.Type{tDBPointer}, Received: val} +	} + +	elem, err := dvd.dBPointerDecodeType(dc, vr, tDBPointer) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (DefaultValueDecoders) timestampDecodeType(dc DecodeContext, vr bsonrw.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 bsontype.Timestamp: +		t, incr, err = vr.ReadTimestamp() +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		err = vr.ReadUndefined() +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a Timestamp", vrType) +	} +	if err != nil { +		return emptyValue, err +	} + +	return reflect.ValueOf(primitive.Timestamp{T: t, I: incr}), nil +} + +// TimestampDecodeValue is the ValueDecoderFunc for Timestamp. +func (dvd DefaultValueDecoders) TimestampDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tTimestamp { +		return ValueDecoderError{Name: "TimestampDecodeValue", Types: []reflect.Type{tTimestamp}, Received: val} +	} + +	elem, err := dvd.timestampDecodeType(dc, vr, tTimestamp) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (DefaultValueDecoders) minKeyDecodeType(dc DecodeContext, vr bsonrw.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 bsontype.MinKey: +		err = vr.ReadMinKey() +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		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(primitive.MinKey{}), nil +} + +// MinKeyDecodeValue is the ValueDecoderFunc for MinKey. +func (dvd DefaultValueDecoders) MinKeyDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tMinKey { +		return ValueDecoderError{Name: "MinKeyDecodeValue", Types: []reflect.Type{tMinKey}, Received: val} +	} + +	elem, err := dvd.minKeyDecodeType(dc, vr, tMinKey) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (DefaultValueDecoders) maxKeyDecodeType(dc DecodeContext, vr bsonrw.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 bsontype.MaxKey: +		err = vr.ReadMaxKey() +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		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(primitive.MaxKey{}), nil +} + +// MaxKeyDecodeValue is the ValueDecoderFunc for MaxKey. +func (dvd DefaultValueDecoders) MaxKeyDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tMaxKey { +		return ValueDecoderError{Name: "MaxKeyDecodeValue", Types: []reflect.Type{tMaxKey}, Received: val} +	} + +	elem, err := dvd.maxKeyDecodeType(dc, vr, tMaxKey) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (dvd DefaultValueDecoders) decimal128DecodeType(dctx DecodeContext, vr bsonrw.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 primitive.Decimal128 +	var err error +	switch vrType := vr.Type(); vrType { +	case bsontype.Decimal128: +		d128, err = vr.ReadDecimal128() +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		err = vr.ReadUndefined() +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a primitive.Decimal128", vr.Type()) +	} +	if err != nil { +		return emptyValue, err +	} + +	return reflect.ValueOf(d128), nil +} + +// Decimal128DecodeValue is the ValueDecoderFunc for primitive.Decimal128. +func (dvd DefaultValueDecoders) Decimal128DecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tDecimal { +		return ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}, Received: val} +	} + +	elem, err := dvd.decimal128DecodeType(dctx, vr, tDecimal) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (dvd DefaultValueDecoders) jsonNumberDecodeType(dc DecodeContext, vr bsonrw.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 bsontype.Double: +		f64, err := vr.ReadDouble() +		if err != nil { +			return emptyValue, err +		} +		jsonNum = json.Number(strconv.FormatFloat(f64, 'f', -1, 64)) +	case bsontype.Int32: +		i32, err := vr.ReadInt32() +		if err != nil { +			return emptyValue, err +		} +		jsonNum = json.Number(strconv.FormatInt(int64(i32), 10)) +	case bsontype.Int64: +		i64, err := vr.ReadInt64() +		if err != nil { +			return emptyValue, err +		} +		jsonNum = json.Number(strconv.FormatInt(i64, 10)) +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		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 (dvd DefaultValueDecoders) JSONNumberDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tJSONNumber { +		return ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}, Received: val} +	} + +	elem, err := dvd.jsonNumberDecodeType(dc, vr, tJSONNumber) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (dvd DefaultValueDecoders) urlDecodeType(dc DecodeContext, vr bsonrw.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 bsontype.String: +		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 bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		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 (dvd DefaultValueDecoders) URLDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tURL { +		return ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}, Received: val} +	} + +	elem, err := dvd.urlDecodeType(dc, vr, tURL) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +// TimeDecodeValue is the ValueDecoderFunc for time.Time. +// +// Deprecated: TimeDecodeValue is not registered by default. Use TimeCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) TimeDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if vr.Type() != bsontype.DateTime { +		return fmt.Errorf("cannot decode %v into a time.Time", vr.Type()) +	} + +	dt, err := vr.ReadDateTime() +	if err != nil { +		return err +	} + +	if !val.CanSet() || val.Type() != tTime { +		return ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}, Received: val} +	} + +	val.Set(reflect.ValueOf(time.Unix(dt/1000, dt%1000*1000000).UTC())) +	return nil +} + +// ByteSliceDecodeValue is the ValueDecoderFunc for []byte. +// +// Deprecated: ByteSliceDecodeValue is not registered by default. Use ByteSliceCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) ByteSliceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if vr.Type() != bsontype.Binary && vr.Type() != bsontype.Null { +		return fmt.Errorf("cannot decode %v into a []byte", vr.Type()) +	} + +	if !val.CanSet() || val.Type() != tByteSlice { +		return ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: val} +	} + +	if vr.Type() == bsontype.Null { +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadNull() +	} + +	data, subtype, err := vr.ReadBinary() +	if err != nil { +		return err +	} +	if subtype != 0x00 { +		return fmt.Errorf("ByteSliceDecodeValue can only be used to decode subtype 0x00 for %s, got %v", bsontype.Binary, subtype) +	} + +	val.Set(reflect.ValueOf(data)) +	return nil +} + +// MapDecodeValue is the ValueDecoderFunc for map[string]* types. +// +// Deprecated: MapDecodeValue is not registered by default. Use MapCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) MapDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String { +		return ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} +	} + +	switch vr.Type() { +	case bsontype.Type(0), bsontype.EmbeddedDocument: +	case bsontype.Null: +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadNull() +	default: +		return fmt.Errorf("cannot decode %v into a %s", vr.Type(), val.Type()) +	} + +	dr, err := vr.ReadDocument() +	if err != nil { +		return err +	} + +	if val.IsNil() { +		val.Set(reflect.MakeMap(val.Type())) +	} + +	eType := val.Type().Elem() +	decoder, err := dc.LookupDecoder(eType) +	if err != nil { +		return err +	} + +	if eType == tEmpty { +		dc.Ancestor = val.Type() +	} + +	keyType := val.Type().Key() +	for { +		key, vr, err := dr.ReadElement() +		if err == bsonrw.ErrEOD { +			break +		} +		if err != nil { +			return err +		} + +		elem := reflect.New(eType).Elem() + +		err = decoder.DecodeValue(dc, vr, elem) +		if err != nil { +			return err +		} + +		val.SetMapIndex(reflect.ValueOf(key).Convert(keyType), elem) +	} +	return nil +} + +// ArrayDecodeValue is the ValueDecoderFunc for array types. +func (dvd DefaultValueDecoders) ArrayDecodeValue(dc DecodeContext, vr bsonrw.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 bsontype.Array: +	case bsontype.Type(0), bsontype.EmbeddedDocument: +		if val.Type().Elem() != tE { +			return fmt.Errorf("cannot decode document into %s", val.Type()) +		} +	case bsontype.Binary: +		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 != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld { +			return fmt.Errorf("ArrayDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", bsontype.Binary, 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 bsontype.Null: +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadNull() +	case bsontype.Undefined: +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadUndefined() +	default: +		return fmt.Errorf("cannot decode %v into an array", vrType) +	} + +	var elemsFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) ([]reflect.Value, error) +	switch val.Type().Elem() { +	case tE: +		elemsFunc = dvd.decodeD +	default: +		elemsFunc = dvd.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 +} + +// SliceDecodeValue is the ValueDecoderFunc for slice types. +// +// Deprecated: SliceDecodeValue is not registered by default. Use SliceCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) SliceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Kind() != reflect.Slice { +		return ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} +	} + +	switch vr.Type() { +	case bsontype.Array: +	case bsontype.Null: +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadNull() +	case bsontype.Type(0), bsontype.EmbeddedDocument: +		if val.Type().Elem() != tE { +			return fmt.Errorf("cannot decode document into %s", val.Type()) +		} +	default: +		return fmt.Errorf("cannot decode %v into a slice", vr.Type()) +	} + +	var elemsFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) ([]reflect.Value, error) +	switch val.Type().Elem() { +	case tE: +		dc.Ancestor = val.Type() +		elemsFunc = dvd.decodeD +	default: +		elemsFunc = dvd.decodeDefault +	} + +	elems, err := elemsFunc(dc, vr, val) +	if err != nil { +		return err +	} + +	if val.IsNil() { +		val.Set(reflect.MakeSlice(val.Type(), 0, len(elems))) +	} + +	val.SetLen(0) +	val.Set(reflect.Append(val, elems...)) + +	return nil +} + +// ValueUnmarshalerDecodeValue is the ValueDecoderFunc for ValueUnmarshaler implementations. +func (dvd DefaultValueDecoders) ValueUnmarshalerDecodeValue(dc DecodeContext, vr bsonrw.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 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 := bsonrw.Copier{}.CopyValueToBytes(vr) +	if err != nil { +		return err +	} + +	fn := val.Convert(tValueUnmarshaler).MethodByName("UnmarshalBSONValue") +	errVal := fn.Call([]reflect.Value{reflect.ValueOf(t), reflect.ValueOf(src)})[0] +	if !errVal.IsNil() { +		return errVal.Interface().(error) +	} +	return nil +} + +// UnmarshalerDecodeValue is the ValueDecoderFunc for Unmarshaler implementations. +func (dvd DefaultValueDecoders) UnmarshalerDecodeValue(dc DecodeContext, vr bsonrw.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 := bsonrw.Copier{}.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. +	} + +	fn := val.Convert(tUnmarshaler).MethodByName("UnmarshalBSON") +	errVal := fn.Call([]reflect.Value{reflect.ValueOf(src)})[0] +	if !errVal.IsNil() { +		return errVal.Interface().(error) +	} +	return nil +} + +// EmptyInterfaceDecodeValue is the ValueDecoderFunc for interface{}. +// +// Deprecated: EmptyInterfaceDecodeValue is not registered by default. Use EmptyInterfaceCodec.DecodeValue instead. +func (dvd DefaultValueDecoders) EmptyInterfaceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tEmpty { +		return ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: val} +	} + +	rtype, err := dc.LookupTypeMapEntry(vr.Type()) +	if err != nil { +		switch vr.Type() { +		case bsontype.EmbeddedDocument: +			if dc.Ancestor != nil { +				rtype = dc.Ancestor +				break +			} +			rtype = tD +		case bsontype.Null: +			val.Set(reflect.Zero(val.Type())) +			return vr.ReadNull() +		default: +			return err +		} +	} + +	decoder, err := dc.LookupDecoder(rtype) +	if err != nil { +		return err +	} + +	elem := reflect.New(rtype).Elem() +	err = decoder.DecodeValue(dc, vr, elem) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +// CoreDocumentDecodeValue is the ValueDecoderFunc for bsoncore.Document. +func (DefaultValueDecoders) CoreDocumentDecodeValue(dc DecodeContext, vr bsonrw.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 := bsonrw.Copier{}.AppendDocumentBytes(val.Interface().(bsoncore.Document), vr) +	val.Set(reflect.ValueOf(cdoc)) +	return err +} + +func (dvd DefaultValueDecoders) decodeDefault(dc DecodeContext, vr bsonrw.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() + +	decoder, err := dc.LookupDecoder(eType) +	if err != nil { +		return nil, err +	} +	eTypeDecoder, _ := decoder.(typeDecoder) + +	idx := 0 +	for { +		vr, err := ar.ReadValue() +		if err == bsonrw.ErrEOA { +			break +		} +		if err != nil { +			return nil, err +		} + +		elem, err := decodeTypeOrValueWithInfo(decoder, eTypeDecoder, dc, vr, eType, true) +		if err != nil { +			return nil, newDecodeError(strconv.Itoa(idx), err) +		} +		elems = append(elems, elem) +		idx++ +	} + +	return elems, nil +} + +func (dvd DefaultValueDecoders) readCodeWithScope(dc DecodeContext, vr bsonrw.ValueReader) (primitive.CodeWithScope, error) { +	var cws primitive.CodeWithScope + +	code, dr, err := vr.ReadCodeWithScope() +	if err != nil { +		return cws, err +	} + +	scope := reflect.New(tD).Elem() +	elems, err := dvd.decodeElemsFromDocumentReader(dc, dr) +	if err != nil { +		return cws, err +	} + +	scope.Set(reflect.MakeSlice(tD, 0, len(elems))) +	scope.Set(reflect.Append(scope, elems...)) + +	cws = primitive.CodeWithScope{ +		Code:  primitive.JavaScript(code), +		Scope: scope.Interface().(primitive.D), +	} +	return cws, nil +} + +func (dvd DefaultValueDecoders) codeWithScopeDecodeType(dc DecodeContext, vr bsonrw.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 primitive.CodeWithScope +	var err error +	switch vrType := vr.Type(); vrType { +	case bsontype.CodeWithScope: +		cws, err = dvd.readCodeWithScope(dc, vr) +	case bsontype.Null: +		err = vr.ReadNull() +	case bsontype.Undefined: +		err = vr.ReadUndefined() +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a primitive.CodeWithScope", vrType) +	} +	if err != nil { +		return emptyValue, err +	} + +	return reflect.ValueOf(cws), nil +} + +// CodeWithScopeDecodeValue is the ValueDecoderFunc for CodeWithScope. +func (dvd DefaultValueDecoders) CodeWithScopeDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tCodeWithScope { +		return ValueDecoderError{Name: "CodeWithScopeDecodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val} +	} + +	elem, err := dvd.codeWithScopeDecodeType(dc, vr, tCodeWithScope) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +func (dvd DefaultValueDecoders) decodeD(dc DecodeContext, vr bsonrw.ValueReader, _ reflect.Value) ([]reflect.Value, error) { +	switch vr.Type() { +	case bsontype.Type(0), bsontype.EmbeddedDocument: +	default: +		return nil, fmt.Errorf("cannot decode %v into a D", vr.Type()) +	} + +	dr, err := vr.ReadDocument() +	if err != nil { +		return nil, err +	} + +	return dvd.decodeElemsFromDocumentReader(dc, dr) +} + +func (DefaultValueDecoders) decodeElemsFromDocumentReader(dc DecodeContext, dr bsonrw.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 err == bsonrw.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(primitive.E{Key: key, Value: val.Interface()})) +	} + +	return elems, nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go new file mode 100644 index 000000000..6bdb43cb4 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go @@ -0,0 +1,766 @@ +// 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 bsoncodec + +import ( +	"encoding/json" +	"errors" +	"fmt" +	"math" +	"net/url" +	"reflect" +	"sync" +	"time" + +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +	"go.mongodb.org/mongo-driver/bson/primitive" +	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore" +) + +var defaultValueEncoders DefaultValueEncoders + +var bvwPool = bsonrw.NewBSONValueWriterPool() + +var errInvalidValue = errors.New("cannot encode invalid element") + +var sliceWriterPool = sync.Pool{ +	New: func() interface{} { +		sw := make(bsonrw.SliceWriter, 0) +		return &sw +	}, +} + +func encodeElement(ec EncodeContext, dw bsonrw.DocumentWriter, e primitive.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 +} + +// DefaultValueEncoders is a namespace type for the default ValueEncoders used +// when creating a registry. +type DefaultValueEncoders struct{} + +// RegisterDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with +// the provided RegistryBuilder. +func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) { +	if rb == nil { +		panic(errors.New("argument to RegisterDefaultEncoders must not be nil")) +	} +	rb. +		RegisterTypeEncoder(tByteSlice, defaultByteSliceCodec). +		RegisterTypeEncoder(tTime, defaultTimeCodec). +		RegisterTypeEncoder(tEmpty, defaultEmptyInterfaceCodec). +		RegisterTypeEncoder(tCoreArray, defaultArrayCodec). +		RegisterTypeEncoder(tOID, ValueEncoderFunc(dve.ObjectIDEncodeValue)). +		RegisterTypeEncoder(tDecimal, ValueEncoderFunc(dve.Decimal128EncodeValue)). +		RegisterTypeEncoder(tJSONNumber, ValueEncoderFunc(dve.JSONNumberEncodeValue)). +		RegisterTypeEncoder(tURL, ValueEncoderFunc(dve.URLEncodeValue)). +		RegisterTypeEncoder(tJavaScript, ValueEncoderFunc(dve.JavaScriptEncodeValue)). +		RegisterTypeEncoder(tSymbol, ValueEncoderFunc(dve.SymbolEncodeValue)). +		RegisterTypeEncoder(tBinary, ValueEncoderFunc(dve.BinaryEncodeValue)). +		RegisterTypeEncoder(tUndefined, ValueEncoderFunc(dve.UndefinedEncodeValue)). +		RegisterTypeEncoder(tDateTime, ValueEncoderFunc(dve.DateTimeEncodeValue)). +		RegisterTypeEncoder(tNull, ValueEncoderFunc(dve.NullEncodeValue)). +		RegisterTypeEncoder(tRegex, ValueEncoderFunc(dve.RegexEncodeValue)). +		RegisterTypeEncoder(tDBPointer, ValueEncoderFunc(dve.DBPointerEncodeValue)). +		RegisterTypeEncoder(tTimestamp, ValueEncoderFunc(dve.TimestampEncodeValue)). +		RegisterTypeEncoder(tMinKey, ValueEncoderFunc(dve.MinKeyEncodeValue)). +		RegisterTypeEncoder(tMaxKey, ValueEncoderFunc(dve.MaxKeyEncodeValue)). +		RegisterTypeEncoder(tCoreDocument, ValueEncoderFunc(dve.CoreDocumentEncodeValue)). +		RegisterTypeEncoder(tCodeWithScope, ValueEncoderFunc(dve.CodeWithScopeEncodeValue)). +		RegisterDefaultEncoder(reflect.Bool, ValueEncoderFunc(dve.BooleanEncodeValue)). +		RegisterDefaultEncoder(reflect.Int, ValueEncoderFunc(dve.IntEncodeValue)). +		RegisterDefaultEncoder(reflect.Int8, ValueEncoderFunc(dve.IntEncodeValue)). +		RegisterDefaultEncoder(reflect.Int16, ValueEncoderFunc(dve.IntEncodeValue)). +		RegisterDefaultEncoder(reflect.Int32, ValueEncoderFunc(dve.IntEncodeValue)). +		RegisterDefaultEncoder(reflect.Int64, ValueEncoderFunc(dve.IntEncodeValue)). +		RegisterDefaultEncoder(reflect.Uint, defaultUIntCodec). +		RegisterDefaultEncoder(reflect.Uint8, defaultUIntCodec). +		RegisterDefaultEncoder(reflect.Uint16, defaultUIntCodec). +		RegisterDefaultEncoder(reflect.Uint32, defaultUIntCodec). +		RegisterDefaultEncoder(reflect.Uint64, defaultUIntCodec). +		RegisterDefaultEncoder(reflect.Float32, ValueEncoderFunc(dve.FloatEncodeValue)). +		RegisterDefaultEncoder(reflect.Float64, ValueEncoderFunc(dve.FloatEncodeValue)). +		RegisterDefaultEncoder(reflect.Array, ValueEncoderFunc(dve.ArrayEncodeValue)). +		RegisterDefaultEncoder(reflect.Map, defaultMapCodec). +		RegisterDefaultEncoder(reflect.Slice, defaultSliceCodec). +		RegisterDefaultEncoder(reflect.String, defaultStringCodec). +		RegisterDefaultEncoder(reflect.Struct, newDefaultStructCodec()). +		RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec()). +		RegisterHookEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)). +		RegisterHookEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)). +		RegisterHookEncoder(tProxy, ValueEncoderFunc(dve.ProxyEncodeValue)) +} + +// BooleanEncodeValue is the ValueEncoderFunc for bool types. +func (dve DefaultValueEncoders) BooleanEncodeValue(ectx EncodeContext, vw bsonrw.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 (dve DefaultValueEncoders) IntEncodeValue(ec EncodeContext, vw bsonrw.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, +	} +} + +// UintEncodeValue is the ValueEncoderFunc for uint types. +// +// Deprecated: UintEncodeValue is not registered by default. Use UintCodec.EncodeValue instead. +func (dve DefaultValueEncoders) UintEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	switch val.Kind() { +	case reflect.Uint8, reflect.Uint16: +		return vw.WriteInt32(int32(val.Uint())) +	case reflect.Uint, reflect.Uint32, reflect.Uint64: +		u64 := val.Uint() +		if ec.MinSize && u64 <= math.MaxInt32 { +			return vw.WriteInt32(int32(u64)) +		} +		if u64 > math.MaxInt64 { +			return fmt.Errorf("%d overflows int64", u64) +		} +		return vw.WriteInt64(int64(u64)) +	} + +	return ValueEncoderError{ +		Name:     "UintEncodeValue", +		Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, +		Received: val, +	} +} + +// FloatEncodeValue is the ValueEncoderFunc for float types. +func (dve DefaultValueEncoders) FloatEncodeValue(ec EncodeContext, vw bsonrw.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} +} + +// StringEncodeValue is the ValueEncoderFunc for string types. +// +// Deprecated: StringEncodeValue is not registered by default. Use StringCodec.EncodeValue instead. +func (dve DefaultValueEncoders) StringEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if val.Kind() != reflect.String { +		return ValueEncoderError{ +			Name:     "StringEncodeValue", +			Kinds:    []reflect.Kind{reflect.String}, +			Received: val, +		} +	} + +	return vw.WriteString(val.String()) +} + +// ObjectIDEncodeValue is the ValueEncoderFunc for primitive.ObjectID. +func (dve DefaultValueEncoders) ObjectIDEncodeValue(ec EncodeContext, vw bsonrw.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().(primitive.ObjectID)) +} + +// Decimal128EncodeValue is the ValueEncoderFunc for primitive.Decimal128. +func (dve DefaultValueEncoders) Decimal128EncodeValue(ec EncodeContext, vw bsonrw.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().(primitive.Decimal128)) +} + +// JSONNumberEncodeValue is the ValueEncoderFunc for json.Number. +func (dve DefaultValueEncoders) JSONNumberEncodeValue(ec EncodeContext, vw bsonrw.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 dve.IntEncodeValue(ec, vw, reflect.ValueOf(i64)) +	} + +	f64, err := jsnum.Float64() +	if err != nil { +		return err +	} + +	return dve.FloatEncodeValue(ec, vw, reflect.ValueOf(f64)) +} + +// URLEncodeValue is the ValueEncoderFunc for url.URL. +func (dve DefaultValueEncoders) URLEncodeValue(ec EncodeContext, vw bsonrw.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()) +} + +// TimeEncodeValue is the ValueEncoderFunc for time.TIme. +// +// Deprecated: TimeEncodeValue is not registered by default. Use TimeCodec.EncodeValue instead. +func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Type() != tTime { +		return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val} +	} +	tt := val.Interface().(time.Time) +	dt := primitive.NewDateTimeFromTime(tt) +	return vw.WriteDateTime(int64(dt)) +} + +// ByteSliceEncodeValue is the ValueEncoderFunc for []byte. +// +// Deprecated: ByteSliceEncodeValue is not registered by default. Use ByteSliceCodec.EncodeValue instead. +func (dve DefaultValueEncoders) ByteSliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Type() != tByteSlice { +		return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val} +	} +	if val.IsNil() { +		return vw.WriteNull() +	} +	return vw.WriteBinary(val.Interface().([]byte)) +} + +// MapEncodeValue is the ValueEncoderFunc for map[string]* types. +// +// Deprecated: MapEncodeValue is not registered by default. Use MapCodec.EncodeValue instead. +func (dve DefaultValueEncoders) MapEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String { +		return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} +	} + +	if val.IsNil() { +		// If we have a nill map but we can't WriteNull, that means we're probably trying to encode +		// to a TopLevel document. We can't currently tell if this is what actually happened, but if +		// there's a deeper underlying problem, the error will also be returned from WriteDocument, +		// so just continue. The operations on a map reflection value are valid, so we can call +		// MapKeys within mapEncodeValue without a problem. +		err := vw.WriteNull() +		if err == nil { +			return nil +		} +	} + +	dw, err := vw.WriteDocument() +	if err != nil { +		return err +	} + +	return dve.mapEncodeValue(ec, dw, val, nil) +} + +// mapEncodeValue handles encoding of the values of a map. The collisionFn returns +// true if the provided key exists, this is mainly used for inline maps in the +// struct codec. +func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error { + +	elemType := val.Type().Elem() +	encoder, err := ec.LookupEncoder(elemType) +	if err != nil && elemType.Kind() != reflect.Interface { +		return err +	} + +	keys := val.MapKeys() +	for _, key := range keys { +		if collisionFn != nil && collisionFn(key.String()) { +			return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key) +		} + +		currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.MapIndex(key)) +		if lookupErr != nil && lookupErr != errInvalidValue { +			return lookupErr +		} + +		vw, err := dw.WriteDocumentElement(key.String()) +		if err != nil { +			return err +		} + +		if lookupErr == errInvalidValue { +			err = vw.WriteNull() +			if err != nil { +				return err +			} +			continue +		} + +		err = currEncoder.EncodeValue(ec, vw, currVal) +		if err != nil { +			return err +		} +	} + +	return dw.WriteDocumentEnd() +} + +// ArrayEncodeValue is the ValueEncoderFunc for array types. +func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.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 []primitive.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().(primitive.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 := dve.lookupElementEncoder(ec, encoder, val.Index(idx)) +		if lookupErr != nil && lookupErr != errInvalidValue { +			return lookupErr +		} + +		vw, err := aw.WriteArrayElement() +		if err != nil { +			return err +		} + +		if 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() +} + +// SliceEncodeValue is the ValueEncoderFunc for slice types. +// +// Deprecated: SliceEncodeValue is not registered by default. Use SliceCodec.EncodeValue instead. +func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Kind() != reflect.Slice { +		return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} +	} + +	if val.IsNil() { +		return vw.WriteNull() +	} + +	// If we have a []primitive.E we want to treat it as a document instead of as an array. +	if val.Type().ConvertibleTo(tD) { +		d := val.Convert(tD).Interface().(primitive.D) + +		dw, err := vw.WriteDocument() +		if err != nil { +			return err +		} + +		for _, e := range d { +			err = encodeElement(ec, dw, e) +			if err != nil { +				return err +			} +		} + +		return dw.WriteDocumentEnd() +	} + +	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 := dve.lookupElementEncoder(ec, encoder, val.Index(idx)) +		if lookupErr != nil && lookupErr != errInvalidValue { +			return lookupErr +		} + +		vw, err := aw.WriteArrayElement() +		if err != nil { +			return err +		} + +		if 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 (dve DefaultValueEncoders) 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 +} + +// EmptyInterfaceEncodeValue is the ValueEncoderFunc for interface{}. +// +// Deprecated: EmptyInterfaceEncodeValue is not registered by default. Use EmptyInterfaceCodec.EncodeValue instead. +func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw bsonrw.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()) +} + +// ValueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations. +func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(ec EncodeContext, vw bsonrw.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} +	} + +	fn := val.Convert(tValueMarshaler).MethodByName("MarshalBSONValue") +	returns := fn.Call(nil) +	if !returns[2].IsNil() { +		return returns[2].Interface().(error) +	} +	t, data := returns[0].Interface().(bsontype.Type), returns[1].Interface().([]byte) +	return bsonrw.Copier{}.CopyValueFromBytes(vw, t, data) +} + +// MarshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations. +func (dve DefaultValueEncoders) MarshalerEncodeValue(ec EncodeContext, vw bsonrw.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} +	} + +	fn := val.Convert(tMarshaler).MethodByName("MarshalBSON") +	returns := fn.Call(nil) +	if !returns[1].IsNil() { +		return returns[1].Interface().(error) +	} +	data := returns[0].Interface().([]byte) +	return bsonrw.Copier{}.CopyValueFromBytes(vw, bsontype.EmbeddedDocument, data) +} + +// ProxyEncodeValue is the ValueEncoderFunc for Proxy implementations. +func (dve DefaultValueEncoders) ProxyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	// Either val or a pointer to val must implement Proxy +	switch { +	case !val.IsValid(): +		return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val} +	case val.Type().Implements(tProxy): +		// If Proxy is implemented on a concrete type, make sure that val isn't a nil pointer +		if isImplementationNil(val, tProxy) { +			return vw.WriteNull() +		} +	case reflect.PtrTo(val.Type()).Implements(tProxy) && val.CanAddr(): +		val = val.Addr() +	default: +		return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val} +	} + +	fn := val.Convert(tProxy).MethodByName("ProxyBSON") +	returns := fn.Call(nil) +	if !returns[1].IsNil() { +		return returns[1].Interface().(error) +	} +	data := returns[0] +	var encoder ValueEncoder +	var err error +	if data.Elem().IsValid() { +		encoder, err = ec.LookupEncoder(data.Elem().Type()) +	} else { +		encoder, err = ec.LookupEncoder(nil) +	} +	if err != nil { +		return err +	} +	return encoder.EncodeValue(ec, vw, data.Elem()) +} + +// JavaScriptEncodeValue is the ValueEncoderFunc for the primitive.JavaScript type. +func (DefaultValueEncoders) JavaScriptEncodeValue(ectx EncodeContext, vw bsonrw.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 primitive.Symbol type. +func (DefaultValueEncoders) SymbolEncodeValue(ectx EncodeContext, vw bsonrw.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 (DefaultValueEncoders) BinaryEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Type() != tBinary { +		return ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val} +	} +	b := val.Interface().(primitive.Binary) + +	return vw.WriteBinaryWithSubtype(b.Data, b.Subtype) +} + +// UndefinedEncodeValue is the ValueEncoderFunc for Undefined. +func (DefaultValueEncoders) UndefinedEncodeValue(ec EncodeContext, vw bsonrw.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 (DefaultValueEncoders) DateTimeEncodeValue(ec EncodeContext, vw bsonrw.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 (DefaultValueEncoders) NullEncodeValue(ec EncodeContext, vw bsonrw.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 (DefaultValueEncoders) RegexEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Type() != tRegex { +		return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val} +	} + +	regex := val.Interface().(primitive.Regex) + +	return vw.WriteRegex(regex.Pattern, regex.Options) +} + +// DBPointerEncodeValue is the ValueEncoderFunc for DBPointer. +func (DefaultValueEncoders) DBPointerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Type() != tDBPointer { +		return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val} +	} + +	dbp := val.Interface().(primitive.DBPointer) + +	return vw.WriteDBPointer(dbp.DB, dbp.Pointer) +} + +// TimestampEncodeValue is the ValueEncoderFunc for Timestamp. +func (DefaultValueEncoders) TimestampEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Type() != tTimestamp { +		return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val} +	} + +	ts := val.Interface().(primitive.Timestamp) + +	return vw.WriteTimestamp(ts.T, ts.I) +} + +// MinKeyEncodeValue is the ValueEncoderFunc for MinKey. +func (DefaultValueEncoders) MinKeyEncodeValue(ec EncodeContext, vw bsonrw.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 (DefaultValueEncoders) MaxKeyEncodeValue(ec EncodeContext, vw bsonrw.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 (DefaultValueEncoders) CoreDocumentEncodeValue(ec EncodeContext, vw bsonrw.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 bsonrw.Copier{}.CopyDocumentFromBytes(vw, cdoc) +} + +// CodeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope. +func (dve DefaultValueEncoders) CodeWithScopeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Type() != tCodeWithScope { +		return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val} +	} + +	cws := val.Interface().(primitive.CodeWithScope) + +	dw, err := vw.WriteCodeWithScope(string(cws.Code)) +	if err != nil { +		return err +	} + +	sw := sliceWriterPool.Get().(*bsonrw.SliceWriter) +	defer sliceWriterPool.Put(sw) +	*sw = (*sw)[:0] + +	scopeVW := bvwPool.Get(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 = bsonrw.Copier{}.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/bson/bsoncodec/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go new file mode 100644 index 000000000..5f903ebea --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go @@ -0,0 +1,90 @@ +// Copyright (C) MongoDB, Inc. 2022-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 bsoncodec provides a system for encoding values to BSON representations and decoding +// values from BSON representations. This package considers both binary BSON and ExtendedJSON as +// BSON representations. The types in this package enable a flexible system for handling this +// encoding and decoding. +// +// The codec system is composed of two parts: +// +// 1) ValueEncoders and ValueDecoders 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. +// +// # ValueEncoders and ValueDecoders +// +// The ValueEncoder interface is implemented by types that can encode a provided Go type to BSON. +// The value to encode is provided as a reflect.Value and a bsonrw.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. +// +// The ValueDecoder interface is the inverse of the ValueEncoder. 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. +// +// # Registry and RegistryBuilder +// +// A Registry is an immutable store for ValueEncoders, ValueDecoders, and a type map. See the Registry type +// documentation for examples of registering various custom encoders and decoders. A Registry can be constructed using a +// RegistryBuilder, which handles three main types of codecs: +// +// 1. Type encoders/decoders - These can be registered using the RegisterTypeEncoder and RegisterTypeDecoder methods. +// The registered codec will be invoked when encoding/decoding a value whose type matches the registered type exactly. +// If the registered type is an interface, the codec will be invoked when encoding or decoding values whose type is the +// interface, but not for values with concrete types that implement the interface. +// +// 2. Hook encoders/decoders - These can be registered using the RegisterHookEncoder and RegisterHookDecoder methods. +// These methods only accept interface types and the registered codecs will be invoked when encoding or decoding values +// whose types implement the interface. An example of a hook defined by the driver is bson.Marshaler. The driver will +// call the MarshalBSON method for any value whose type implements bson.Marshaler, regardless of the value's concrete +// type. +// +// 3. Type map entries - This can be used to associate a BSON type with a Go type. These type associations are used when +// decoding into a bson.D/bson.M or a struct field of type interface{}. For example, by default, BSON int32 and int64 +// values decode as Go int32 and int64 instances, respectively, when decoding into a bson.D. The following code would +// change the behavior so these values decode as Go int instances instead: +// +//	intType := reflect.TypeOf(int(0)) +//	registryBuilder.RegisterTypeMapEntry(bsontype.Int32, intType).RegisterTypeMapEntry(bsontype.Int64, intType) +// +// 4. Kind encoder/decoders - These can be registered using the RegisterDefaultEncoder and RegisterDefaultDecoder +// methods. The registered codec will be invoked when encoding or decoding values whose reflect.Kind matches the +// registered reflect.Kind as long as the value's type doesn't match a registered type or hook encoder/decoder first. +// These methods should be used to change the behavior for all values for a specific kind. +// +// # Registry Lookup Procedure +// +// When looking up an encoder in a Registry, the precedence rules are as follows: +// +// 1. A type encoder registered for the exact type of the value. +// +// 2. A hook encoder registered for an interface that is implemented by the value or by a pointer to the value. If the +// value matches multiple hooks (e.g. the type implements bsoncodec.Marshaler and bsoncodec.ValueMarshaler), the first +// one registered will be selected. Note that registries constructed using bson.NewRegistryBuilder have driver-defined +// hooks registered for the bsoncodec.Marshaler, bsoncodec.ValueMarshaler, and bsoncodec.Proxy interfaces, so those +// will take precedence over any new hooks. +// +// 3. A kind encoder registered for the value's kind. +// +// If all of these lookups fail to find an encoder, an error of type ErrNoEncoder is returned. The same precedence +// rules apply for decoders, with the exception that an error of type ErrNoDecoder will be returned if no decoder is +// found. +// +// # DefaultValueEncoders and DefaultValueDecoders +// +// The DefaultValueEncoders and DefaultValueDecoders types provide a full set of ValueEncoders and +// ValueDecoders for handling a wide range of Go types, including all of the types within the +// primitive package. To make registering these codecs easier, a helper method on each type is +// provided. For the DefaultValueEncoders type the method is called RegisterDefaultEncoders and for +// the DefaultValueDecoders type the method is called RegisterDefaultDecoders, this method also +// handles registering type map entries for each BSON type. +package bsoncodec diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go new file mode 100644 index 000000000..eda417cff --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go @@ -0,0 +1,147 @@ +// 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 bsoncodec + +import ( +	"reflect" + +	"go.mongodb.org/mongo-driver/bson/bsonoptions" +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +	"go.mongodb.org/mongo-driver/bson/primitive" +) + +// EmptyInterfaceCodec is the Codec used for interface{} values. +type EmptyInterfaceCodec struct { +	DecodeBinaryAsSlice bool +} + +var ( +	defaultEmptyInterfaceCodec = NewEmptyInterfaceCodec() + +	_ ValueCodec  = defaultEmptyInterfaceCodec +	_ typeDecoder = defaultEmptyInterfaceCodec +) + +// NewEmptyInterfaceCodec returns a EmptyInterfaceCodec with options opts. +func NewEmptyInterfaceCodec(opts ...*bsonoptions.EmptyInterfaceCodecOptions) *EmptyInterfaceCodec { +	interfaceOpt := bsonoptions.MergeEmptyInterfaceCodecOptions(opts...) + +	codec := EmptyInterfaceCodec{} +	if interfaceOpt.DecodeBinaryAsSlice != nil { +		codec.DecodeBinaryAsSlice = *interfaceOpt.DecodeBinaryAsSlice +	} +	return &codec +} + +// EncodeValue is the ValueEncoderFunc for interface{}. +func (eic EmptyInterfaceCodec) EncodeValue(ec EncodeContext, vw bsonrw.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 bsontype.Type) (reflect.Type, error) { +	isDocument := valueType == bsontype.Type(0) || valueType == bsontype.EmbeddedDocument +	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 +		} +		if dc.Ancestor != nil { +			// Using ancestor information rather than looking up the type map entry forces consistent decoding. +			// If we're decoding into a bson.D, subdocuments should also be decoded as bson.D, even if a type map entry +			// has been registered. +			return dc.Ancestor, 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 bsontype.Type(0) or bsontype.EmbeddedDocument, +		// depending on the original valueType. +		var lookupType bsontype.Type +		switch valueType { +		case bsontype.Type(0): +			lookupType = bsontype.EmbeddedDocument +		case bsontype.EmbeddedDocument: +			lookupType = bsontype.Type(0) +		} + +		rtype, err = dc.LookupTypeMapEntry(lookupType) +		if err == nil { +			return rtype, nil +		} +	} + +	return nil, err +} + +func (eic EmptyInterfaceCodec) decodeType(dc DecodeContext, vr bsonrw.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 bsontype.Null: +			return reflect.Zero(t), vr.ReadNull() +		default: +			return emptyValue, err +		} +	} + +	decoder, err := dc.LookupDecoder(rtype) +	if err != nil { +		return emptyValue, err +	} + +	elem, err := decodeTypeOrValue(decoder, dc, vr, rtype) +	if err != nil { +		return emptyValue, err +	} + +	if eic.DecodeBinaryAsSlice && rtype == tBinary { +		binElem := elem.Interface().(primitive.Binary) +		if binElem.Subtype == bsontype.BinaryGeneric || binElem.Subtype == bsontype.BinaryBinaryOld { +			elem = reflect.ValueOf(binElem.Data) +		} +	} + +	return elem, nil +} + +// DecodeValue is the ValueDecoderFunc for interface{}. +func (eic EmptyInterfaceCodec) DecodeValue(dc DecodeContext, vr bsonrw.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/bson/bsoncodec/map_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go new file mode 100644 index 000000000..e1fbef9c6 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go @@ -0,0 +1,309 @@ +// 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 bsoncodec + +import ( +	"encoding" +	"fmt" +	"reflect" +	"strconv" + +	"go.mongodb.org/mongo-driver/bson/bsonoptions" +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +) + +var defaultMapCodec = NewMapCodec() + +// MapCodec is the Codec used for map values. +type MapCodec struct { +	DecodeZerosMap         bool +	EncodeNilAsEmpty       bool +	EncodeKeysWithStringer bool +} + +var _ ValueCodec = &MapCodec{} + +// KeyMarshaler is the interface implemented by an object that can marshal itself into a string key. +// This applies to types used as map keys and is similar to encoding.TextMarshaler. +type KeyMarshaler interface { +	MarshalKey() (key string, err error) +} + +// KeyUnmarshaler is the interface implemented by an object that can unmarshal a string representation +// of itself. This applies to types used as map keys and is similar to encoding.TextUnmarshaler. +// +// UnmarshalKey must be able to decode the form generated by MarshalKey. +// UnmarshalKey must copy the text if it wishes to retain the text +// after returning. +type KeyUnmarshaler interface { +	UnmarshalKey(key string) error +} + +// NewMapCodec returns a MapCodec with options opts. +func NewMapCodec(opts ...*bsonoptions.MapCodecOptions) *MapCodec { +	mapOpt := bsonoptions.MergeMapCodecOptions(opts...) + +	codec := MapCodec{} +	if mapOpt.DecodeZerosMap != nil { +		codec.DecodeZerosMap = *mapOpt.DecodeZerosMap +	} +	if mapOpt.EncodeNilAsEmpty != nil { +		codec.EncodeNilAsEmpty = *mapOpt.EncodeNilAsEmpty +	} +	if mapOpt.EncodeKeysWithStringer != nil { +		codec.EncodeKeysWithStringer = *mapOpt.EncodeKeysWithStringer +	} +	return &codec +} + +// EncodeValue is the ValueEncoder for map[*]* types. +func (mc *MapCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Kind() != reflect.Map { +		return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} +	} + +	if val.IsNil() && !mc.EncodeNilAsEmpty { +		// If we have a nil map but we can't WriteNull, that means we're probably trying to encode +		// to a TopLevel document. We can't currently tell if this is what actually happened, but if +		// there's a deeper underlying problem, the error will also be returned from WriteDocument, +		// so just continue. The operations on a map reflection value are valid, so we can call +		// MapKeys within mapEncodeValue without a problem. +		err := vw.WriteNull() +		if err == nil { +			return nil +		} +	} + +	dw, err := vw.WriteDocument() +	if err != nil { +		return err +	} + +	return mc.mapEncodeValue(ec, dw, val, nil) +} + +// mapEncodeValue handles encoding of the values of a map. The collisionFn returns +// true if the provided key exists, this is mainly used for inline maps in the +// struct codec. +func (mc *MapCodec) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error { + +	elemType := val.Type().Elem() +	encoder, err := ec.LookupEncoder(elemType) +	if err != nil && elemType.Kind() != reflect.Interface { +		return err +	} + +	keys := val.MapKeys() +	for _, key := range keys { +		keyStr, err := mc.encodeKey(key) +		if err != nil { +			return err +		} + +		if collisionFn != nil && collisionFn(keyStr) { +			return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key) +		} + +		currEncoder, currVal, lookupErr := defaultValueEncoders.lookupElementEncoder(ec, encoder, val.MapIndex(key)) +		if lookupErr != nil && lookupErr != errInvalidValue { +			return lookupErr +		} + +		vw, err := dw.WriteDocumentElement(keyStr) +		if err != nil { +			return err +		} + +		if lookupErr == errInvalidValue { +			err = vw.WriteNull() +			if err != nil { +				return err +			} +			continue +		} + +		err = currEncoder.EncodeValue(ec, vw, currVal) +		if err != nil { +			return err +		} +	} + +	return dw.WriteDocumentEnd() +} + +// DecodeValue is the ValueDecoder for map[string/decimal]* types. +func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if val.Kind() != reflect.Map || (!val.CanSet() && val.IsNil()) { +		return ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val} +	} + +	switch vrType := vr.Type(); vrType { +	case bsontype.Type(0), bsontype.EmbeddedDocument: +	case bsontype.Null: +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadNull() +	case bsontype.Undefined: +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadUndefined() +	default: +		return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type()) +	} + +	dr, err := vr.ReadDocument() +	if err != nil { +		return err +	} + +	if val.IsNil() { +		val.Set(reflect.MakeMap(val.Type())) +	} + +	if val.Len() > 0 && mc.DecodeZerosMap { +		clearMap(val) +	} + +	eType := val.Type().Elem() +	decoder, err := dc.LookupDecoder(eType) +	if err != nil { +		return err +	} +	eTypeDecoder, _ := decoder.(typeDecoder) + +	if eType == tEmpty { +		dc.Ancestor = val.Type() +	} + +	keyType := val.Type().Key() + +	for { +		key, vr, err := dr.ReadElement() +		if err == bsonrw.ErrEOD { +			break +		} +		if err != nil { +			return err +		} + +		k, err := mc.decodeKey(key, keyType) +		if err != nil { +			return err +		} + +		elem, err := decodeTypeOrValueWithInfo(decoder, eTypeDecoder, dc, vr, eType, true) +		if err != nil { +			return newDecodeError(key, err) +		} + +		val.SetMapIndex(k, elem) +	} +	return nil +} + +func clearMap(m reflect.Value) { +	var none reflect.Value +	for _, k := range m.MapKeys() { +		m.SetMapIndex(k, none) +	} +} + +func (mc *MapCodec) encodeKey(val reflect.Value) (string, error) { +	if mc.EncodeKeysWithStringer { +		return fmt.Sprint(val), nil +	} + +	// keys of any string type are used directly +	if val.Kind() == reflect.String { +		return val.String(), nil +	} +	// KeyMarshalers are marshaled +	if km, ok := val.Interface().(KeyMarshaler); ok { +		if val.Kind() == reflect.Ptr && val.IsNil() { +			return "", nil +		} +		buf, err := km.MarshalKey() +		if err == nil { +			return buf, nil +		} +		return "", err +	} +	// keys implement encoding.TextMarshaler are marshaled. +	if km, ok := val.Interface().(encoding.TextMarshaler); ok { +		if val.Kind() == reflect.Ptr && val.IsNil() { +			return "", nil +		} + +		buf, err := km.MarshalText() +		if err != nil { +			return "", err +		} + +		return string(buf), nil +	} + +	switch val.Kind() { +	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: +		return strconv.FormatInt(val.Int(), 10), nil +	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: +		return strconv.FormatUint(val.Uint(), 10), nil +	} +	return "", fmt.Errorf("unsupported key type: %v", val.Type()) +} + +var keyUnmarshalerType = reflect.TypeOf((*KeyUnmarshaler)(nil)).Elem() +var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + +func (mc *MapCodec) decodeKey(key string, keyType reflect.Type) (reflect.Value, error) { +	keyVal := reflect.ValueOf(key) +	var err error +	switch { +	// First, if EncodeKeysWithStringer is not enabled, try to decode withKeyUnmarshaler +	case !mc.EncodeKeysWithStringer && reflect.PtrTo(keyType).Implements(keyUnmarshalerType): +		keyVal = reflect.New(keyType) +		v := keyVal.Interface().(KeyUnmarshaler) +		err = v.UnmarshalKey(key) +		keyVal = keyVal.Elem() +	// Try to decode encoding.TextUnmarshalers. +	case reflect.PtrTo(keyType).Implements(textUnmarshalerType): +		keyVal = reflect.New(keyType) +		v := keyVal.Interface().(encoding.TextUnmarshaler) +		err = v.UnmarshalText([]byte(key)) +		keyVal = keyVal.Elem() +	// Otherwise, go to type specific behavior +	default: +		switch keyType.Kind() { +		case reflect.String: +			keyVal = reflect.ValueOf(key).Convert(keyType) +		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: +			n, parseErr := strconv.ParseInt(key, 10, 64) +			if parseErr != nil || reflect.Zero(keyType).OverflowInt(n) { +				err = fmt.Errorf("failed to unmarshal number key %v", key) +			} +			keyVal = reflect.ValueOf(n).Convert(keyType) +		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: +			n, parseErr := strconv.ParseUint(key, 10, 64) +			if parseErr != nil || reflect.Zero(keyType).OverflowUint(n) { +				err = fmt.Errorf("failed to unmarshal number key %v", key) +				break +			} +			keyVal = reflect.ValueOf(n).Convert(keyType) +		case reflect.Float32, reflect.Float64: +			if mc.EncodeKeysWithStringer { +				parsed, err := strconv.ParseFloat(key, 64) +				if err != nil { +					return keyVal, fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %v", keyType.Kind(), err) +				} +				keyVal = reflect.ValueOf(parsed) +				break +			} +			fallthrough +		default: +			return keyVal, fmt.Errorf("unsupported key type: %v", keyType) +		} +	} +	return keyVal, err +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/mode.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/mode.go new file mode 100644 index 000000000..fbd9f0a9e --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/mode.go @@ -0,0 +1,65 @@ +// 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 bsoncodec + +import "fmt" + +type mode int + +const ( +	_ mode = iota +	mTopLevel +	mDocument +	mArray +	mValue +	mElement +	mCodeWithScope +	mSpacer +) + +func (m mode) String() string { +	var str string + +	switch m { +	case mTopLevel: +		str = "TopLevel" +	case mDocument: +		str = "DocumentMode" +	case mArray: +		str = "ArrayMode" +	case mValue: +		str = "ValueMode" +	case mElement: +		str = "ElementMode" +	case mCodeWithScope: +		str = "CodeWithScopeMode" +	case mSpacer: +		str = "CodeWithScopeSpacerFrame" +	default: +		str = "UnknownMode" +	} + +	return str +} + +// TransitionError is an error returned when an invalid progressing a +// ValueReader or ValueWriter state machine occurs. +type TransitionError struct { +	parent      mode +	current     mode +	destination mode +} + +func (te TransitionError) Error() string { +	if te.destination == mode(0) { +		return fmt.Sprintf("invalid state transition: cannot read/write value while in %s", te.current) +	} +	if te.parent == mode(0) { +		return fmt.Sprintf("invalid state transition: %s -> %s", te.current, te.destination) +	} +	return fmt.Sprintf("invalid state transition: %s -> %s; parent %s", te.current, te.destination, te.parent) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go new file mode 100644 index 000000000..616a3e701 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go @@ -0,0 +1,109 @@ +// 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 bsoncodec + +import ( +	"reflect" +	"sync" + +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +) + +var _ ValueEncoder = &PointerCodec{} +var _ ValueDecoder = &PointerCodec{} + +// PointerCodec is the Codec used for pointers. +type PointerCodec struct { +	ecache map[reflect.Type]ValueEncoder +	dcache map[reflect.Type]ValueDecoder +	l      sync.RWMutex +} + +// NewPointerCodec returns a PointerCodec that has been initialized. +func NewPointerCodec() *PointerCodec { +	return &PointerCodec{ +		ecache: make(map[reflect.Type]ValueEncoder), +		dcache: make(map[reflect.Type]ValueDecoder), +	} +} + +// EncodeValue handles encoding a pointer by either encoding it to BSON Null if the pointer is nil +// or looking up an encoder for the type of value the pointer points to. +func (pc *PointerCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if val.Kind() != reflect.Ptr { +		if !val.IsValid() { +			return vw.WriteNull() +		} +		return ValueEncoderError{Name: "PointerCodec.EncodeValue", Kinds: []reflect.Kind{reflect.Ptr}, Received: val} +	} + +	if val.IsNil() { +		return vw.WriteNull() +	} + +	pc.l.RLock() +	enc, ok := pc.ecache[val.Type()] +	pc.l.RUnlock() +	if ok { +		if enc == nil { +			return ErrNoEncoder{Type: val.Type()} +		} +		return enc.EncodeValue(ec, vw, val.Elem()) +	} + +	enc, err := ec.LookupEncoder(val.Type().Elem()) +	pc.l.Lock() +	pc.ecache[val.Type()] = enc +	pc.l.Unlock() +	if err != nil { +		return err +	} + +	return enc.EncodeValue(ec, vw, val.Elem()) +} + +// DecodeValue handles decoding a pointer by looking up a decoder for the type it points to and +// using that to decode. If the BSON value is Null, this method will set the pointer to nil. +func (pc *PointerCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Kind() != reflect.Ptr { +		return ValueDecoderError{Name: "PointerCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Ptr}, Received: val} +	} + +	if vr.Type() == bsontype.Null { +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadNull() +	} +	if vr.Type() == bsontype.Undefined { +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadUndefined() +	} + +	if val.IsNil() { +		val.Set(reflect.New(val.Type().Elem())) +	} + +	pc.l.RLock() +	dec, ok := pc.dcache[val.Type()] +	pc.l.RUnlock() +	if ok { +		if dec == nil { +			return ErrNoDecoder{Type: val.Type()} +		} +		return dec.DecodeValue(dc, vr, val.Elem()) +	} + +	dec, err := dc.LookupDecoder(val.Type().Elem()) +	pc.l.Lock() +	pc.dcache[val.Type()] = dec +	pc.l.Unlock() +	if err != nil { +		return err +	} + +	return dec.DecodeValue(dc, vr, val.Elem()) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/proxy.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/proxy.go new file mode 100644 index 000000000..4cf2b01ab --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/proxy.go @@ -0,0 +1,14 @@ +// 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 bsoncodec + +// Proxy is an interface implemented by types that cannot themselves be directly encoded. Types +// that implement this interface with have ProxyBSON called during the encoding process and that +// value will be encoded in place for the implementer. +type Proxy interface { +	ProxyBSON() (interface{}, error) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go new file mode 100644 index 000000000..80644023c --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go @@ -0,0 +1,469 @@ +// 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 bsoncodec + +import ( +	"errors" +	"fmt" +	"reflect" +	"sync" + +	"go.mongodb.org/mongo-driver/bson/bsontype" +) + +// ErrNilType is returned when nil is passed to either LookupEncoder or LookupDecoder. +var ErrNilType = errors.New("cannot perform a decoder lookup on <nil>") + +// ErrNotPointer is returned when a non-pointer type is provided to LookupDecoder. +var ErrNotPointer = errors.New("non-pointer provided to LookupDecoder") + +// ErrNoEncoder is returned when there wasn't an encoder available for a type. +type ErrNoEncoder struct { +	Type reflect.Type +} + +func (ene ErrNoEncoder) Error() string { +	if ene.Type == nil { +		return "no encoder found for <nil>" +	} +	return "no encoder found for " + ene.Type.String() +} + +// ErrNoDecoder is returned when there wasn't a decoder available for a type. +type ErrNoDecoder struct { +	Type reflect.Type +} + +func (end ErrNoDecoder) Error() string { +	return "no decoder found for " + end.Type.String() +} + +// ErrNoTypeMapEntry is returned when there wasn't a type available for the provided BSON type. +type ErrNoTypeMapEntry struct { +	Type bsontype.Type +} + +func (entme ErrNoTypeMapEntry) Error() string { +	return "no type map entry found for " + entme.Type.String() +} + +// ErrNotInterface is returned when the provided type is not an interface. +var ErrNotInterface = errors.New("The provided type is not an interface") + +// A RegistryBuilder is used to build a Registry. This type is not goroutine +// safe. +type RegistryBuilder struct { +	typeEncoders      map[reflect.Type]ValueEncoder +	interfaceEncoders []interfaceValueEncoder +	kindEncoders      map[reflect.Kind]ValueEncoder + +	typeDecoders      map[reflect.Type]ValueDecoder +	interfaceDecoders []interfaceValueDecoder +	kindDecoders      map[reflect.Kind]ValueDecoder + +	typeMap map[bsontype.Type]reflect.Type +} + +// A Registry is used to store and retrieve codecs for types and interfaces. This type is the main +// typed passed around and Encoders and Decoders are constructed from it. +type Registry struct { +	typeEncoders map[reflect.Type]ValueEncoder +	typeDecoders map[reflect.Type]ValueDecoder + +	interfaceEncoders []interfaceValueEncoder +	interfaceDecoders []interfaceValueDecoder + +	kindEncoders map[reflect.Kind]ValueEncoder +	kindDecoders map[reflect.Kind]ValueDecoder + +	typeMap map[bsontype.Type]reflect.Type + +	mu sync.RWMutex +} + +// NewRegistryBuilder creates a new empty RegistryBuilder. +func NewRegistryBuilder() *RegistryBuilder { +	return &RegistryBuilder{ +		typeEncoders: make(map[reflect.Type]ValueEncoder), +		typeDecoders: make(map[reflect.Type]ValueDecoder), + +		interfaceEncoders: make([]interfaceValueEncoder, 0), +		interfaceDecoders: make([]interfaceValueDecoder, 0), + +		kindEncoders: make(map[reflect.Kind]ValueEncoder), +		kindDecoders: make(map[reflect.Kind]ValueDecoder), + +		typeMap: make(map[bsontype.Type]reflect.Type), +	} +} + +func buildDefaultRegistry() *Registry { +	rb := NewRegistryBuilder() +	defaultValueEncoders.RegisterDefaultEncoders(rb) +	defaultValueDecoders.RegisterDefaultDecoders(rb) +	return rb.Build() +} + +// RegisterCodec will register the provided ValueCodec for the provided type. +func (rb *RegistryBuilder) RegisterCodec(t reflect.Type, codec ValueCodec) *RegistryBuilder { +	rb.RegisterTypeEncoder(t, codec) +	rb.RegisterTypeDecoder(t, codec) +	return rb +} + +// RegisterTypeEncoder will register the provided ValueEncoder for the provided type. +// +// The type will be used directly, so an encoder can be registered for a type and a different encoder can be registered +// for a pointer to that type. +// +// If the given type is an interface, the encoder will be called when marshalling a type that is that interface. It +// will not be called when marshalling a non-interface type that implements the interface. +func (rb *RegistryBuilder) RegisterTypeEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder { +	rb.typeEncoders[t] = enc +	return rb +} + +// RegisterHookEncoder will register an encoder for the provided interface type t. This encoder will be called when +// marshalling a type if the type implements t or a pointer to the type implements t. If the provided type is not +// an interface (i.e. t.Kind() != reflect.Interface), this method will panic. +func (rb *RegistryBuilder) RegisterHookEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder { +	if t.Kind() != reflect.Interface { +		panicStr := fmt.Sprintf("RegisterHookEncoder expects a type with kind reflect.Interface, "+ +			"got type %s with kind %s", t, t.Kind()) +		panic(panicStr) +	} + +	for idx, encoder := range rb.interfaceEncoders { +		if encoder.i == t { +			rb.interfaceEncoders[idx].ve = enc +			return rb +		} +	} + +	rb.interfaceEncoders = append(rb.interfaceEncoders, interfaceValueEncoder{i: t, ve: enc}) +	return rb +} + +// RegisterTypeDecoder will register the provided ValueDecoder for the provided type. +// +// The type will be used directly, so a decoder can be registered for a type and a different decoder can be registered +// for a pointer to that type. +// +// If the given type is an interface, the decoder will be called when unmarshalling into a type that is that interface. +// It will not be called when unmarshalling into a non-interface type that implements the interface. +func (rb *RegistryBuilder) RegisterTypeDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder { +	rb.typeDecoders[t] = dec +	return rb +} + +// RegisterHookDecoder will register an decoder for the provided interface type t. This decoder will be called when +// unmarshalling into a type if the type implements t or a pointer to the type implements t. If the provided type is not +// an interface (i.e. t.Kind() != reflect.Interface), this method will panic. +func (rb *RegistryBuilder) RegisterHookDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder { +	if t.Kind() != reflect.Interface { +		panicStr := fmt.Sprintf("RegisterHookDecoder expects a type with kind reflect.Interface, "+ +			"got type %s with kind %s", t, t.Kind()) +		panic(panicStr) +	} + +	for idx, decoder := range rb.interfaceDecoders { +		if decoder.i == t { +			rb.interfaceDecoders[idx].vd = dec +			return rb +		} +	} + +	rb.interfaceDecoders = append(rb.interfaceDecoders, interfaceValueDecoder{i: t, vd: dec}) +	return rb +} + +// RegisterEncoder registers the provided type and encoder pair. +// +// Deprecated: Use RegisterTypeEncoder or RegisterHookEncoder instead. +func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder { +	if t == tEmpty { +		rb.typeEncoders[t] = enc +		return rb +	} +	switch t.Kind() { +	case reflect.Interface: +		for idx, ir := range rb.interfaceEncoders { +			if ir.i == t { +				rb.interfaceEncoders[idx].ve = enc +				return rb +			} +		} + +		rb.interfaceEncoders = append(rb.interfaceEncoders, interfaceValueEncoder{i: t, ve: enc}) +	default: +		rb.typeEncoders[t] = enc +	} +	return rb +} + +// RegisterDecoder registers the provided type and decoder pair. +// +// Deprecated: Use RegisterTypeDecoder or RegisterHookDecoder instead. +func (rb *RegistryBuilder) RegisterDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder { +	if t == nil { +		rb.typeDecoders[nil] = dec +		return rb +	} +	if t == tEmpty { +		rb.typeDecoders[t] = dec +		return rb +	} +	switch t.Kind() { +	case reflect.Interface: +		for idx, ir := range rb.interfaceDecoders { +			if ir.i == t { +				rb.interfaceDecoders[idx].vd = dec +				return rb +			} +		} + +		rb.interfaceDecoders = append(rb.interfaceDecoders, interfaceValueDecoder{i: t, vd: dec}) +	default: +		rb.typeDecoders[t] = dec +	} +	return rb +} + +// RegisterDefaultEncoder will registr the provided ValueEncoder to the provided +// kind. +func (rb *RegistryBuilder) RegisterDefaultEncoder(kind reflect.Kind, enc ValueEncoder) *RegistryBuilder { +	rb.kindEncoders[kind] = enc +	return rb +} + +// RegisterDefaultDecoder will register the provided ValueDecoder to the +// provided kind. +func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDecoder) *RegistryBuilder { +	rb.kindDecoders[kind] = dec +	return rb +} + +// RegisterTypeMapEntry will register the provided type to the BSON type. The primary usage for this +// mapping is decoding situations where an empty interface is used and a default type needs to be +// created and decoded into. +// +// By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON +// documents, a type map entry for bsontype.EmbeddedDocument should be registered. For example, to force BSON documents +// to decode to bson.Raw, use the following code: +// +//	rb.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{})) +func (rb *RegistryBuilder) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) *RegistryBuilder { +	rb.typeMap[bt] = rt +	return rb +} + +// Build creates a Registry from the current state of this RegistryBuilder. +func (rb *RegistryBuilder) Build() *Registry { +	registry := new(Registry) + +	registry.typeEncoders = make(map[reflect.Type]ValueEncoder) +	for t, enc := range rb.typeEncoders { +		registry.typeEncoders[t] = enc +	} + +	registry.typeDecoders = make(map[reflect.Type]ValueDecoder) +	for t, dec := range rb.typeDecoders { +		registry.typeDecoders[t] = dec +	} + +	registry.interfaceEncoders = make([]interfaceValueEncoder, len(rb.interfaceEncoders)) +	copy(registry.interfaceEncoders, rb.interfaceEncoders) + +	registry.interfaceDecoders = make([]interfaceValueDecoder, len(rb.interfaceDecoders)) +	copy(registry.interfaceDecoders, rb.interfaceDecoders) + +	registry.kindEncoders = make(map[reflect.Kind]ValueEncoder) +	for kind, enc := range rb.kindEncoders { +		registry.kindEncoders[kind] = enc +	} + +	registry.kindDecoders = make(map[reflect.Kind]ValueDecoder) +	for kind, dec := range rb.kindDecoders { +		registry.kindDecoders[kind] = dec +	} + +	registry.typeMap = make(map[bsontype.Type]reflect.Type) +	for bt, rt := range rb.typeMap { +		registry.typeMap[bt] = rt +	} + +	return registry +} + +// LookupEncoder inspects the registry for an encoder for the given type. The lookup precedence works as follows: +// +// 1. An encoder registered for the exact type. If the given type represents an interface, an encoder registered using +// RegisterTypeEncoder for the interface will be selected. +// +// 2. An encoder registered using RegisterHookEncoder for an interface implemented by the type or by a pointer to the +// type. +// +// 3. An encoder registered for the reflect.Kind of the value. +// +// If no encoder is found, an error of type ErrNoEncoder is returned. +func (r *Registry) LookupEncoder(t reflect.Type) (ValueEncoder, error) { +	encodererr := ErrNoEncoder{Type: t} +	r.mu.RLock() +	enc, found := r.lookupTypeEncoder(t) +	r.mu.RUnlock() +	if found { +		if enc == nil { +			return nil, ErrNoEncoder{Type: t} +		} +		return enc, nil +	} + +	enc, found = r.lookupInterfaceEncoder(t, true) +	if found { +		r.mu.Lock() +		r.typeEncoders[t] = enc +		r.mu.Unlock() +		return enc, nil +	} + +	if t == nil { +		r.mu.Lock() +		r.typeEncoders[t] = nil +		r.mu.Unlock() +		return nil, encodererr +	} + +	enc, found = r.kindEncoders[t.Kind()] +	if !found { +		r.mu.Lock() +		r.typeEncoders[t] = nil +		r.mu.Unlock() +		return nil, encodererr +	} + +	r.mu.Lock() +	r.typeEncoders[t] = enc +	r.mu.Unlock() +	return enc, nil +} + +func (r *Registry) lookupTypeEncoder(t reflect.Type) (ValueEncoder, bool) { +	enc, found := r.typeEncoders[t] +	return enc, found +} + +func (r *Registry) lookupInterfaceEncoder(t reflect.Type, allowAddr bool) (ValueEncoder, bool) { +	if t == nil { +		return nil, false +	} +	for _, ienc := range r.interfaceEncoders { +		if t.Implements(ienc.i) { +			return ienc.ve, true +		} +		if allowAddr && t.Kind() != reflect.Ptr && reflect.PtrTo(t).Implements(ienc.i) { +			// if *t implements an interface, this will catch if t implements an interface further ahead +			// in interfaceEncoders +			defaultEnc, found := r.lookupInterfaceEncoder(t, false) +			if !found { +				defaultEnc = r.kindEncoders[t.Kind()] +			} +			return newCondAddrEncoder(ienc.ve, defaultEnc), true +		} +	} +	return nil, false +} + +// LookupDecoder inspects the registry for an decoder for the given type. The lookup precedence works as follows: +// +// 1. A decoder registered for the exact type. If the given type represents an interface, a decoder registered using +// RegisterTypeDecoder for the interface will be selected. +// +// 2. A decoder registered using RegisterHookDecoder for an interface implemented by the type or by a pointer to the +// type. +// +// 3. A decoder registered for the reflect.Kind of the value. +// +// If no decoder is found, an error of type ErrNoDecoder is returned. +func (r *Registry) LookupDecoder(t reflect.Type) (ValueDecoder, error) { +	if t == nil { +		return nil, ErrNilType +	} +	decodererr := ErrNoDecoder{Type: t} +	r.mu.RLock() +	dec, found := r.lookupTypeDecoder(t) +	r.mu.RUnlock() +	if found { +		if dec == nil { +			return nil, ErrNoDecoder{Type: t} +		} +		return dec, nil +	} + +	dec, found = r.lookupInterfaceDecoder(t, true) +	if found { +		r.mu.Lock() +		r.typeDecoders[t] = dec +		r.mu.Unlock() +		return dec, nil +	} + +	dec, found = r.kindDecoders[t.Kind()] +	if !found { +		r.mu.Lock() +		r.typeDecoders[t] = nil +		r.mu.Unlock() +		return nil, decodererr +	} + +	r.mu.Lock() +	r.typeDecoders[t] = dec +	r.mu.Unlock() +	return dec, nil +} + +func (r *Registry) lookupTypeDecoder(t reflect.Type) (ValueDecoder, bool) { +	dec, found := r.typeDecoders[t] +	return dec, found +} + +func (r *Registry) lookupInterfaceDecoder(t reflect.Type, allowAddr bool) (ValueDecoder, bool) { +	for _, idec := range r.interfaceDecoders { +		if t.Implements(idec.i) { +			return idec.vd, true +		} +		if allowAddr && t.Kind() != reflect.Ptr && reflect.PtrTo(t).Implements(idec.i) { +			// if *t implements an interface, this will catch if t implements an interface further ahead +			// in interfaceDecoders +			defaultDec, found := r.lookupInterfaceDecoder(t, false) +			if !found { +				defaultDec = r.kindDecoders[t.Kind()] +			} +			return newCondAddrDecoder(idec.vd, defaultDec), true +		} +	} +	return nil, false +} + +// LookupTypeMapEntry inspects the registry's type map for a Go type for the corresponding BSON +// type. If no type is found, ErrNoTypeMapEntry is returned. +func (r *Registry) LookupTypeMapEntry(bt bsontype.Type) (reflect.Type, error) { +	t, ok := r.typeMap[bt] +	if !ok || t == nil { +		return nil, ErrNoTypeMapEntry{Type: bt} +	} +	return t, nil +} + +type interfaceValueEncoder struct { +	i  reflect.Type +	ve ValueEncoder +} + +type interfaceValueDecoder struct { +	i  reflect.Type +	vd ValueDecoder +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go new file mode 100644 index 000000000..3c1b6b860 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go @@ -0,0 +1,199 @@ +// 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 bsoncodec + +import ( +	"fmt" +	"reflect" + +	"go.mongodb.org/mongo-driver/bson/bsonoptions" +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +	"go.mongodb.org/mongo-driver/bson/primitive" +) + +var defaultSliceCodec = NewSliceCodec() + +// SliceCodec is the Codec used for slice values. +type SliceCodec struct { +	EncodeNilAsEmpty bool +} + +var _ ValueCodec = &MapCodec{} + +// NewSliceCodec returns a MapCodec with options opts. +func NewSliceCodec(opts ...*bsonoptions.SliceCodecOptions) *SliceCodec { +	sliceOpt := bsonoptions.MergeSliceCodecOptions(opts...) + +	codec := SliceCodec{} +	if sliceOpt.EncodeNilAsEmpty != nil { +		codec.EncodeNilAsEmpty = *sliceOpt.EncodeNilAsEmpty +	} +	return &codec +} + +// EncodeValue is the ValueEncoder for slice types. +func (sc SliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Kind() != reflect.Slice { +		return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} +	} + +	if val.IsNil() && !sc.EncodeNilAsEmpty { +		return vw.WriteNull() +	} + +	// 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) +	} + +	// If we have a []primitive.E we want to treat it as a document instead of as an array. +	if val.Type().ConvertibleTo(tD) { +		d := val.Convert(tD).Interface().(primitive.D) + +		dw, err := vw.WriteDocument() +		if err != nil { +			return err +		} + +		for _, e := range d { +			err = encodeElement(ec, dw, e) +			if err != nil { +				return err +			} +		} + +		return dw.WriteDocumentEnd() +	} + +	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 := defaultValueEncoders.lookupElementEncoder(ec, encoder, val.Index(idx)) +		if lookupErr != nil && lookupErr != errInvalidValue { +			return lookupErr +		} + +		vw, err := aw.WriteArrayElement() +		if err != nil { +			return err +		} + +		if 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() +} + +// DecodeValue is the ValueDecoder for slice types. +func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Kind() != reflect.Slice { +		return ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val} +	} + +	switch vrType := vr.Type(); vrType { +	case bsontype.Array: +	case bsontype.Null: +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadNull() +	case bsontype.Undefined: +		val.Set(reflect.Zero(val.Type())) +		return vr.ReadUndefined() +	case bsontype.Type(0), bsontype.EmbeddedDocument: +		if val.Type().Elem() != tE { +			return fmt.Errorf("cannot decode document into %s", val.Type()) +		} +	case bsontype.Binary: +		if val.Type().Elem() != tByte { +			return fmt.Errorf("SliceDecodeValue can only decode a binary into a byte array, got %v", vrType) +		} +		data, subtype, err := vr.ReadBinary() +		if err != nil { +			return err +		} +		if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld { +			return fmt.Errorf("SliceDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", bsontype.Binary, subtype) +		} + +		if val.IsNil() { +			val.Set(reflect.MakeSlice(val.Type(), 0, len(data))) +		} + +		val.SetLen(0) +		for _, elem := range data { +			val.Set(reflect.Append(val, reflect.ValueOf(elem))) +		} +		return nil +	case bsontype.String: +		if sliceType := val.Type().Elem(); sliceType != tByte { +			return fmt.Errorf("SliceDecodeValue can only decode a string into a byte array, got %v", sliceType) +		} +		str, err := vr.ReadString() +		if err != nil { +			return err +		} +		byteStr := []byte(str) + +		if val.IsNil() { +			val.Set(reflect.MakeSlice(val.Type(), 0, len(byteStr))) +		} + +		val.SetLen(0) +		for _, elem := range byteStr { +			val.Set(reflect.Append(val, reflect.ValueOf(elem))) +		} +		return nil +	default: +		return fmt.Errorf("cannot decode %v into a slice", vrType) +	} + +	var elemsFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) ([]reflect.Value, error) +	switch val.Type().Elem() { +	case tE: +		dc.Ancestor = val.Type() +		elemsFunc = defaultValueDecoders.decodeD +	default: +		elemsFunc = defaultValueDecoders.decodeDefault +	} + +	elems, err := elemsFunc(dc, vr, val) +	if err != nil { +		return err +	} + +	if val.IsNil() { +		val.Set(reflect.MakeSlice(val.Type(), 0, len(elems))) +	} + +	val.SetLen(0) +	val.Set(reflect.Append(val, elems...)) + +	return nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go new file mode 100644 index 000000000..5332b7c3b --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go @@ -0,0 +1,119 @@ +// 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 bsoncodec + +import ( +	"fmt" +	"reflect" + +	"go.mongodb.org/mongo-driver/bson/bsonoptions" +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +) + +// StringCodec is the Codec used for struct values. +type StringCodec struct { +	DecodeObjectIDAsHex bool +} + +var ( +	defaultStringCodec = NewStringCodec() + +	_ ValueCodec  = defaultStringCodec +	_ typeDecoder = defaultStringCodec +) + +// NewStringCodec returns a StringCodec with options opts. +func NewStringCodec(opts ...*bsonoptions.StringCodecOptions) *StringCodec { +	stringOpt := bsonoptions.MergeStringCodecOptions(opts...) +	return &StringCodec{*stringOpt.DecodeObjectIDAsHex} +} + +// EncodeValue is the ValueEncoder for string types. +func (sc *StringCodec) EncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if val.Kind() != reflect.String { +		return ValueEncoderError{ +			Name:     "StringEncodeValue", +			Kinds:    []reflect.Kind{reflect.String}, +			Received: val, +		} +	} + +	return vw.WriteString(val.String()) +} + +func (sc *StringCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { +	if t.Kind() != reflect.String { +		return emptyValue, ValueDecoderError{ +			Name:     "StringDecodeValue", +			Kinds:    []reflect.Kind{reflect.String}, +			Received: reflect.Zero(t), +		} +	} + +	var str string +	var err error +	switch vr.Type() { +	case bsontype.String: +		str, err = vr.ReadString() +		if err != nil { +			return emptyValue, err +		} +	case bsontype.ObjectID: +		oid, err := vr.ReadObjectID() +		if err != nil { +			return emptyValue, err +		} +		if sc.DecodeObjectIDAsHex { +			str = oid.Hex() +		} else { +			byteArray := [12]byte(oid) +			str = string(byteArray[:]) +		} +	case bsontype.Symbol: +		str, err = vr.ReadSymbol() +		if err != nil { +			return emptyValue, err +		} +	case bsontype.Binary: +		data, subtype, err := vr.ReadBinary() +		if err != nil { +			return emptyValue, err +		} +		if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld { +			return emptyValue, decodeBinaryError{subtype: subtype, typeName: "string"} +		} +		str = string(data) +	case bsontype.Null: +		if err = vr.ReadNull(); err != nil { +			return emptyValue, err +		} +	case bsontype.Undefined: +		if err = vr.ReadUndefined(); err != nil { +			return emptyValue, err +		} +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a string type", vr.Type()) +	} + +	return reflect.ValueOf(str), nil +} + +// DecodeValue is the ValueDecoder for string types. +func (sc *StringCodec) DecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Kind() != reflect.String { +		return ValueDecoderError{Name: "StringDecodeValue", Kinds: []reflect.Kind{reflect.String}, Received: val} +	} + +	elem, err := sc.decodeType(dctx, vr, val.Type()) +	if err != nil { +		return err +	} + +	val.SetString(elem.String()) +	return nil +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go new file mode 100644 index 000000000..be3f2081e --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go @@ -0,0 +1,664 @@ +// 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 bsoncodec + +import ( +	"errors" +	"fmt" +	"reflect" +	"sort" +	"strings" +	"sync" +	"time" + +	"go.mongodb.org/mongo-driver/bson/bsonoptions" +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +) + +// DecodeError represents an error that occurs when unmarshalling BSON bytes into a native Go type. +type DecodeError struct { +	keys    []string +	wrapped error +} + +// Unwrap returns the underlying error +func (de *DecodeError) Unwrap() error { +	return de.wrapped +} + +// Error implements the error interface. +func (de *DecodeError) Error() string { +	// The keys are stored in reverse order because the de.keys slice is builtup while propagating the error up the +	// stack of BSON keys, so we call de.Keys(), which reverses them. +	keyPath := strings.Join(de.Keys(), ".") +	return fmt.Sprintf("error decoding key %s: %v", keyPath, de.wrapped) +} + +// Keys returns the BSON key path that caused an error as a slice of strings. The keys in the slice are in top-down +// order. For example, if the document being unmarshalled was {a: {b: {c: 1}}} and the value for c was supposed to be +// a string, the keys slice will be ["a", "b", "c"]. +func (de *DecodeError) Keys() []string { +	reversedKeys := make([]string, 0, len(de.keys)) +	for idx := len(de.keys) - 1; idx >= 0; idx-- { +		reversedKeys = append(reversedKeys, de.keys[idx]) +	} + +	return reversedKeys +} + +// Zeroer allows custom struct types to implement a report of zero +// state. All struct types that don't implement Zeroer or where IsZero +// returns false are considered to be not zero. +type Zeroer interface { +	IsZero() bool +} + +// StructCodec is the Codec used for struct values. +type StructCodec struct { +	cache                            map[reflect.Type]*structDescription +	l                                sync.RWMutex +	parser                           StructTagParser +	DecodeZeroStruct                 bool +	DecodeDeepZeroInline             bool +	EncodeOmitDefaultStruct          bool +	AllowUnexportedFields            bool +	OverwriteDuplicatedInlinedFields bool +} + +var _ ValueEncoder = &StructCodec{} +var _ ValueDecoder = &StructCodec{} + +// NewStructCodec returns a StructCodec that uses p for struct tag parsing. +func NewStructCodec(p StructTagParser, opts ...*bsonoptions.StructCodecOptions) (*StructCodec, error) { +	if p == nil { +		return nil, errors.New("a StructTagParser must be provided to NewStructCodec") +	} + +	structOpt := bsonoptions.MergeStructCodecOptions(opts...) + +	codec := &StructCodec{ +		cache:  make(map[reflect.Type]*structDescription), +		parser: p, +	} + +	if structOpt.DecodeZeroStruct != nil { +		codec.DecodeZeroStruct = *structOpt.DecodeZeroStruct +	} +	if structOpt.DecodeDeepZeroInline != nil { +		codec.DecodeDeepZeroInline = *structOpt.DecodeDeepZeroInline +	} +	if structOpt.EncodeOmitDefaultStruct != nil { +		codec.EncodeOmitDefaultStruct = *structOpt.EncodeOmitDefaultStruct +	} +	if structOpt.OverwriteDuplicatedInlinedFields != nil { +		codec.OverwriteDuplicatedInlinedFields = *structOpt.OverwriteDuplicatedInlinedFields +	} +	if structOpt.AllowUnexportedFields != nil { +		codec.AllowUnexportedFields = *structOpt.AllowUnexportedFields +	} + +	return codec, nil +} + +// EncodeValue handles encoding generic struct types. +func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Kind() != reflect.Struct { +		return ValueEncoderError{Name: "StructCodec.EncodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val} +	} + +	sd, err := sc.describeStruct(r.Registry, val.Type()) +	if err != nil { +		return err +	} + +	dw, err := vw.WriteDocument() +	if err != nil { +		return err +	} +	var rv reflect.Value +	for _, desc := range sd.fl { +		if desc.inline == nil { +			rv = val.Field(desc.idx) +		} else { +			rv, err = fieldByIndexErr(val, desc.inline) +			if err != nil { +				continue +			} +		} + +		desc.encoder, rv, err = defaultValueEncoders.lookupElementEncoder(r, desc.encoder, rv) + +		if err != nil && err != errInvalidValue { +			return err +		} + +		if err == errInvalidValue { +			if desc.omitEmpty { +				continue +			} +			vw2, err := dw.WriteDocumentElement(desc.name) +			if err != nil { +				return err +			} +			err = vw2.WriteNull() +			if err != nil { +				return err +			} +			continue +		} + +		if desc.encoder == nil { +			return ErrNoEncoder{Type: rv.Type()} +		} + +		encoder := desc.encoder + +		var isZero bool +		rvInterface := rv.Interface() +		if cz, ok := encoder.(CodecZeroer); ok { +			isZero = cz.IsTypeZero(rvInterface) +		} else if rv.Kind() == reflect.Interface { +			// sc.isZero will not treat an interface rv as an interface, so we need to check for the zero interface separately. +			isZero = rv.IsNil() +		} else { +			isZero = sc.isZero(rvInterface) +		} +		if desc.omitEmpty && isZero { +			continue +		} + +		vw2, err := dw.WriteDocumentElement(desc.name) +		if err != nil { +			return err +		} + +		ectx := EncodeContext{Registry: r.Registry, MinSize: desc.minSize} +		err = encoder.EncodeValue(ectx, vw2, rv) +		if err != nil { +			return err +		} +	} + +	if sd.inlineMap >= 0 { +		rv := val.Field(sd.inlineMap) +		collisionFn := func(key string) bool { +			_, exists := sd.fm[key] +			return exists +		} + +		return defaultMapCodec.mapEncodeValue(r, dw, rv, collisionFn) +	} + +	return dw.WriteDocumentEnd() +} + +func newDecodeError(key string, original error) error { +	de, ok := original.(*DecodeError) +	if !ok { +		return &DecodeError{ +			keys:    []string{key}, +			wrapped: original, +		} +	} + +	de.keys = append(de.keys, key) +	return de +} + +// DecodeValue implements the Codec interface. +// By default, map types in val will not be cleared. If a map has existing key/value pairs, it will be extended with the new ones from vr. +// For slices, the decoder will set the length of the slice to zero and append all elements. The underlying array will not be cleared. +func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Kind() != reflect.Struct { +		return ValueDecoderError{Name: "StructCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val} +	} + +	switch vrType := vr.Type(); vrType { +	case bsontype.Type(0), bsontype.EmbeddedDocument: +	case bsontype.Null: +		if err := vr.ReadNull(); err != nil { +			return err +		} + +		val.Set(reflect.Zero(val.Type())) +		return nil +	case bsontype.Undefined: +		if err := vr.ReadUndefined(); err != nil { +			return err +		} + +		val.Set(reflect.Zero(val.Type())) +		return nil +	default: +		return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type()) +	} + +	sd, err := sc.describeStruct(r.Registry, val.Type()) +	if err != nil { +		return err +	} + +	if sc.DecodeZeroStruct { +		val.Set(reflect.Zero(val.Type())) +	} +	if sc.DecodeDeepZeroInline && sd.inline { +		val.Set(deepZero(val.Type())) +	} + +	var decoder ValueDecoder +	var inlineMap reflect.Value +	if sd.inlineMap >= 0 { +		inlineMap = val.Field(sd.inlineMap) +		decoder, err = r.LookupDecoder(inlineMap.Type().Elem()) +		if err != nil { +			return err +		} +	} + +	dr, err := vr.ReadDocument() +	if err != nil { +		return err +	} + +	for { +		name, vr, err := dr.ReadElement() +		if err == bsonrw.ErrEOD { +			break +		} +		if err != nil { +			return err +		} + +		fd, exists := sd.fm[name] +		if !exists { +			// if the original name isn't found in the struct description, try again with the name in lowercase +			// this could match if a BSON tag isn't specified because by default, describeStruct lowercases all field +			// names +			fd, exists = sd.fm[strings.ToLower(name)] +		} + +		if !exists { +			if sd.inlineMap < 0 { +				// The encoding/json package requires a flag to return on error for non-existent fields. +				// This functionality seems appropriate for the struct codec. +				err = vr.Skip() +				if err != nil { +					return err +				} +				continue +			} + +			if inlineMap.IsNil() { +				inlineMap.Set(reflect.MakeMap(inlineMap.Type())) +			} + +			elem := reflect.New(inlineMap.Type().Elem()).Elem() +			r.Ancestor = inlineMap.Type() +			err = decoder.DecodeValue(r, vr, elem) +			if err != nil { +				return err +			} +			inlineMap.SetMapIndex(reflect.ValueOf(name), elem) +			continue +		} + +		var field reflect.Value +		if fd.inline == nil { +			field = val.Field(fd.idx) +		} else { +			field, err = getInlineField(val, fd.inline) +			if err != nil { +				return err +			} +		} + +		if !field.CanSet() { // Being settable is a super set of being addressable. +			innerErr := fmt.Errorf("field %v is not settable", field) +			return newDecodeError(fd.name, innerErr) +		} +		if field.Kind() == reflect.Ptr && field.IsNil() { +			field.Set(reflect.New(field.Type().Elem())) +		} +		field = field.Addr() + +		dctx := DecodeContext{Registry: r.Registry, Truncate: fd.truncate || r.Truncate} +		if fd.decoder == nil { +			return newDecodeError(fd.name, ErrNoDecoder{Type: field.Elem().Type()}) +		} + +		err = fd.decoder.DecodeValue(dctx, vr, field.Elem()) +		if err != nil { +			return newDecodeError(fd.name, err) +		} +	} + +	return nil +} + +func (sc *StructCodec) isZero(i interface{}) bool { +	v := reflect.ValueOf(i) + +	// check the value validity +	if !v.IsValid() { +		return true +	} + +	if z, ok := v.Interface().(Zeroer); ok && (v.Kind() != reflect.Ptr || !v.IsNil()) { +		return z.IsZero() +	} + +	switch v.Kind() { +	case reflect.Array, reflect.Map, reflect.Slice, reflect.String: +		return v.Len() == 0 +	case reflect.Bool: +		return !v.Bool() +	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: +		return v.Int() == 0 +	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: +		return v.Uint() == 0 +	case reflect.Float32, reflect.Float64: +		return v.Float() == 0 +	case reflect.Interface, reflect.Ptr: +		return v.IsNil() +	case reflect.Struct: +		if sc.EncodeOmitDefaultStruct { +			vt := v.Type() +			if vt == tTime { +				return v.Interface().(time.Time).IsZero() +			} +			for i := 0; i < v.NumField(); i++ { +				if vt.Field(i).PkgPath != "" && !vt.Field(i).Anonymous { +					continue // Private field +				} +				fld := v.Field(i) +				if !sc.isZero(fld.Interface()) { +					return false +				} +			} +			return true +		} +	} + +	return false +} + +type structDescription struct { +	fm        map[string]fieldDescription +	fl        []fieldDescription +	inlineMap int +	inline    bool +} + +type fieldDescription struct { +	name      string // BSON key name +	fieldName string // struct field name +	idx       int +	omitEmpty bool +	minSize   bool +	truncate  bool +	inline    []int +	encoder   ValueEncoder +	decoder   ValueDecoder +} + +type byIndex []fieldDescription + +func (bi byIndex) Len() int { return len(bi) } + +func (bi byIndex) Swap(i, j int) { bi[i], bi[j] = bi[j], bi[i] } + +func (bi byIndex) Less(i, j int) bool { +	// If a field is inlined, its index in the top level struct is stored at inline[0] +	iIdx, jIdx := bi[i].idx, bi[j].idx +	if len(bi[i].inline) > 0 { +		iIdx = bi[i].inline[0] +	} +	if len(bi[j].inline) > 0 { +		jIdx = bi[j].inline[0] +	} +	if iIdx != jIdx { +		return iIdx < jIdx +	} +	for k, biik := range bi[i].inline { +		if k >= len(bi[j].inline) { +			return false +		} +		if biik != bi[j].inline[k] { +			return biik < bi[j].inline[k] +		} +	} +	return len(bi[i].inline) < len(bi[j].inline) +} + +func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescription, error) { +	// We need to analyze the struct, including getting the tags, collecting +	// information about inlining, and create a map of the field name to the field. +	sc.l.RLock() +	ds, exists := sc.cache[t] +	sc.l.RUnlock() +	if exists { +		return ds, nil +	} + +	numFields := t.NumField() +	sd := &structDescription{ +		fm:        make(map[string]fieldDescription, numFields), +		fl:        make([]fieldDescription, 0, numFields), +		inlineMap: -1, +	} + +	var fields []fieldDescription +	for i := 0; i < numFields; i++ { +		sf := t.Field(i) +		if sf.PkgPath != "" && (!sc.AllowUnexportedFields || !sf.Anonymous) { +			// field is private or unexported fields aren't allowed, ignore +			continue +		} + +		sfType := sf.Type +		encoder, err := r.LookupEncoder(sfType) +		if err != nil { +			encoder = nil +		} +		decoder, err := r.LookupDecoder(sfType) +		if err != nil { +			decoder = nil +		} + +		description := fieldDescription{ +			fieldName: sf.Name, +			idx:       i, +			encoder:   encoder, +			decoder:   decoder, +		} + +		stags, err := sc.parser.ParseStructTags(sf) +		if err != nil { +			return nil, err +		} +		if stags.Skip { +			continue +		} +		description.name = stags.Name +		description.omitEmpty = stags.OmitEmpty +		description.minSize = stags.MinSize +		description.truncate = stags.Truncate + +		if stags.Inline { +			sd.inline = true +			switch sfType.Kind() { +			case reflect.Map: +				if sd.inlineMap >= 0 { +					return nil, errors.New("(struct " + t.String() + ") multiple inline maps") +				} +				if sfType.Key() != tString { +					return nil, errors.New("(struct " + t.String() + ") inline map must have a string keys") +				} +				sd.inlineMap = description.idx +			case reflect.Ptr: +				sfType = sfType.Elem() +				if sfType.Kind() != reflect.Struct { +					return nil, fmt.Errorf("(struct %s) inline fields must be a struct, a struct pointer, or a map", t.String()) +				} +				fallthrough +			case reflect.Struct: +				inlinesf, err := sc.describeStruct(r, sfType) +				if err != nil { +					return nil, err +				} +				for _, fd := range inlinesf.fl { +					if fd.inline == nil { +						fd.inline = []int{i, fd.idx} +					} else { +						fd.inline = append([]int{i}, fd.inline...) +					} +					fields = append(fields, fd) + +				} +			default: +				return nil, fmt.Errorf("(struct %s) inline fields must be a struct, a struct pointer, or a map", t.String()) +			} +			continue +		} +		fields = append(fields, description) +	} + +	// Sort fieldDescriptions by name and use dominance rules to determine which should be added for each name +	sort.Slice(fields, func(i, j int) bool { +		x := fields +		// sort field by name, breaking ties with depth, then +		// breaking ties with index sequence. +		if x[i].name != x[j].name { +			return x[i].name < x[j].name +		} +		if len(x[i].inline) != len(x[j].inline) { +			return len(x[i].inline) < len(x[j].inline) +		} +		return byIndex(x).Less(i, j) +	}) + +	for advance, i := 0, 0; i < len(fields); i += advance { +		// One iteration per name. +		// Find the sequence of fields with the name of this first field. +		fi := fields[i] +		name := fi.name +		for advance = 1; i+advance < len(fields); advance++ { +			fj := fields[i+advance] +			if fj.name != name { +				break +			} +		} +		if advance == 1 { // Only one field with this name +			sd.fl = append(sd.fl, fi) +			sd.fm[name] = fi +			continue +		} +		dominant, ok := dominantField(fields[i : i+advance]) +		if !ok || !sc.OverwriteDuplicatedInlinedFields { +			return nil, fmt.Errorf("struct %s has duplicated key %s", t.String(), name) +		} +		sd.fl = append(sd.fl, dominant) +		sd.fm[name] = dominant +	} + +	sort.Sort(byIndex(sd.fl)) + +	sc.l.Lock() +	sc.cache[t] = sd +	sc.l.Unlock() + +	return sd, nil +} + +// dominantField looks through the fields, all of which are known to +// have the same name, to find the single field that dominates the +// others using Go's inlining rules. If there are multiple top-level +// fields, the boolean will be false: This condition is an error in Go +// and we skip all the fields. +func dominantField(fields []fieldDescription) (fieldDescription, bool) { +	// The fields are sorted in increasing index-length order, then by presence of tag. +	// That means that the first field is the dominant one. We need only check +	// for error cases: two fields at top level. +	if len(fields) > 1 && +		len(fields[0].inline) == len(fields[1].inline) { +		return fieldDescription{}, false +	} +	return fields[0], true +} + +func fieldByIndexErr(v reflect.Value, index []int) (result reflect.Value, err error) { +	defer func() { +		if recovered := recover(); recovered != nil { +			switch r := recovered.(type) { +			case string: +				err = fmt.Errorf("%s", r) +			case error: +				err = r +			} +		} +	}() + +	result = v.FieldByIndex(index) +	return +} + +func getInlineField(val reflect.Value, index []int) (reflect.Value, error) { +	field, err := fieldByIndexErr(val, index) +	if err == nil { +		return field, nil +	} + +	// if parent of this element doesn't exist, fix its parent +	inlineParent := index[:len(index)-1] +	var fParent reflect.Value +	if fParent, err = fieldByIndexErr(val, inlineParent); err != nil { +		fParent, err = getInlineField(val, inlineParent) +		if err != nil { +			return fParent, err +		} +	} +	fParent.Set(reflect.New(fParent.Type().Elem())) + +	return fieldByIndexErr(val, index) +} + +// DeepZero returns recursive zero object +func deepZero(st reflect.Type) (result reflect.Value) { +	result = reflect.Indirect(reflect.New(st)) + +	if result.Kind() == reflect.Struct { +		for i := 0; i < result.NumField(); i++ { +			if f := result.Field(i); f.Kind() == reflect.Ptr { +				if f.CanInterface() { +					if ft := reflect.TypeOf(f.Interface()); ft.Elem().Kind() == reflect.Struct { +						result.Field(i).Set(recursivePointerTo(deepZero(ft.Elem()))) +					} +				} +			} +		} +	} + +	return +} + +// recursivePointerTo calls reflect.New(v.Type) but recursively for its fields inside +func recursivePointerTo(v reflect.Value) reflect.Value { +	v = reflect.Indirect(v) +	result := reflect.New(v.Type()) +	if v.Kind() == reflect.Struct { +		for i := 0; i < v.NumField(); i++ { +			if f := v.Field(i); f.Kind() == reflect.Ptr { +				if f.Elem().Kind() == reflect.Struct { +					result.Elem().Field(i).Set(recursivePointerTo(f)) +				} +			} +		} +	} + +	return result +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go new file mode 100644 index 000000000..62708c5c7 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go @@ -0,0 +1,139 @@ +// 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 bsoncodec + +import ( +	"reflect" +	"strings" +) + +// StructTagParser returns the struct tags for a given struct field. +type StructTagParser interface { +	ParseStructTags(reflect.StructField) (StructTags, error) +} + +// StructTagParserFunc is an adapter that allows a generic function to be used +// as a StructTagParser. +type StructTagParserFunc func(reflect.StructField) (StructTags, error) + +// ParseStructTags implements the StructTagParser interface. +func (stpf StructTagParserFunc) ParseStructTags(sf reflect.StructField) (StructTags, error) { +	return stpf(sf) +} + +// StructTags represents the struct tag fields that the StructCodec uses during +// the encoding and decoding process. +// +// In the case of a struct, the lowercased field name is used as the key for each exported +// field but this behavior may be changed using a struct tag. The tag may also contain flags to +// adjust the marshalling behavior for the field. +// +// The properties are defined below: +// +//	OmitEmpty  Only include the field if it's not set to the zero value for the type or to +//	           empty slices or maps. +// +//	MinSize    Marshal an integer of a type larger than 32 bits value as an int32, if that's +//	           feasible while preserving the numeric value. +// +//	Truncate   When unmarshaling a BSON double, it is permitted to lose precision to fit within +//	           a float32. +// +//	Inline     Inline the field, which must be a struct or a map, causing all of its fields +//	           or keys to be processed as if they were part of the outer struct. For maps, +//	           keys must not conflict with the bson keys of other struct fields. +// +//	Skip       This struct field should be skipped. This is usually denoted by parsing a "-" +//	           for the name. +// +// TODO(skriptble): Add tags for undefined as nil and for null as nil. +type StructTags struct { +	Name      string +	OmitEmpty bool +	MinSize   bool +	Truncate  bool +	Inline    bool +	Skip      bool +} + +// DefaultStructTagParser is the StructTagParser used by the StructCodec by default. +// It will handle the bson struct tag. See the documentation for StructTags to see +// what each of the returned fields means. +// +// If there is no name in the struct tag fields, the struct field name is lowercased. +// The tag formats accepted are: +// +//	"[<key>][,<flag1>[,<flag2>]]" +// +//	`(...) bson:"[<key>][,<flag1>[,<flag2>]]" (...)` +// +// An example: +// +//	type T struct { +//	    A bool +//	    B int    "myb" +//	    C string "myc,omitempty" +//	    D string `bson:",omitempty" json:"jsonkey"` +//	    E int64  ",minsize" +//	    F int64  "myf,omitempty,minsize" +//	} +// +// A struct tag either consisting entirely of '-' or with a bson key with a +// value consisting entirely of '-' will return a StructTags with Skip true and +// the remaining fields will be their default values. +var DefaultStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) { +	key := strings.ToLower(sf.Name) +	tag, ok := sf.Tag.Lookup("bson") +	if !ok && !strings.Contains(string(sf.Tag), ":") && len(sf.Tag) > 0 { +		tag = string(sf.Tag) +	} +	return parseTags(key, tag) +} + +func parseTags(key string, tag string) (StructTags, error) { +	var st StructTags +	if tag == "-" { +		st.Skip = true +		return st, nil +	} + +	for idx, str := range strings.Split(tag, ",") { +		if idx == 0 && str != "" { +			key = str +		} +		switch str { +		case "omitempty": +			st.OmitEmpty = true +		case "minsize": +			st.MinSize = true +		case "truncate": +			st.Truncate = true +		case "inline": +			st.Inline = true +		} +	} + +	st.Name = key + +	return st, nil +} + +// JSONFallbackStructTagParser has the same behavior as DefaultStructTagParser +// but will also fallback to parsing the json tag instead on a field where the +// bson tag isn't available. +var JSONFallbackStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) { +	key := strings.ToLower(sf.Name) +	tag, ok := sf.Tag.Lookup("bson") +	if !ok { +		tag, ok = sf.Tag.Lookup("json") +	} +	if !ok && !strings.Contains(string(sf.Tag), ":") && len(sf.Tag) > 0 { +		tag = string(sf.Tag) +	} + +	return parseTags(key, tag) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go new file mode 100644 index 000000000..ec7e30f72 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_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 bsoncodec + +import ( +	"fmt" +	"reflect" +	"time" + +	"go.mongodb.org/mongo-driver/bson/bsonoptions" +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +	"go.mongodb.org/mongo-driver/bson/primitive" +) + +const ( +	timeFormatString = "2006-01-02T15:04:05.999Z07:00" +) + +// TimeCodec is the Codec used for time.Time values. +type TimeCodec struct { +	UseLocalTimeZone bool +} + +var ( +	defaultTimeCodec = NewTimeCodec() + +	_ ValueCodec  = defaultTimeCodec +	_ typeDecoder = defaultTimeCodec +) + +// NewTimeCodec returns a TimeCodec with options opts. +func NewTimeCodec(opts ...*bsonoptions.TimeCodecOptions) *TimeCodec { +	timeOpt := bsonoptions.MergeTimeCodecOptions(opts...) + +	codec := TimeCodec{} +	if timeOpt.UseLocalTimeZone != nil { +		codec.UseLocalTimeZone = *timeOpt.UseLocalTimeZone +	} +	return &codec +} + +func (tc *TimeCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { +	if t != tTime { +		return emptyValue, ValueDecoderError{ +			Name:     "TimeDecodeValue", +			Types:    []reflect.Type{tTime}, +			Received: reflect.Zero(t), +		} +	} + +	var timeVal time.Time +	switch vrType := vr.Type(); vrType { +	case bsontype.DateTime: +		dt, err := vr.ReadDateTime() +		if err != nil { +			return emptyValue, err +		} +		timeVal = time.Unix(dt/1000, dt%1000*1000000) +	case bsontype.String: +		// assume strings are in the isoTimeFormat +		timeStr, err := vr.ReadString() +		if err != nil { +			return emptyValue, err +		} +		timeVal, err = time.Parse(timeFormatString, timeStr) +		if err != nil { +			return emptyValue, err +		} +	case bsontype.Int64: +		i64, err := vr.ReadInt64() +		if err != nil { +			return emptyValue, err +		} +		timeVal = time.Unix(i64/1000, i64%1000*1000000) +	case bsontype.Timestamp: +		t, _, err := vr.ReadTimestamp() +		if err != nil { +			return emptyValue, err +		} +		timeVal = time.Unix(int64(t), 0) +	case bsontype.Null: +		if err := vr.ReadNull(); err != nil { +			return emptyValue, err +		} +	case bsontype.Undefined: +		if err := vr.ReadUndefined(); err != nil { +			return emptyValue, err +		} +	default: +		return emptyValue, fmt.Errorf("cannot decode %v into a time.Time", vrType) +	} + +	if !tc.UseLocalTimeZone { +		timeVal = timeVal.UTC() +	} +	return reflect.ValueOf(timeVal), nil +} + +// DecodeValue is the ValueDecoderFunc for time.Time. +func (tc *TimeCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() || val.Type() != tTime { +		return ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}, Received: val} +	} + +	elem, err := tc.decodeType(dc, vr, tTime) +	if err != nil { +		return err +	} + +	val.Set(elem) +	return nil +} + +// EncodeValue is the ValueEncoderFunc for time.TIme. +func (tc *TimeCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	if !val.IsValid() || val.Type() != tTime { +		return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val} +	} +	tt := val.Interface().(time.Time) +	dt := primitive.NewDateTimeFromTime(tt) +	return vw.WriteDateTime(int64(dt)) +} diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go new file mode 100644 index 000000000..07f4b70e6 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go @@ -0,0 +1,57 @@ +// 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 bsoncodec + +import ( +	"encoding/json" +	"net/url" +	"reflect" +	"time" + +	"go.mongodb.org/mongo-driver/bson/primitive" +	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore" +) + +var tBool = reflect.TypeOf(false) +var tFloat64 = reflect.TypeOf(float64(0)) +var tInt32 = reflect.TypeOf(int32(0)) +var tInt64 = reflect.TypeOf(int64(0)) +var tString = reflect.TypeOf("") +var tTime = reflect.TypeOf(time.Time{}) + +var tEmpty = reflect.TypeOf((*interface{})(nil)).Elem() +var tByteSlice = reflect.TypeOf([]byte(nil)) +var tByte = reflect.TypeOf(byte(0x00)) +var tURL = reflect.TypeOf(url.URL{}) +var tJSONNumber = reflect.TypeOf(json.Number("")) + +var tValueMarshaler = reflect.TypeOf((*ValueMarshaler)(nil)).Elem() +var tValueUnmarshaler = reflect.TypeOf((*ValueUnmarshaler)(nil)).Elem() +var tMarshaler = reflect.TypeOf((*Marshaler)(nil)).Elem() +var tUnmarshaler = reflect.TypeOf((*Unmarshaler)(nil)).Elem() +var tProxy = reflect.TypeOf((*Proxy)(nil)).Elem() + +var tBinary = reflect.TypeOf(primitive.Binary{}) +var tUndefined = reflect.TypeOf(primitive.Undefined{}) +var tOID = reflect.TypeOf(primitive.ObjectID{}) +var tDateTime = reflect.TypeOf(primitive.DateTime(0)) +var tNull = reflect.TypeOf(primitive.Null{}) +var tRegex = reflect.TypeOf(primitive.Regex{}) +var tCodeWithScope = reflect.TypeOf(primitive.CodeWithScope{}) +var tDBPointer = reflect.TypeOf(primitive.DBPointer{}) +var tJavaScript = reflect.TypeOf(primitive.JavaScript("")) +var tSymbol = reflect.TypeOf(primitive.Symbol("")) +var tTimestamp = reflect.TypeOf(primitive.Timestamp{}) +var tDecimal = reflect.TypeOf(primitive.Decimal128{}) +var tMinKey = reflect.TypeOf(primitive.MinKey{}) +var tMaxKey = reflect.TypeOf(primitive.MaxKey{}) +var tD = reflect.TypeOf(primitive.D{}) +var tA = reflect.TypeOf(primitive.A{}) +var tE = reflect.TypeOf(primitive.E{}) + +var tCoreDocument = reflect.TypeOf(bsoncore.Document{}) +var tCoreArray = reflect.TypeOf(bsoncore.Array{}) diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go new file mode 100644 index 000000000..0b21ce999 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go @@ -0,0 +1,173 @@ +// 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 bsoncodec + +import ( +	"fmt" +	"math" +	"reflect" + +	"go.mongodb.org/mongo-driver/bson/bsonoptions" +	"go.mongodb.org/mongo-driver/bson/bsonrw" +	"go.mongodb.org/mongo-driver/bson/bsontype" +) + +// UIntCodec is the Codec used for uint values. +type UIntCodec struct { +	EncodeToMinSize bool +} + +var ( +	defaultUIntCodec = NewUIntCodec() + +	_ ValueCodec  = defaultUIntCodec +	_ typeDecoder = defaultUIntCodec +) + +// NewUIntCodec returns a UIntCodec with options opts. +func NewUIntCodec(opts ...*bsonoptions.UIntCodecOptions) *UIntCodec { +	uintOpt := bsonoptions.MergeUIntCodecOptions(opts...) + +	codec := UIntCodec{} +	if uintOpt.EncodeToMinSize != nil { +		codec.EncodeToMinSize = *uintOpt.EncodeToMinSize +	} +	return &codec +} + +// EncodeValue is the ValueEncoder for uint types. +func (uic *UIntCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error { +	switch val.Kind() { +	case reflect.Uint8, reflect.Uint16: +		return vw.WriteInt32(int32(val.Uint())) +	case reflect.Uint, reflect.Uint32, reflect.Uint64: +		u64 := val.Uint() + +		// If ec.MinSize or if encodeToMinSize is true for a non-uint64 value we should write val as an int32 +		useMinSize := ec.MinSize || (uic.EncodeToMinSize && val.Kind() != reflect.Uint64) + +		if u64 <= math.MaxInt32 && useMinSize { +			return vw.WriteInt32(int32(u64)) +		} +		if u64 > math.MaxInt64 { +			return fmt.Errorf("%d overflows int64", u64) +		} +		return vw.WriteInt64(int64(u64)) +	} + +	return ValueEncoderError{ +		Name:     "UintEncodeValue", +		Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, +		Received: val, +	} +} + +func (uic *UIntCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) { +	var i64 int64 +	var err error +	switch vrType := vr.Type(); vrType { +	case bsontype.Int32: +		i32, err := vr.ReadInt32() +		if err != nil { +			return emptyValue, err +		} +		i64 = int64(i32) +	case bsontype.Int64: +		i64, err = vr.ReadInt64() +		if err != nil { +			return emptyValue, err +		} +	case bsontype.Double: +		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 bsontype.Boolean: +		b, err := vr.ReadBoolean() +		if err != nil { +			return emptyValue, err +		} +		if b { +			i64 = 1 +		} +	case bsontype.Null: +		if err = vr.ReadNull(); err != nil { +			return emptyValue, err +		} +	case bsontype.Undefined: +		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.Uint8: +		if i64 < 0 || i64 > math.MaxUint8 { +			return emptyValue, fmt.Errorf("%d overflows uint8", i64) +		} + +		return reflect.ValueOf(uint8(i64)), nil +	case reflect.Uint16: +		if i64 < 0 || i64 > math.MaxUint16 { +			return emptyValue, fmt.Errorf("%d overflows uint16", i64) +		} + +		return reflect.ValueOf(uint16(i64)), nil +	case reflect.Uint32: +		if i64 < 0 || i64 > math.MaxUint32 { +			return emptyValue, fmt.Errorf("%d overflows uint32", i64) +		} + +		return reflect.ValueOf(uint32(i64)), nil +	case reflect.Uint64: +		if i64 < 0 { +			return emptyValue, fmt.Errorf("%d overflows uint64", i64) +		} + +		return reflect.ValueOf(uint64(i64)), nil +	case reflect.Uint: +		if i64 < 0 || int64(uint(i64)) != i64 { // Can we fit this inside of an uint +			return emptyValue, fmt.Errorf("%d overflows uint", i64) +		} + +		return reflect.ValueOf(uint(i64)), nil +	default: +		return emptyValue, ValueDecoderError{ +			Name:     "UintDecodeValue", +			Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, +			Received: reflect.Zero(t), +		} +	} +} + +// DecodeValue is the ValueDecoder for uint types. +func (uic *UIntCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { +	if !val.CanSet() { +		return ValueDecoderError{ +			Name:     "UintDecodeValue", +			Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint}, +			Received: val, +		} +	} + +	elem, err := uic.decodeType(dc, vr, val.Type()) +	if err != nil { +		return err +	} + +	val.SetUint(elem.Uint()) +	return nil +}  | 
