...

Source file src/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go

Documentation: go.mongodb.org/mongo-driver/bson/bsoncodec

     1  // Copyright (C) MongoDB, Inc. 2017-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package bsoncodec
     8  
     9  import (
    10  	"encoding/json"
    11  	"errors"
    12  	"fmt"
    13  	"math"
    14  	"net/url"
    15  	"reflect"
    16  	"sync"
    17  	"time"
    18  
    19  	"go.mongodb.org/mongo-driver/bson/bsonrw"
    20  	"go.mongodb.org/mongo-driver/bson/bsontype"
    21  	"go.mongodb.org/mongo-driver/bson/primitive"
    22  	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
    23  )
    24  
    25  var defaultValueEncoders DefaultValueEncoders
    26  
    27  var bvwPool = bsonrw.NewBSONValueWriterPool()
    28  
    29  var errInvalidValue = errors.New("cannot encode invalid element")
    30  
    31  var sliceWriterPool = sync.Pool{
    32  	New: func() interface{} {
    33  		sw := make(bsonrw.SliceWriter, 0)
    34  		return &sw
    35  	},
    36  }
    37  
    38  func encodeElement(ec EncodeContext, dw bsonrw.DocumentWriter, e primitive.E) error {
    39  	vw, err := dw.WriteDocumentElement(e.Key)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	if e.Value == nil {
    45  		return vw.WriteNull()
    46  	}
    47  	encoder, err := ec.LookupEncoder(reflect.TypeOf(e.Value))
    48  	if err != nil {
    49  		return err
    50  	}
    51  
    52  	err = encoder.EncodeValue(ec, vw, reflect.ValueOf(e.Value))
    53  	if err != nil {
    54  		return err
    55  	}
    56  	return nil
    57  }
    58  
    59  // DefaultValueEncoders is a namespace type for the default ValueEncoders used
    60  // when creating a registry.
    61  //
    62  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
    63  // value encoders registered.
    64  type DefaultValueEncoders struct{}
    65  
    66  // RegisterDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with
    67  // the provided RegistryBuilder.
    68  //
    69  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
    70  // value encoders registered.
    71  func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) {
    72  	if rb == nil {
    73  		panic(errors.New("argument to RegisterDefaultEncoders must not be nil"))
    74  	}
    75  	rb.
    76  		RegisterTypeEncoder(tByteSlice, defaultByteSliceCodec).
    77  		RegisterTypeEncoder(tTime, defaultTimeCodec).
    78  		RegisterTypeEncoder(tEmpty, defaultEmptyInterfaceCodec).
    79  		RegisterTypeEncoder(tCoreArray, defaultArrayCodec).
    80  		RegisterTypeEncoder(tOID, ValueEncoderFunc(dve.ObjectIDEncodeValue)).
    81  		RegisterTypeEncoder(tDecimal, ValueEncoderFunc(dve.Decimal128EncodeValue)).
    82  		RegisterTypeEncoder(tJSONNumber, ValueEncoderFunc(dve.JSONNumberEncodeValue)).
    83  		RegisterTypeEncoder(tURL, ValueEncoderFunc(dve.URLEncodeValue)).
    84  		RegisterTypeEncoder(tJavaScript, ValueEncoderFunc(dve.JavaScriptEncodeValue)).
    85  		RegisterTypeEncoder(tSymbol, ValueEncoderFunc(dve.SymbolEncodeValue)).
    86  		RegisterTypeEncoder(tBinary, ValueEncoderFunc(dve.BinaryEncodeValue)).
    87  		RegisterTypeEncoder(tUndefined, ValueEncoderFunc(dve.UndefinedEncodeValue)).
    88  		RegisterTypeEncoder(tDateTime, ValueEncoderFunc(dve.DateTimeEncodeValue)).
    89  		RegisterTypeEncoder(tNull, ValueEncoderFunc(dve.NullEncodeValue)).
    90  		RegisterTypeEncoder(tRegex, ValueEncoderFunc(dve.RegexEncodeValue)).
    91  		RegisterTypeEncoder(tDBPointer, ValueEncoderFunc(dve.DBPointerEncodeValue)).
    92  		RegisterTypeEncoder(tTimestamp, ValueEncoderFunc(dve.TimestampEncodeValue)).
    93  		RegisterTypeEncoder(tMinKey, ValueEncoderFunc(dve.MinKeyEncodeValue)).
    94  		RegisterTypeEncoder(tMaxKey, ValueEncoderFunc(dve.MaxKeyEncodeValue)).
    95  		RegisterTypeEncoder(tCoreDocument, ValueEncoderFunc(dve.CoreDocumentEncodeValue)).
    96  		RegisterTypeEncoder(tCodeWithScope, ValueEncoderFunc(dve.CodeWithScopeEncodeValue)).
    97  		RegisterDefaultEncoder(reflect.Bool, ValueEncoderFunc(dve.BooleanEncodeValue)).
    98  		RegisterDefaultEncoder(reflect.Int, ValueEncoderFunc(dve.IntEncodeValue)).
    99  		RegisterDefaultEncoder(reflect.Int8, ValueEncoderFunc(dve.IntEncodeValue)).
   100  		RegisterDefaultEncoder(reflect.Int16, ValueEncoderFunc(dve.IntEncodeValue)).
   101  		RegisterDefaultEncoder(reflect.Int32, ValueEncoderFunc(dve.IntEncodeValue)).
   102  		RegisterDefaultEncoder(reflect.Int64, ValueEncoderFunc(dve.IntEncodeValue)).
   103  		RegisterDefaultEncoder(reflect.Uint, defaultUIntCodec).
   104  		RegisterDefaultEncoder(reflect.Uint8, defaultUIntCodec).
   105  		RegisterDefaultEncoder(reflect.Uint16, defaultUIntCodec).
   106  		RegisterDefaultEncoder(reflect.Uint32, defaultUIntCodec).
   107  		RegisterDefaultEncoder(reflect.Uint64, defaultUIntCodec).
   108  		RegisterDefaultEncoder(reflect.Float32, ValueEncoderFunc(dve.FloatEncodeValue)).
   109  		RegisterDefaultEncoder(reflect.Float64, ValueEncoderFunc(dve.FloatEncodeValue)).
   110  		RegisterDefaultEncoder(reflect.Array, ValueEncoderFunc(dve.ArrayEncodeValue)).
   111  		RegisterDefaultEncoder(reflect.Map, defaultMapCodec).
   112  		RegisterDefaultEncoder(reflect.Slice, defaultSliceCodec).
   113  		RegisterDefaultEncoder(reflect.String, defaultStringCodec).
   114  		RegisterDefaultEncoder(reflect.Struct, newDefaultStructCodec()).
   115  		RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec()).
   116  		RegisterHookEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)).
   117  		RegisterHookEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)).
   118  		RegisterHookEncoder(tProxy, ValueEncoderFunc(dve.ProxyEncodeValue))
   119  }
   120  
   121  // BooleanEncodeValue is the ValueEncoderFunc for bool types.
   122  //
   123  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   124  // value encoders registered.
   125  func (dve DefaultValueEncoders) BooleanEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   126  	if !val.IsValid() || val.Kind() != reflect.Bool {
   127  		return ValueEncoderError{Name: "BooleanEncodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val}
   128  	}
   129  	return vw.WriteBoolean(val.Bool())
   130  }
   131  
   132  func fitsIn32Bits(i int64) bool {
   133  	return math.MinInt32 <= i && i <= math.MaxInt32
   134  }
   135  
   136  // IntEncodeValue is the ValueEncoderFunc for int types.
   137  //
   138  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   139  // value encoders registered.
   140  func (dve DefaultValueEncoders) IntEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   141  	switch val.Kind() {
   142  	case reflect.Int8, reflect.Int16, reflect.Int32:
   143  		return vw.WriteInt32(int32(val.Int()))
   144  	case reflect.Int:
   145  		i64 := val.Int()
   146  		if fitsIn32Bits(i64) {
   147  			return vw.WriteInt32(int32(i64))
   148  		}
   149  		return vw.WriteInt64(i64)
   150  	case reflect.Int64:
   151  		i64 := val.Int()
   152  		if ec.MinSize && fitsIn32Bits(i64) {
   153  			return vw.WriteInt32(int32(i64))
   154  		}
   155  		return vw.WriteInt64(i64)
   156  	}
   157  
   158  	return ValueEncoderError{
   159  		Name:     "IntEncodeValue",
   160  		Kinds:    []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
   161  		Received: val,
   162  	}
   163  }
   164  
   165  // UintEncodeValue is the ValueEncoderFunc for uint types.
   166  //
   167  // Deprecated: UintEncodeValue is not registered by default. Use UintCodec.EncodeValue instead.
   168  func (dve DefaultValueEncoders) UintEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   169  	switch val.Kind() {
   170  	case reflect.Uint8, reflect.Uint16:
   171  		return vw.WriteInt32(int32(val.Uint()))
   172  	case reflect.Uint, reflect.Uint32, reflect.Uint64:
   173  		u64 := val.Uint()
   174  		if ec.MinSize && u64 <= math.MaxInt32 {
   175  			return vw.WriteInt32(int32(u64))
   176  		}
   177  		if u64 > math.MaxInt64 {
   178  			return fmt.Errorf("%d overflows int64", u64)
   179  		}
   180  		return vw.WriteInt64(int64(u64))
   181  	}
   182  
   183  	return ValueEncoderError{
   184  		Name:     "UintEncodeValue",
   185  		Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
   186  		Received: val,
   187  	}
   188  }
   189  
   190  // FloatEncodeValue is the ValueEncoderFunc for float types.
   191  //
   192  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   193  // value encoders registered.
   194  func (dve DefaultValueEncoders) FloatEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   195  	switch val.Kind() {
   196  	case reflect.Float32, reflect.Float64:
   197  		return vw.WriteDouble(val.Float())
   198  	}
   199  
   200  	return ValueEncoderError{Name: "FloatEncodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val}
   201  }
   202  
   203  // StringEncodeValue is the ValueEncoderFunc for string types.
   204  //
   205  // Deprecated: StringEncodeValue is not registered by default. Use StringCodec.EncodeValue instead.
   206  func (dve DefaultValueEncoders) StringEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   207  	if val.Kind() != reflect.String {
   208  		return ValueEncoderError{
   209  			Name:     "StringEncodeValue",
   210  			Kinds:    []reflect.Kind{reflect.String},
   211  			Received: val,
   212  		}
   213  	}
   214  
   215  	return vw.WriteString(val.String())
   216  }
   217  
   218  // ObjectIDEncodeValue is the ValueEncoderFunc for primitive.ObjectID.
   219  //
   220  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   221  // value encoders registered.
   222  func (dve DefaultValueEncoders) ObjectIDEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   223  	if !val.IsValid() || val.Type() != tOID {
   224  		return ValueEncoderError{Name: "ObjectIDEncodeValue", Types: []reflect.Type{tOID}, Received: val}
   225  	}
   226  	return vw.WriteObjectID(val.Interface().(primitive.ObjectID))
   227  }
   228  
   229  // Decimal128EncodeValue is the ValueEncoderFunc for primitive.Decimal128.
   230  //
   231  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   232  // value encoders registered.
   233  func (dve DefaultValueEncoders) Decimal128EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   234  	if !val.IsValid() || val.Type() != tDecimal {
   235  		return ValueEncoderError{Name: "Decimal128EncodeValue", Types: []reflect.Type{tDecimal}, Received: val}
   236  	}
   237  	return vw.WriteDecimal128(val.Interface().(primitive.Decimal128))
   238  }
   239  
   240  // JSONNumberEncodeValue is the ValueEncoderFunc for json.Number.
   241  //
   242  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   243  // value encoders registered.
   244  func (dve DefaultValueEncoders) JSONNumberEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   245  	if !val.IsValid() || val.Type() != tJSONNumber {
   246  		return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: val}
   247  	}
   248  	jsnum := val.Interface().(json.Number)
   249  
   250  	// Attempt int first, then float64
   251  	if i64, err := jsnum.Int64(); err == nil {
   252  		return dve.IntEncodeValue(ec, vw, reflect.ValueOf(i64))
   253  	}
   254  
   255  	f64, err := jsnum.Float64()
   256  	if err != nil {
   257  		return err
   258  	}
   259  
   260  	return dve.FloatEncodeValue(ec, vw, reflect.ValueOf(f64))
   261  }
   262  
   263  // URLEncodeValue is the ValueEncoderFunc for url.URL.
   264  //
   265  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   266  // value encoders registered.
   267  func (dve DefaultValueEncoders) URLEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   268  	if !val.IsValid() || val.Type() != tURL {
   269  		return ValueEncoderError{Name: "URLEncodeValue", Types: []reflect.Type{tURL}, Received: val}
   270  	}
   271  	u := val.Interface().(url.URL)
   272  	return vw.WriteString(u.String())
   273  }
   274  
   275  // TimeEncodeValue is the ValueEncoderFunc for time.TIme.
   276  //
   277  // Deprecated: TimeEncodeValue is not registered by default. Use TimeCodec.EncodeValue instead.
   278  func (dve DefaultValueEncoders) TimeEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   279  	if !val.IsValid() || val.Type() != tTime {
   280  		return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
   281  	}
   282  	tt := val.Interface().(time.Time)
   283  	dt := primitive.NewDateTimeFromTime(tt)
   284  	return vw.WriteDateTime(int64(dt))
   285  }
   286  
   287  // ByteSliceEncodeValue is the ValueEncoderFunc for []byte.
   288  //
   289  // Deprecated: ByteSliceEncodeValue is not registered by default. Use ByteSliceCodec.EncodeValue instead.
   290  func (dve DefaultValueEncoders) ByteSliceEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   291  	if !val.IsValid() || val.Type() != tByteSlice {
   292  		return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
   293  	}
   294  	if val.IsNil() {
   295  		return vw.WriteNull()
   296  	}
   297  	return vw.WriteBinary(val.Interface().([]byte))
   298  }
   299  
   300  // MapEncodeValue is the ValueEncoderFunc for map[string]* types.
   301  //
   302  // Deprecated: MapEncodeValue is not registered by default. Use MapCodec.EncodeValue instead.
   303  func (dve DefaultValueEncoders) MapEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   304  	if !val.IsValid() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String {
   305  		return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
   306  	}
   307  
   308  	if val.IsNil() {
   309  		// If we have a nill map but we can't WriteNull, that means we're probably trying to encode
   310  		// to a TopLevel document. We can't currently tell if this is what actually happened, but if
   311  		// there's a deeper underlying problem, the error will also be returned from WriteDocument,
   312  		// so just continue. The operations on a map reflection value are valid, so we can call
   313  		// MapKeys within mapEncodeValue without a problem.
   314  		err := vw.WriteNull()
   315  		if err == nil {
   316  			return nil
   317  		}
   318  	}
   319  
   320  	dw, err := vw.WriteDocument()
   321  	if err != nil {
   322  		return err
   323  	}
   324  
   325  	return dve.mapEncodeValue(ec, dw, val, nil)
   326  }
   327  
   328  // mapEncodeValue handles encoding of the values of a map. The collisionFn returns
   329  // true if the provided key exists, this is mainly used for inline maps in the
   330  // struct codec.
   331  func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error {
   332  
   333  	elemType := val.Type().Elem()
   334  	encoder, err := ec.LookupEncoder(elemType)
   335  	if err != nil && elemType.Kind() != reflect.Interface {
   336  		return err
   337  	}
   338  
   339  	keys := val.MapKeys()
   340  	for _, key := range keys {
   341  		if collisionFn != nil && collisionFn(key.String()) {
   342  			return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key)
   343  		}
   344  
   345  		currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.MapIndex(key))
   346  		if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
   347  			return lookupErr
   348  		}
   349  
   350  		vw, err := dw.WriteDocumentElement(key.String())
   351  		if err != nil {
   352  			return err
   353  		}
   354  
   355  		if errors.Is(lookupErr, errInvalidValue) {
   356  			err = vw.WriteNull()
   357  			if err != nil {
   358  				return err
   359  			}
   360  			continue
   361  		}
   362  
   363  		err = currEncoder.EncodeValue(ec, vw, currVal)
   364  		if err != nil {
   365  			return err
   366  		}
   367  	}
   368  
   369  	return dw.WriteDocumentEnd()
   370  }
   371  
   372  // ArrayEncodeValue is the ValueEncoderFunc for array types.
   373  //
   374  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   375  // value encoders registered.
   376  func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   377  	if !val.IsValid() || val.Kind() != reflect.Array {
   378  		return ValueEncoderError{Name: "ArrayEncodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val}
   379  	}
   380  
   381  	// If we have a []primitive.E we want to treat it as a document instead of as an array.
   382  	if val.Type().Elem() == tE {
   383  		dw, err := vw.WriteDocument()
   384  		if err != nil {
   385  			return err
   386  		}
   387  
   388  		for idx := 0; idx < val.Len(); idx++ {
   389  			e := val.Index(idx).Interface().(primitive.E)
   390  			err = encodeElement(ec, dw, e)
   391  			if err != nil {
   392  				return err
   393  			}
   394  		}
   395  
   396  		return dw.WriteDocumentEnd()
   397  	}
   398  
   399  	// If we have a []byte we want to treat it as a binary instead of as an array.
   400  	if val.Type().Elem() == tByte {
   401  		var byteSlice []byte
   402  		for idx := 0; idx < val.Len(); idx++ {
   403  			byteSlice = append(byteSlice, val.Index(idx).Interface().(byte))
   404  		}
   405  		return vw.WriteBinary(byteSlice)
   406  	}
   407  
   408  	aw, err := vw.WriteArray()
   409  	if err != nil {
   410  		return err
   411  	}
   412  
   413  	elemType := val.Type().Elem()
   414  	encoder, err := ec.LookupEncoder(elemType)
   415  	if err != nil && elemType.Kind() != reflect.Interface {
   416  		return err
   417  	}
   418  
   419  	for idx := 0; idx < val.Len(); idx++ {
   420  		currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx))
   421  		if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
   422  			return lookupErr
   423  		}
   424  
   425  		vw, err := aw.WriteArrayElement()
   426  		if err != nil {
   427  			return err
   428  		}
   429  
   430  		if errors.Is(lookupErr, errInvalidValue) {
   431  			err = vw.WriteNull()
   432  			if err != nil {
   433  				return err
   434  			}
   435  			continue
   436  		}
   437  
   438  		err = currEncoder.EncodeValue(ec, vw, currVal)
   439  		if err != nil {
   440  			return err
   441  		}
   442  	}
   443  	return aw.WriteArrayEnd()
   444  }
   445  
   446  // SliceEncodeValue is the ValueEncoderFunc for slice types.
   447  //
   448  // Deprecated: SliceEncodeValue is not registered by default. Use SliceCodec.EncodeValue instead.
   449  func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   450  	if !val.IsValid() || val.Kind() != reflect.Slice {
   451  		return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
   452  	}
   453  
   454  	if val.IsNil() {
   455  		return vw.WriteNull()
   456  	}
   457  
   458  	// If we have a []primitive.E we want to treat it as a document instead of as an array.
   459  	if val.Type().ConvertibleTo(tD) {
   460  		d := val.Convert(tD).Interface().(primitive.D)
   461  
   462  		dw, err := vw.WriteDocument()
   463  		if err != nil {
   464  			return err
   465  		}
   466  
   467  		for _, e := range d {
   468  			err = encodeElement(ec, dw, e)
   469  			if err != nil {
   470  				return err
   471  			}
   472  		}
   473  
   474  		return dw.WriteDocumentEnd()
   475  	}
   476  
   477  	aw, err := vw.WriteArray()
   478  	if err != nil {
   479  		return err
   480  	}
   481  
   482  	elemType := val.Type().Elem()
   483  	encoder, err := ec.LookupEncoder(elemType)
   484  	if err != nil && elemType.Kind() != reflect.Interface {
   485  		return err
   486  	}
   487  
   488  	for idx := 0; idx < val.Len(); idx++ {
   489  		currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx))
   490  		if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
   491  			return lookupErr
   492  		}
   493  
   494  		vw, err := aw.WriteArrayElement()
   495  		if err != nil {
   496  			return err
   497  		}
   498  
   499  		if errors.Is(lookupErr, errInvalidValue) {
   500  			err = vw.WriteNull()
   501  			if err != nil {
   502  				return err
   503  			}
   504  			continue
   505  		}
   506  
   507  		err = currEncoder.EncodeValue(ec, vw, currVal)
   508  		if err != nil {
   509  			return err
   510  		}
   511  	}
   512  	return aw.WriteArrayEnd()
   513  }
   514  
   515  func (dve DefaultValueEncoders) lookupElementEncoder(ec EncodeContext, origEncoder ValueEncoder, currVal reflect.Value) (ValueEncoder, reflect.Value, error) {
   516  	if origEncoder != nil || (currVal.Kind() != reflect.Interface) {
   517  		return origEncoder, currVal, nil
   518  	}
   519  	currVal = currVal.Elem()
   520  	if !currVal.IsValid() {
   521  		return nil, currVal, errInvalidValue
   522  	}
   523  	currEncoder, err := ec.LookupEncoder(currVal.Type())
   524  
   525  	return currEncoder, currVal, err
   526  }
   527  
   528  // EmptyInterfaceEncodeValue is the ValueEncoderFunc for interface{}.
   529  //
   530  // Deprecated: EmptyInterfaceEncodeValue is not registered by default. Use EmptyInterfaceCodec.EncodeValue instead.
   531  func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   532  	if !val.IsValid() || val.Type() != tEmpty {
   533  		return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val}
   534  	}
   535  
   536  	if val.IsNil() {
   537  		return vw.WriteNull()
   538  	}
   539  	encoder, err := ec.LookupEncoder(val.Elem().Type())
   540  	if err != nil {
   541  		return err
   542  	}
   543  
   544  	return encoder.EncodeValue(ec, vw, val.Elem())
   545  }
   546  
   547  // ValueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations.
   548  //
   549  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   550  // value encoders registered.
   551  func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   552  	// Either val or a pointer to val must implement ValueMarshaler
   553  	switch {
   554  	case !val.IsValid():
   555  		return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val}
   556  	case val.Type().Implements(tValueMarshaler):
   557  		// If ValueMarshaler is implemented on a concrete type, make sure that val isn't a nil pointer
   558  		if isImplementationNil(val, tValueMarshaler) {
   559  			return vw.WriteNull()
   560  		}
   561  	case reflect.PtrTo(val.Type()).Implements(tValueMarshaler) && val.CanAddr():
   562  		val = val.Addr()
   563  	default:
   564  		return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val}
   565  	}
   566  
   567  	m, ok := val.Interface().(ValueMarshaler)
   568  	if !ok {
   569  		return vw.WriteNull()
   570  	}
   571  	t, data, err := m.MarshalBSONValue()
   572  	if err != nil {
   573  		return err
   574  	}
   575  	return bsonrw.Copier{}.CopyValueFromBytes(vw, t, data)
   576  }
   577  
   578  // MarshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations.
   579  //
   580  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   581  // value encoders registered.
   582  func (dve DefaultValueEncoders) MarshalerEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   583  	// Either val or a pointer to val must implement Marshaler
   584  	switch {
   585  	case !val.IsValid():
   586  		return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val}
   587  	case val.Type().Implements(tMarshaler):
   588  		// If Marshaler is implemented on a concrete type, make sure that val isn't a nil pointer
   589  		if isImplementationNil(val, tMarshaler) {
   590  			return vw.WriteNull()
   591  		}
   592  	case reflect.PtrTo(val.Type()).Implements(tMarshaler) && val.CanAddr():
   593  		val = val.Addr()
   594  	default:
   595  		return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val}
   596  	}
   597  
   598  	m, ok := val.Interface().(Marshaler)
   599  	if !ok {
   600  		return vw.WriteNull()
   601  	}
   602  	data, err := m.MarshalBSON()
   603  	if err != nil {
   604  		return err
   605  	}
   606  	return bsonrw.Copier{}.CopyValueFromBytes(vw, bsontype.EmbeddedDocument, data)
   607  }
   608  
   609  // ProxyEncodeValue is the ValueEncoderFunc for Proxy implementations.
   610  //
   611  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   612  // value encoders registered.
   613  func (dve DefaultValueEncoders) ProxyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   614  	// Either val or a pointer to val must implement Proxy
   615  	switch {
   616  	case !val.IsValid():
   617  		return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val}
   618  	case val.Type().Implements(tProxy):
   619  		// If Proxy is implemented on a concrete type, make sure that val isn't a nil pointer
   620  		if isImplementationNil(val, tProxy) {
   621  			return vw.WriteNull()
   622  		}
   623  	case reflect.PtrTo(val.Type()).Implements(tProxy) && val.CanAddr():
   624  		val = val.Addr()
   625  	default:
   626  		return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val}
   627  	}
   628  
   629  	m, ok := val.Interface().(Proxy)
   630  	if !ok {
   631  		return vw.WriteNull()
   632  	}
   633  	v, err := m.ProxyBSON()
   634  	if err != nil {
   635  		return err
   636  	}
   637  	if v == nil {
   638  		encoder, err := ec.LookupEncoder(nil)
   639  		if err != nil {
   640  			return err
   641  		}
   642  		return encoder.EncodeValue(ec, vw, reflect.ValueOf(nil))
   643  	}
   644  	vv := reflect.ValueOf(v)
   645  	switch vv.Kind() {
   646  	case reflect.Ptr, reflect.Interface:
   647  		vv = vv.Elem()
   648  	}
   649  	encoder, err := ec.LookupEncoder(vv.Type())
   650  	if err != nil {
   651  		return err
   652  	}
   653  	return encoder.EncodeValue(ec, vw, vv)
   654  }
   655  
   656  // JavaScriptEncodeValue is the ValueEncoderFunc for the primitive.JavaScript type.
   657  //
   658  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   659  // value encoders registered.
   660  func (DefaultValueEncoders) JavaScriptEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   661  	if !val.IsValid() || val.Type() != tJavaScript {
   662  		return ValueEncoderError{Name: "JavaScriptEncodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
   663  	}
   664  
   665  	return vw.WriteJavascript(val.String())
   666  }
   667  
   668  // SymbolEncodeValue is the ValueEncoderFunc for the primitive.Symbol type.
   669  //
   670  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   671  // value encoders registered.
   672  func (DefaultValueEncoders) SymbolEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   673  	if !val.IsValid() || val.Type() != tSymbol {
   674  		return ValueEncoderError{Name: "SymbolEncodeValue", Types: []reflect.Type{tSymbol}, Received: val}
   675  	}
   676  
   677  	return vw.WriteSymbol(val.String())
   678  }
   679  
   680  // BinaryEncodeValue is the ValueEncoderFunc for Binary.
   681  //
   682  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   683  // value encoders registered.
   684  func (DefaultValueEncoders) BinaryEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   685  	if !val.IsValid() || val.Type() != tBinary {
   686  		return ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val}
   687  	}
   688  	b := val.Interface().(primitive.Binary)
   689  
   690  	return vw.WriteBinaryWithSubtype(b.Data, b.Subtype)
   691  }
   692  
   693  // UndefinedEncodeValue is the ValueEncoderFunc for Undefined.
   694  //
   695  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   696  // value encoders registered.
   697  func (DefaultValueEncoders) UndefinedEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   698  	if !val.IsValid() || val.Type() != tUndefined {
   699  		return ValueEncoderError{Name: "UndefinedEncodeValue", Types: []reflect.Type{tUndefined}, Received: val}
   700  	}
   701  
   702  	return vw.WriteUndefined()
   703  }
   704  
   705  // DateTimeEncodeValue is the ValueEncoderFunc for DateTime.
   706  //
   707  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   708  // value encoders registered.
   709  func (DefaultValueEncoders) DateTimeEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   710  	if !val.IsValid() || val.Type() != tDateTime {
   711  		return ValueEncoderError{Name: "DateTimeEncodeValue", Types: []reflect.Type{tDateTime}, Received: val}
   712  	}
   713  
   714  	return vw.WriteDateTime(val.Int())
   715  }
   716  
   717  // NullEncodeValue is the ValueEncoderFunc for Null.
   718  //
   719  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   720  // value encoders registered.
   721  func (DefaultValueEncoders) NullEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   722  	if !val.IsValid() || val.Type() != tNull {
   723  		return ValueEncoderError{Name: "NullEncodeValue", Types: []reflect.Type{tNull}, Received: val}
   724  	}
   725  
   726  	return vw.WriteNull()
   727  }
   728  
   729  // RegexEncodeValue is the ValueEncoderFunc for Regex.
   730  //
   731  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   732  // value encoders registered.
   733  func (DefaultValueEncoders) RegexEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   734  	if !val.IsValid() || val.Type() != tRegex {
   735  		return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val}
   736  	}
   737  
   738  	regex := val.Interface().(primitive.Regex)
   739  
   740  	return vw.WriteRegex(regex.Pattern, regex.Options)
   741  }
   742  
   743  // DBPointerEncodeValue is the ValueEncoderFunc for DBPointer.
   744  //
   745  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   746  // value encoders registered.
   747  func (DefaultValueEncoders) DBPointerEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   748  	if !val.IsValid() || val.Type() != tDBPointer {
   749  		return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val}
   750  	}
   751  
   752  	dbp := val.Interface().(primitive.DBPointer)
   753  
   754  	return vw.WriteDBPointer(dbp.DB, dbp.Pointer)
   755  }
   756  
   757  // TimestampEncodeValue is the ValueEncoderFunc for Timestamp.
   758  //
   759  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   760  // value encoders registered.
   761  func (DefaultValueEncoders) TimestampEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   762  	if !val.IsValid() || val.Type() != tTimestamp {
   763  		return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val}
   764  	}
   765  
   766  	ts := val.Interface().(primitive.Timestamp)
   767  
   768  	return vw.WriteTimestamp(ts.T, ts.I)
   769  }
   770  
   771  // MinKeyEncodeValue is the ValueEncoderFunc for MinKey.
   772  //
   773  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   774  // value encoders registered.
   775  func (DefaultValueEncoders) MinKeyEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   776  	if !val.IsValid() || val.Type() != tMinKey {
   777  		return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: val}
   778  	}
   779  
   780  	return vw.WriteMinKey()
   781  }
   782  
   783  // MaxKeyEncodeValue is the ValueEncoderFunc for MaxKey.
   784  //
   785  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   786  // value encoders registered.
   787  func (DefaultValueEncoders) MaxKeyEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   788  	if !val.IsValid() || val.Type() != tMaxKey {
   789  		return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: val}
   790  	}
   791  
   792  	return vw.WriteMaxKey()
   793  }
   794  
   795  // CoreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document.
   796  //
   797  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   798  // value encoders registered.
   799  func (DefaultValueEncoders) CoreDocumentEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   800  	if !val.IsValid() || val.Type() != tCoreDocument {
   801  		return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: val}
   802  	}
   803  
   804  	cdoc := val.Interface().(bsoncore.Document)
   805  
   806  	return bsonrw.Copier{}.CopyDocumentFromBytes(vw, cdoc)
   807  }
   808  
   809  // CodeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope.
   810  //
   811  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
   812  // value encoders registered.
   813  func (dve DefaultValueEncoders) CodeWithScopeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
   814  	if !val.IsValid() || val.Type() != tCodeWithScope {
   815  		return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val}
   816  	}
   817  
   818  	cws := val.Interface().(primitive.CodeWithScope)
   819  
   820  	dw, err := vw.WriteCodeWithScope(string(cws.Code))
   821  	if err != nil {
   822  		return err
   823  	}
   824  
   825  	sw := sliceWriterPool.Get().(*bsonrw.SliceWriter)
   826  	defer sliceWriterPool.Put(sw)
   827  	*sw = (*sw)[:0]
   828  
   829  	scopeVW := bvwPool.Get(sw)
   830  	defer bvwPool.Put(scopeVW)
   831  
   832  	encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope))
   833  	if err != nil {
   834  		return err
   835  	}
   836  
   837  	err = encoder.EncodeValue(ec, scopeVW, reflect.ValueOf(cws.Scope))
   838  	if err != nil {
   839  		return err
   840  	}
   841  
   842  	err = bsonrw.Copier{}.CopyBytesToDocumentWriter(dw, *sw)
   843  	if err != nil {
   844  		return err
   845  	}
   846  	return dw.WriteDocumentEnd()
   847  }
   848  
   849  // isImplementationNil returns if val is a nil pointer and inter is implemented on a concrete type
   850  func isImplementationNil(val reflect.Value, inter reflect.Type) bool {
   851  	vt := val.Type()
   852  	for vt.Kind() == reflect.Ptr {
   853  		vt = vt.Elem()
   854  	}
   855  	return vt.Implements(inter) && val.Kind() == reflect.Ptr && val.IsNil()
   856  }
   857  

View as plain text