seba-365 - implemented dep
Change-Id: Ia6226d50e7615935a0c8876809a687427ff88c22
diff --git a/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/bsoncodec.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/bsoncodec.go
new file mode 100644
index 0000000..4c5530c
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/bsoncodec.go
@@ -0,0 +1,163 @@
+// 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"
+ "strings"
+
+ "github.com/mongodb/mongo-go-driver/bson/bsonrw"
+ "github.com/mongodb/mongo-go-driver/bson/bsontype"
+)
+
+// 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 representaiton 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.
+ Ancestor reflect.Type
+}
+
+// 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)
+}
+
+// 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/github.com/mongodb/mongo-go-driver/bson/bsoncodec/default_value_decoders.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/default_value_decoders.go
new file mode 100644
index 0000000..645f89e
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/default_value_decoders.go
@@ -0,0 +1,1014 @@
+// 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"
+
+ "github.com/mongodb/mongo-go-driver/bson/bsonrw"
+ "github.com/mongodb/mongo-go-driver/bson/bsontype"
+ "github.com/mongodb/mongo-go-driver/bson/primitive"
+ "github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore"
+)
+
+var defaultValueDecoders DefaultValueDecoders
+
+// 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{} becuase there is no decoder for
+// interface{}, so users must either register this decoder themselves or use the
+// EmptyInterfaceDecoder avaialble in the bson package.
+func (dvd DefaultValueDecoders) RegisterDefaultDecoders(rb *RegistryBuilder) {
+ if rb == nil {
+ panic(errors.New("argument to RegisterDefaultDecoders must not be nil"))
+ }
+
+ rb.
+ RegisterDecoder(tBinary, ValueDecoderFunc(dvd.BinaryDecodeValue)).
+ RegisterDecoder(tUndefined, ValueDecoderFunc(dvd.UndefinedDecodeValue)).
+ RegisterDecoder(tDateTime, ValueDecoderFunc(dvd.DateTimeDecodeValue)).
+ RegisterDecoder(tNull, ValueDecoderFunc(dvd.NullDecodeValue)).
+ RegisterDecoder(tRegex, ValueDecoderFunc(dvd.RegexDecodeValue)).
+ RegisterDecoder(tDBPointer, ValueDecoderFunc(dvd.DBPointerDecodeValue)).
+ RegisterDecoder(tTimestamp, ValueDecoderFunc(dvd.TimestampDecodeValue)).
+ RegisterDecoder(tMinKey, ValueDecoderFunc(dvd.MinKeyDecodeValue)).
+ RegisterDecoder(tMaxKey, ValueDecoderFunc(dvd.MaxKeyDecodeValue)).
+ RegisterDecoder(tJavaScript, ValueDecoderFunc(dvd.JavaScriptDecodeValue)).
+ RegisterDecoder(tSymbol, ValueDecoderFunc(dvd.SymbolDecodeValue)).
+ RegisterDecoder(tByteSlice, ValueDecoderFunc(dvd.ByteSliceDecodeValue)).
+ RegisterDecoder(tTime, ValueDecoderFunc(dvd.TimeDecodeValue)).
+ RegisterDecoder(tEmpty, ValueDecoderFunc(dvd.EmptyInterfaceDecodeValue)).
+ RegisterDecoder(tOID, ValueDecoderFunc(dvd.ObjectIDDecodeValue)).
+ RegisterDecoder(tDecimal, ValueDecoderFunc(dvd.Decimal128DecodeValue)).
+ RegisterDecoder(tJSONNumber, ValueDecoderFunc(dvd.JSONNumberDecodeValue)).
+ RegisterDecoder(tURL, ValueDecoderFunc(dvd.URLDecodeValue)).
+ RegisterDecoder(tValueUnmarshaler, ValueDecoderFunc(dvd.ValueUnmarshalerDecodeValue)).
+ RegisterDecoder(tUnmarshaler, ValueDecoderFunc(dvd.UnmarshalerDecodeValue)).
+ RegisterDecoder(tCoreDocument, ValueDecoderFunc(dvd.CoreDocumentDecodeValue)).
+ RegisterDecoder(tCodeWithScope, ValueDecoderFunc(dvd.CodeWithScopeDecodeValue)).
+ RegisterDefaultDecoder(reflect.Bool, ValueDecoderFunc(dvd.BooleanDecodeValue)).
+ RegisterDefaultDecoder(reflect.Int, ValueDecoderFunc(dvd.IntDecodeValue)).
+ RegisterDefaultDecoder(reflect.Int8, ValueDecoderFunc(dvd.IntDecodeValue)).
+ RegisterDefaultDecoder(reflect.Int16, ValueDecoderFunc(dvd.IntDecodeValue)).
+ RegisterDefaultDecoder(reflect.Int32, ValueDecoderFunc(dvd.IntDecodeValue)).
+ RegisterDefaultDecoder(reflect.Int64, ValueDecoderFunc(dvd.IntDecodeValue)).
+ RegisterDefaultDecoder(reflect.Uint, ValueDecoderFunc(dvd.UintDecodeValue)).
+ RegisterDefaultDecoder(reflect.Uint8, ValueDecoderFunc(dvd.UintDecodeValue)).
+ RegisterDefaultDecoder(reflect.Uint16, ValueDecoderFunc(dvd.UintDecodeValue)).
+ RegisterDefaultDecoder(reflect.Uint32, ValueDecoderFunc(dvd.UintDecodeValue)).
+ RegisterDefaultDecoder(reflect.Uint64, ValueDecoderFunc(dvd.UintDecodeValue)).
+ RegisterDefaultDecoder(reflect.Float32, ValueDecoderFunc(dvd.FloatDecodeValue)).
+ RegisterDefaultDecoder(reflect.Float64, ValueDecoderFunc(dvd.FloatDecodeValue)).
+ RegisterDefaultDecoder(reflect.Array, ValueDecoderFunc(dvd.ArrayDecodeValue)).
+ RegisterDefaultDecoder(reflect.Map, ValueDecoderFunc(dvd.MapDecodeValue)).
+ RegisterDefaultDecoder(reflect.Slice, ValueDecoderFunc(dvd.SliceDecodeValue)).
+ RegisterDefaultDecoder(reflect.String, ValueDecoderFunc(dvd.StringDecodeValue)).
+ RegisterDefaultDecoder(reflect.Struct, &StructCodec{cache: make(map[reflect.Type]*structDescription), parser: DefaultStructTagParser}).
+ 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)
+}
+
+// BooleanDecodeValue is the ValueDecoderFunc for bool types.
+func (dvd DefaultValueDecoders) BooleanDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+ if vr.Type() != bsontype.Boolean {
+ return fmt.Errorf("cannot decode %v into a boolean", vr.Type())
+ }
+ if !val.IsValid() || !val.CanSet() || val.Kind() != reflect.Bool {
+ return ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val}
+ }
+
+ b, err := vr.ReadBoolean()
+ val.SetBool(b)
+ return err
+}
+
+// IntDecodeValue is the ValueDecoderFunc for bool types.
+func (dvd DefaultValueDecoders) IntDecodeValue(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("IntDecodeValue 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)
+ default:
+ return fmt.Errorf("cannot decode %v into an integer type", vr.Type())
+ }
+
+ if !val.CanSet() {
+ return ValueDecoderError{
+ Name: "IntDecodeValue",
+ Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
+ Received: val,
+ }
+ }
+
+ switch val.Kind() {
+ case reflect.Int8:
+ if i64 < math.MinInt8 || i64 > math.MaxInt8 {
+ return fmt.Errorf("%d overflows int8", i64)
+ }
+ case reflect.Int16:
+ if i64 < math.MinInt16 || i64 > math.MaxInt16 {
+ return fmt.Errorf("%d overflows int16", i64)
+ }
+ case reflect.Int32:
+ if i64 < math.MinInt32 || i64 > math.MaxInt32 {
+ return fmt.Errorf("%d overflows int32", i64)
+ }
+ case reflect.Int64:
+ case reflect.Int:
+ if int64(int(i64)) != i64 { // Can we fit this inside of an int
+ return fmt.Errorf("%d overflows int", i64)
+ }
+ default:
+ return ValueDecoderError{
+ Name: "IntDecodeValue",
+ Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
+ Received: val,
+ }
+ }
+
+ val.SetInt(i64)
+ return nil
+}
+
+// UintDecodeValue is the ValueDecoderFunc for uint types.
+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)
+ 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
+}
+
+// FloatDecodeValue is the ValueDecoderFunc for float types.
+func (dvd DefaultValueDecoders) FloatDecodeValue(ec DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+ var f float64
+ var err error
+ switch vr.Type() {
+ case bsontype.Int32:
+ i32, err := vr.ReadInt32()
+ if err != nil {
+ return err
+ }
+ f = float64(i32)
+ case bsontype.Int64:
+ i64, err := vr.ReadInt64()
+ if err != nil {
+ return err
+ }
+ f = float64(i64)
+ case bsontype.Double:
+ f, err = vr.ReadDouble()
+ if err != nil {
+ return err
+ }
+ default:
+ return fmt.Errorf("cannot decode %v into a float32 or float64 type", vr.Type())
+ }
+
+ if !val.CanSet() {
+ return ValueDecoderError{Name: "FloatDecodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val}
+ }
+
+ switch val.Kind() {
+ case reflect.Float32:
+ if !ec.Truncate && float64(float32(f)) != f {
+ return errors.New("FloatDecodeValue can only convert float64 to float32 when truncation is allowed")
+ }
+ case reflect.Float64:
+ default:
+ return ValueDecoderError{Name: "FloatDecodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val}
+ }
+
+ val.SetFloat(f)
+ return nil
+}
+
+// StringDecodeValue is the ValueDecoderFunc for string types.
+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
+}
+
+// JavaScriptDecodeValue is the ValueDecoderFunc for the primitive.JavaScript type.
+func (DefaultValueDecoders) JavaScriptDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tJavaScript {
+ return ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
+ }
+
+ if vr.Type() != bsontype.JavaScript {
+ return fmt.Errorf("cannot decode %v into a primitive.JavaScript", vr.Type())
+ }
+
+ js, err := vr.ReadJavascript()
+ if err != nil {
+ return err
+ }
+
+ val.SetString(js)
+ return nil
+}
+
+// SymbolDecodeValue is the ValueDecoderFunc for the primitive.Symbol type.
+func (DefaultValueDecoders) SymbolDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+ if !val.CanSet() || val.Type() != tSymbol {
+ return ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tSymbol}, Received: val}
+ }
+
+ if vr.Type() != bsontype.Symbol {
+ return fmt.Errorf("cannot decode %v into a primitive.Symbol", vr.Type())
+ }
+
+ symbol, err := vr.ReadSymbol()
+ if err != nil {
+ return err
+ }
+
+ val.SetString(symbol)
+ return nil
+}
+
+// BinaryDecodeValue is the ValueDecoderFunc for Binary.
+func (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}
+ }
+
+ if vr.Type() != bsontype.Binary {
+ return fmt.Errorf("cannot decode %v into a Binary", vr.Type())
+ }
+
+ data, subtype, err := vr.ReadBinary()
+ if err != nil {
+ return err
+ }
+
+ val.Set(reflect.ValueOf(primitive.Binary{Subtype: subtype, Data: data}))
+ return nil
+}
+
+// UndefinedDecodeValue is the ValueDecoderFunc for Undefined.
+func (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}
+ }
+
+ if vr.Type() != bsontype.Undefined {
+ return fmt.Errorf("cannot decode %v into an Undefined", vr.Type())
+ }
+
+ val.Set(reflect.ValueOf(primitive.Undefined{}))
+ return vr.ReadUndefined()
+}
+
+// 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}
+ }
+
+ if vr.Type() != bsontype.ObjectID {
+ return fmt.Errorf("cannot decode %v into an ObjectID", vr.Type())
+ }
+ oid, err := vr.ReadObjectID()
+ val.Set(reflect.ValueOf(oid))
+ return err
+}
+
+// DateTimeDecodeValue is the ValueDecoderFunc for DateTime.
+func (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}
+ }
+
+ if vr.Type() != bsontype.DateTime {
+ return fmt.Errorf("cannot decode %v into a DateTime", vr.Type())
+ }
+
+ dt, err := vr.ReadDateTime()
+ if err != nil {
+ return err
+ }
+
+ val.Set(reflect.ValueOf(primitive.DateTime(dt)))
+ return nil
+}
+
+// NullDecodeValue is the ValueDecoderFunc for Null.
+func (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}
+ }
+
+ if vr.Type() != bsontype.Null {
+ return fmt.Errorf("cannot decode %v into a Null", vr.Type())
+ }
+
+ val.Set(reflect.ValueOf(primitive.Null{}))
+ return vr.ReadNull()
+}
+
+// RegexDecodeValue is the ValueDecoderFunc for Regex.
+func (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}
+ }
+
+ if vr.Type() != bsontype.Regex {
+ return fmt.Errorf("cannot decode %v into a Regex", vr.Type())
+ }
+
+ pattern, options, err := vr.ReadRegex()
+ if err != nil {
+ return err
+ }
+
+ val.Set(reflect.ValueOf(primitive.Regex{Pattern: pattern, Options: options}))
+ return nil
+}
+
+// DBPointerDecodeValue is the ValueDecoderFunc for DBPointer.
+func (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}
+ }
+
+ if vr.Type() != bsontype.DBPointer {
+ return fmt.Errorf("cannot decode %v into a DBPointer", vr.Type())
+ }
+
+ ns, pointer, err := vr.ReadDBPointer()
+ if err != nil {
+ return err
+ }
+
+ val.Set(reflect.ValueOf(primitive.DBPointer{DB: ns, Pointer: pointer}))
+ return nil
+}
+
+// TimestampDecodeValue is the ValueDecoderFunc for Timestamp.
+func (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}
+ }
+
+ if vr.Type() != bsontype.Timestamp {
+ return fmt.Errorf("cannot decode %v into a Timestamp", vr.Type())
+ }
+
+ t, incr, err := vr.ReadTimestamp()
+ if err != nil {
+ return err
+ }
+
+ val.Set(reflect.ValueOf(primitive.Timestamp{T: t, I: incr}))
+ return nil
+}
+
+// MinKeyDecodeValue is the ValueDecoderFunc for MinKey.
+func (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}
+ }
+
+ if vr.Type() != bsontype.MinKey {
+ return fmt.Errorf("cannot decode %v into a MinKey", vr.Type())
+ }
+
+ val.Set(reflect.ValueOf(primitive.MinKey{}))
+ return vr.ReadMinKey()
+}
+
+// MaxKeyDecodeValue is the ValueDecoderFunc for MaxKey.
+func (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}
+ }
+
+ if vr.Type() != bsontype.MaxKey {
+ return fmt.Errorf("cannot decode %v into a MaxKey", vr.Type())
+ }
+
+ val.Set(reflect.ValueOf(primitive.MaxKey{}))
+ return vr.ReadMaxKey()
+}
+
+// Decimal128DecodeValue is the ValueDecoderFunc for primitive.Decimal128.
+func (dvd DefaultValueDecoders) Decimal128DecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+ if vr.Type() != bsontype.Decimal128 {
+ return fmt.Errorf("cannot decode %v into a primitive.Decimal128", vr.Type())
+ }
+
+ if !val.CanSet() || val.Type() != tDecimal {
+ return ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}, Received: val}
+ }
+ d128, err := vr.ReadDecimal128()
+ val.Set(reflect.ValueOf(d128))
+ return err
+}
+
+// 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}
+ }
+
+ switch vr.Type() {
+ case bsontype.Double:
+ f64, err := vr.ReadDouble()
+ if err != nil {
+ return err
+ }
+ val.Set(reflect.ValueOf(json.Number(strconv.FormatFloat(f64, 'g', -1, 64))))
+ case bsontype.Int32:
+ i32, err := vr.ReadInt32()
+ if err != nil {
+ return err
+ }
+ val.Set(reflect.ValueOf(json.Number(strconv.FormatInt(int64(i32), 10))))
+ case bsontype.Int64:
+ i64, err := vr.ReadInt64()
+ if err != nil {
+ return err
+ }
+ val.Set(reflect.ValueOf(json.Number(strconv.FormatInt(i64, 10))))
+ default:
+ return fmt.Errorf("cannot decode %v into a json.Number", vr.Type())
+ }
+
+ return nil
+}
+
+// URLDecodeValue is the ValueDecoderFunc for url.URL.
+func (dvd DefaultValueDecoders) URLDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+ if vr.Type() != bsontype.String {
+ return fmt.Errorf("cannot decode %v into a *url.URL", vr.Type())
+ }
+
+ str, err := vr.ReadString()
+ if err != nil {
+ return err
+ }
+
+ u, err := url.Parse(str)
+ if err != nil {
+ return err
+ }
+
+ if !val.CanSet() || val.Type() != tURL {
+ return ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}, Received: val}
+ }
+
+ val.Set(reflect.ValueOf(u).Elem())
+ return nil
+}
+
+// TimeDecodeValue is the ValueDecoderFunc for time.Time.
+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)))
+ return nil
+}
+
+// ByteSliceDecodeValue is the ValueDecoderFunc for []byte.
+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.
+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 vr.Type() {
+ case bsontype.Array:
+ 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 an array", vr.Type())
+ }
+
+ 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", val.Type())
+ }
+
+ for idx, elem := range elems {
+ val.Index(idx).Set(elem)
+ }
+
+ return nil
+}
+
+// SliceDecodeValue is the ValueDecoderFunc for slice types.
+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 they 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()))
+ }
+
+ if !val.Type().Implements(tUnmarshaler) {
+ if !val.CanAddr() {
+ return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val}
+ }
+ val = val.Addr() // If they type doesn't implement the interface, a pointer to it must.
+ }
+
+ _, src, err := bsonrw.Copier{}.CopyValueToBytes(vr)
+ if err != nil {
+ return err
+ }
+
+ 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{}.
+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
+ }
+
+ for {
+ vr, err := ar.ReadValue()
+ if err == bsonrw.ErrEOA {
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ elem := reflect.New(eType).Elem()
+
+ err = decoder.DecodeValue(dc, vr, elem)
+ if err != nil {
+ return nil, err
+ }
+ elems = append(elems, elem)
+ }
+
+ return elems, 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}
+ }
+
+ if vr.Type() != bsontype.CodeWithScope {
+ return fmt.Errorf("cannot decode %v into a primitive.CodeWithScope", vr.Type())
+ }
+
+ code, dr, err := vr.ReadCodeWithScope()
+ if err != nil {
+ return err
+ }
+
+ scope := reflect.New(tD).Elem()
+
+ elems, err := dvd.decodeElemsFromDocumentReader(dc, dr)
+ if err != nil {
+ return err
+ }
+
+ scope.Set(reflect.MakeSlice(tD, 0, len(elems)))
+ scope.Set(reflect.Append(scope, elems...))
+
+ val.Set(reflect.ValueOf(primitive.CodeWithScope{Code: primitive.JavaScript(code), Scope: scope.Interface().(primitive.D)}))
+ 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, err
+ }
+
+ elems = append(elems, reflect.ValueOf(primitive.E{Key: key, Value: val.Interface()}))
+ }
+
+ return elems, nil
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/default_value_encoders.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/default_value_encoders.go
new file mode 100644
index 0000000..61295bd
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/default_value_encoders.go
@@ -0,0 +1,648 @@
+// 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"
+
+ "github.com/mongodb/mongo-go-driver/bson/bsonrw"
+ "github.com/mongodb/mongo-go-driver/bson/bsontype"
+ "github.com/mongodb/mongo-go-driver/bson/primitive"
+ "github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore"
+)
+
+var defaultValueEncoders DefaultValueEncoders
+
+var bvwPool = bsonrw.NewBSONValueWriterPool()
+
+var sliceWriterPool = sync.Pool{
+ New: func() interface{} {
+ sw := make(bsonrw.SliceWriter, 0, 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.
+ RegisterEncoder(tByteSlice, ValueEncoderFunc(dve.ByteSliceEncodeValue)).
+ RegisterEncoder(tTime, ValueEncoderFunc(dve.TimeEncodeValue)).
+ RegisterEncoder(tEmpty, ValueEncoderFunc(dve.EmptyInterfaceEncodeValue)).
+ RegisterEncoder(tOID, ValueEncoderFunc(dve.ObjectIDEncodeValue)).
+ RegisterEncoder(tDecimal, ValueEncoderFunc(dve.Decimal128EncodeValue)).
+ RegisterEncoder(tJSONNumber, ValueEncoderFunc(dve.JSONNumberEncodeValue)).
+ RegisterEncoder(tURL, ValueEncoderFunc(dve.URLEncodeValue)).
+ RegisterEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)).
+ RegisterEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)).
+ RegisterEncoder(tProxy, ValueEncoderFunc(dve.ProxyEncodeValue)).
+ RegisterEncoder(tJavaScript, ValueEncoderFunc(dve.JavaScriptEncodeValue)).
+ RegisterEncoder(tSymbol, ValueEncoderFunc(dve.SymbolEncodeValue)).
+ RegisterEncoder(tBinary, ValueEncoderFunc(dve.BinaryEncodeValue)).
+ RegisterEncoder(tUndefined, ValueEncoderFunc(dve.UndefinedEncodeValue)).
+ RegisterEncoder(tDateTime, ValueEncoderFunc(dve.DateTimeEncodeValue)).
+ RegisterEncoder(tNull, ValueEncoderFunc(dve.NullEncodeValue)).
+ RegisterEncoder(tRegex, ValueEncoderFunc(dve.RegexEncodeValue)).
+ RegisterEncoder(tDBPointer, ValueEncoderFunc(dve.DBPointerEncodeValue)).
+ RegisterEncoder(tTimestamp, ValueEncoderFunc(dve.TimestampEncodeValue)).
+ RegisterEncoder(tMinKey, ValueEncoderFunc(dve.MinKeyEncodeValue)).
+ RegisterEncoder(tMaxKey, ValueEncoderFunc(dve.MaxKeyEncodeValue)).
+ RegisterEncoder(tCoreDocument, ValueEncoderFunc(dve.CoreDocumentEncodeValue)).
+ RegisterEncoder(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, ValueEncoderFunc(dve.UintEncodeValue)).
+ RegisterDefaultEncoder(reflect.Uint8, ValueEncoderFunc(dve.UintEncodeValue)).
+ RegisterDefaultEncoder(reflect.Uint16, ValueEncoderFunc(dve.UintEncodeValue)).
+ RegisterDefaultEncoder(reflect.Uint32, ValueEncoderFunc(dve.UintEncodeValue)).
+ RegisterDefaultEncoder(reflect.Uint64, ValueEncoderFunc(dve.UintEncodeValue)).
+ RegisterDefaultEncoder(reflect.Float32, ValueEncoderFunc(dve.FloatEncodeValue)).
+ RegisterDefaultEncoder(reflect.Float64, ValueEncoderFunc(dve.FloatEncodeValue)).
+ RegisterDefaultEncoder(reflect.Array, ValueEncoderFunc(dve.ArrayEncodeValue)).
+ RegisterDefaultEncoder(reflect.Map, ValueEncoderFunc(dve.MapEncodeValue)).
+ RegisterDefaultEncoder(reflect.Slice, ValueEncoderFunc(dve.SliceEncodeValue)).
+ RegisterDefaultEncoder(reflect.String, ValueEncoderFunc(dve.StringEncodeValue)).
+ RegisterDefaultEncoder(reflect.Struct, &StructCodec{cache: make(map[reflect.Type]*structDescription), parser: DefaultStructTagParser}).
+ RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec())
+}
+
+// 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.
+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.
+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.
+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)
+ return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6))
+}
+
+// ByteSliceEncodeValue is the ValueEncoderFunc for []byte.
+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.
+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 {
+
+ encoder, err := ec.LookupEncoder(val.Type().Elem())
+ if err != nil {
+ 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)
+ }
+ vw, err := dw.WriteDocumentElement(key.String())
+ if err != nil {
+ return err
+ }
+
+ if enc, ok := encoder.(ValueEncoder); ok {
+ err = enc.EncodeValue(ec, vw, val.MapIndex(key))
+ if err != nil {
+ return err
+ }
+ continue
+ }
+ err = encoder.EncodeValue(ec, vw, val.MapIndex(key))
+ 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()
+ }
+
+ aw, err := vw.WriteArray()
+ if err != nil {
+ return err
+ }
+
+ encoder, err := ec.LookupEncoder(val.Type().Elem())
+ if err != nil {
+ return err
+ }
+
+ for idx := 0; idx < val.Len(); idx++ {
+ vw, err := aw.WriteArrayElement()
+ if err != nil {
+ return err
+ }
+
+ err = encoder.EncodeValue(ec, vw, val.Index(idx))
+ if err != nil {
+ return err
+ }
+ }
+ return aw.WriteArrayEnd()
+}
+
+// SliceEncodeValue is the ValueEncoderFunc for slice types.
+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
+ }
+
+ encoder, err := ec.LookupEncoder(val.Type().Elem())
+ if err != nil {
+ return err
+ }
+
+ for idx := 0; idx < val.Len(); idx++ {
+ vw, err := aw.WriteArrayElement()
+ if err != nil {
+ return err
+ }
+
+ err = encoder.EncodeValue(ec, vw, val.Index(idx))
+ if err != nil {
+ return err
+ }
+ }
+ return aw.WriteArrayEnd()
+}
+
+// EmptyInterfaceEncodeValue is the ValueEncoderFunc for interface{}.
+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 {
+ if !val.IsValid() || !val.Type().Implements(tValueMarshaler) {
+ 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 {
+ if !val.IsValid() || !val.Type().Implements(tMarshaler) {
+ 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 {
+ if !val.IsValid() || !val.Type().Implements(tProxy) {
+ 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()
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/doc.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/doc.go
new file mode 100644
index 0000000..978511c
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/doc.go
@@ -0,0 +1,61 @@
+// 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. For looking up
+// ValueEncoders and Decoders the Registry first attempts to find a ValueEncoder or ValueDecoder for
+// the type provided; if one cannot be found it then checks to see if a registered ValueEncoder or
+// ValueDecoder exists for an interface the type implements. Finally, the reflect.Kind of the type
+// is used to lookup a default ValueEncoder or ValueDecoder for that kind. If no ValueEncoder or
+// ValueDecoder can be found, an error is returned.
+//
+// The Registry also holds a type map. This allows users to retrieve the Go type that should be used
+// when decoding a BSON value into an empty interface. This is primarily only used for the empty
+// interface ValueDecoder.
+//
+// A RegistryBuilder is used to construct a Registry. The Register methods are used to associate
+// either a reflect.Type or a reflect.Kind with a ValueEncoder or ValueDecoder. A RegistryBuilder
+// returned from NewRegistryBuilder contains no registered ValueEncoders nor ValueDecoders and
+// contains an empty type map.
+//
+// The RegisterTypeMapEntry method handles associating a BSON type with a Go type. For example, if
+// you want to decode BSON int64 and int32 values into Go int instances, you would do the following:
+//
+// var regbuilder *RegistryBuilder = ... intType := reflect.TypeOf(int(0))
+// regbuilder.RegisterTypeMapEntry(bsontype.Int64, intType).RegisterTypeMapEntry(bsontype.Int32,
+// intType)
+//
+// 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/github.com/mongodb/mongo-go-driver/bson/bsoncodec/mode.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/mode.go
new file mode 100644
index 0000000..fbd9f0a
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-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/github.com/mongodb/mongo-go-driver/bson/bsoncodec/pointer_codec.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/pointer_codec.go
new file mode 100644
index 0000000..b78ec0a
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/pointer_codec.go
@@ -0,0 +1,110 @@
+// 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"
+
+ "github.com/mongodb/mongo-go-driver/bson/bsonrw"
+ "github.com/mongodb/mongo-go-driver/bson/bsontype"
+)
+
+var defaultPointerCodec = &PointerCodec{
+ ecache: make(map[reflect.Type]ValueEncoder),
+ dcache: make(map[reflect.Type]ValueDecoder),
+}
+
+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 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/github.com/mongodb/mongo-go-driver/bson/bsoncodec/proxy.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/proxy.go
new file mode 100644
index 0000000..4cf2b01
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-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/github.com/mongodb/mongo-go-driver/bson/bsoncodec/registry.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/registry.go
new file mode 100644
index 0000000..741deb8
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/registry.go
@@ -0,0 +1,384 @@
+// 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"
+ "reflect"
+ "sync"
+
+ "github.com/mongodb/mongo-go-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")
+
+var defaultRegistry *Registry
+
+func init() {
+ defaultRegistry = buildDefaultRegistry()
+}
+
+// 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.RegisterEncoder(t, codec)
+ rb.RegisterDecoder(t, codec)
+ return rb
+}
+
+// RegisterEncoder will register the provided ValueEncoder to the provided type.
+//
+// The type registered 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.
+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 will register the provided ValueDecoder to the provided type.
+//
+// The type registered 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.
+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.
+//
+// NOTE: It is unlikely that registering a type for BSON Embedded Document is actually desired. By
+// registering a type map entry for BSON Embedded Document the type registered will be used in any
+// case where a BSON Embedded Document will be decoded into an empty interface. For example, if you
+// register primitive.M, the EmptyInterface decoder will always use primitive.M, even if an ancestor
+// was a primitive.D.
+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 will inspect the registry for an encoder that satisfies the
+// type provided. An encoder registered for a specific type will take
+// precedence over an encoder registered for an interface the type satisfies,
+// which takes precedence over an encoder for the reflect.Kind of the value. If
+// no encoder can be found, an error 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)
+ 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) (ValueEncoder, bool) {
+ if t == nil {
+ return nil, false
+ }
+ for _, ienc := range r.interfaceEncoders {
+ if !t.Implements(ienc.i) {
+ continue
+ }
+
+ return ienc.ve, true
+ }
+ return nil, false
+}
+
+// LookupDecoder will inspect the registry for a decoder that satisfies the
+// type provided. A decoder registered for a specific type will take
+// precedence over a decoder registered for an interface the type satisfies,
+// which takes precedence over a decoder for the reflect.Kind of the value. If
+// no decoder can be found, an error 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)
+ 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) (ValueDecoder, bool) {
+ for _, idec := range r.interfaceDecoders {
+ if !t.Implements(idec.i) && !reflect.PtrTo(t).Implements(idec.i) {
+ continue
+ }
+
+ return idec.vd, 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/github.com/mongodb/mongo-go-driver/bson/bsoncodec/struct_codec.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/struct_codec.go
new file mode 100644
index 0000000..34f3b4c
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/struct_codec.go
@@ -0,0 +1,357 @@
+// 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"
+
+ "github.com/mongodb/mongo-go-driver/bson/bsonrw"
+ "github.com/mongodb/mongo-go-driver/bson/bsontype"
+)
+
+var defaultStructCodec = &StructCodec{
+ cache: make(map[reflect.Type]*structDescription),
+ parser: DefaultStructTagParser,
+}
+
+// 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
+}
+
+var _ ValueEncoder = &StructCodec{}
+var _ ValueDecoder = &StructCodec{}
+
+// NewStructCodec returns a StructCodec that uses p for struct tag parsing.
+func NewStructCodec(p StructTagParser) (*StructCodec, error) {
+ if p == nil {
+ return nil, errors.New("a StructTagParser must be provided to NewStructCodec")
+ }
+
+ return &StructCodec{
+ cache: make(map[reflect.Type]*structDescription),
+ parser: p,
+ }, 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 = val.FieldByIndex(desc.inline)
+ }
+
+ if desc.encoder == nil {
+ return ErrNoEncoder{Type: rv.Type()}
+ }
+
+ encoder := desc.encoder
+
+ iszero := sc.isZero
+ if iz, ok := encoder.(CodecZeroer); ok {
+ iszero = iz.IsTypeZero
+ }
+
+ if desc.omitEmpty && iszero(rv.Interface()) {
+ 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 defaultValueEncoders.mapEncodeValue(r, dw, rv, collisionFn)
+ }
+
+ return dw.WriteDocumentEnd()
+}
+
+// DecodeValue implements the Codec interface.
+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 vr.Type() {
+ case bsontype.Type(0), bsontype.EmbeddedDocument:
+ default:
+ return fmt.Errorf("cannot decode %v into a %s", vr.Type(), val.Type())
+ }
+
+ sd, err := sc.describeStruct(r.Registry, val.Type())
+ if err != nil {
+ return err
+ }
+
+ var decoder ValueDecoder
+ var inlineMap reflect.Value
+ if sd.inlineMap >= 0 {
+ inlineMap = val.Field(sd.inlineMap)
+ if inlineMap.IsNil() {
+ inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
+ }
+ 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 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
+ }
+
+ elem := reflect.New(inlineMap.Type().Elem()).Elem()
+ 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 = val.FieldByIndex(fd.inline)
+ }
+
+ if !field.CanSet() { // Being settable is a super set of being addressable.
+ return fmt.Errorf("cannot decode element '%s' into field %v; it is not settable", name, field)
+ }
+ 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}
+ if fd.decoder == nil {
+ return ErrNoDecoder{Type: field.Elem().Type()}
+ }
+
+ if decoder, ok := fd.decoder.(ValueDecoder); ok {
+ err = decoder.DecodeValue(dctx, vr, field.Elem())
+ if err != nil {
+ return err
+ }
+ continue
+ }
+ err = fd.decoder.DecodeValue(dctx, vr, field)
+ if err != nil {
+ return 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()
+ }
+
+ return false
+}
+
+type structDescription struct {
+ fm map[string]fieldDescription
+ fl []fieldDescription
+ inlineMap int
+}
+
+type fieldDescription struct {
+ name string
+ idx int
+ omitEmpty bool
+ minSize bool
+ truncate bool
+ inline []int
+ encoder ValueEncoder
+ decoder ValueDecoder
+}
+
+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,
+ }
+
+ for i := 0; i < numFields; i++ {
+ sf := t.Field(i)
+ if sf.PkgPath != "" {
+ // unexported, ignore
+ continue
+ }
+
+ encoder, err := r.LookupEncoder(sf.Type)
+ if err != nil {
+ encoder = nil
+ }
+ decoder, err := r.LookupDecoder(sf.Type)
+ if err != nil {
+ decoder = nil
+ }
+
+ description := fieldDescription{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 {
+ switch sf.Type.Kind() {
+ case reflect.Map:
+ if sd.inlineMap >= 0 {
+ return nil, errors.New("(struct " + t.String() + ") multiple inline maps")
+ }
+ if sf.Type.Key() != tString {
+ return nil, errors.New("(struct " + t.String() + ") inline map must have a string keys")
+ }
+ sd.inlineMap = description.idx
+ case reflect.Struct:
+ inlinesf, err := sc.describeStruct(r, sf.Type)
+ if err != nil {
+ return nil, err
+ }
+ for _, fd := range inlinesf.fl {
+ if _, exists := sd.fm[fd.name]; exists {
+ return nil, fmt.Errorf("(struct %s) duplicated key %s", t.String(), fd.name)
+ }
+ if fd.inline == nil {
+ fd.inline = []int{i, fd.idx}
+ } else {
+ fd.inline = append([]int{i}, fd.inline...)
+ }
+ sd.fm[fd.name] = fd
+ sd.fl = append(sd.fl, fd)
+ }
+ default:
+ return nil, fmt.Errorf("(struct %s) inline fields must be either a struct or a map", t.String())
+ }
+ continue
+ }
+
+ if _, exists := sd.fm[description.name]; exists {
+ return nil, fmt.Errorf("struct %s) duplicated key %s", t.String(), description.name)
+ }
+
+ sd.fm[description.name] = description
+ sd.fl = append(sd.fl, description)
+ }
+
+ sc.l.Lock()
+ sc.cache[t] = sd
+ sc.l.Unlock()
+
+ return sd, nil
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/struct_tag_parser.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/struct_tag_parser.go
new file mode 100644
index 0000000..69d0ae4
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/struct_tag_parser.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 (
+ "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)
+ }
+ 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
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/types.go b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/types.go
new file mode 100644
index 0000000..c349a94
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/bson/bsoncodec/types.go
@@ -0,0 +1,80 @@
+// 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"
+
+ "github.com/mongodb/mongo-go-driver/bson/primitive"
+ "github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore"
+)
+
+var ptBool = reflect.TypeOf((*bool)(nil))
+var ptInt8 = reflect.TypeOf((*int8)(nil))
+var ptInt16 = reflect.TypeOf((*int16)(nil))
+var ptInt32 = reflect.TypeOf((*int32)(nil))
+var ptInt64 = reflect.TypeOf((*int64)(nil))
+var ptInt = reflect.TypeOf((*int)(nil))
+var ptUint8 = reflect.TypeOf((*uint8)(nil))
+var ptUint16 = reflect.TypeOf((*uint16)(nil))
+var ptUint32 = reflect.TypeOf((*uint32)(nil))
+var ptUint64 = reflect.TypeOf((*uint64)(nil))
+var ptUint = reflect.TypeOf((*uint)(nil))
+var ptFloat32 = reflect.TypeOf((*float32)(nil))
+var ptFloat64 = reflect.TypeOf((*float64)(nil))
+var ptString = reflect.TypeOf((*string)(nil))
+
+var tBool = reflect.TypeOf(false)
+var tFloat32 = reflect.TypeOf(float32(0))
+var tFloat64 = reflect.TypeOf(float64(0))
+var tInt = reflect.TypeOf(int(0))
+var tInt8 = reflect.TypeOf(int8(0))
+var tInt16 = reflect.TypeOf(int16(0))
+var tInt32 = reflect.TypeOf(int32(0))
+var tInt64 = reflect.TypeOf(int64(0))
+var tString = reflect.TypeOf("")
+var tTime = reflect.TypeOf(time.Time{})
+var tUint = reflect.TypeOf(uint(0))
+var tUint8 = reflect.TypeOf(uint8(0))
+var tUint16 = reflect.TypeOf(uint16(0))
+var tUint32 = reflect.TypeOf(uint32(0))
+var tUint64 = reflect.TypeOf(uint64(0))
+
+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{})