default_value_encoders.go raw

   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 && 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 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 && lookupErr != errInvalidValue {
 422  			return lookupErr
 423  		}
 424  
 425  		vw, err := aw.WriteArrayElement()
 426  		if err != nil {
 427  			return err
 428  		}
 429  
 430  		if 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 && lookupErr != errInvalidValue {
 491  			return lookupErr
 492  		}
 493  
 494  		vw, err := aw.WriteArrayElement()
 495  		if err != nil {
 496  			return err
 497  		}
 498  
 499  		if 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