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
7package bsoncodec
8
9import (
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
25var defaultValueEncoders DefaultValueEncoders
26
27var bvwPool = bsonrw.NewBSONValueWriterPool()
28
29var errInvalidValue = errors.New("cannot encode invalid element")
30
31var sliceWriterPool = sync.Pool{
32	New: func() interface{} {
33		sw := make(bsonrw.SliceWriter, 0, 0)
34		return &sw
35	},
36}
37
38func 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.
61type DefaultValueEncoders struct{}
62
63// RegisterDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with
64// the provided RegistryBuilder.
65func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) {
66	if rb == nil {
67		panic(errors.New("argument to RegisterDefaultEncoders must not be nil"))
68	}
69	rb.
70		RegisterEncoder(tByteSlice, ValueEncoderFunc(dve.ByteSliceEncodeValue)).
71		RegisterEncoder(tTime, defaultTimeCodec).
72		RegisterEncoder(tEmpty, ValueEncoderFunc(dve.EmptyInterfaceEncodeValue)).
73		RegisterEncoder(tOID, ValueEncoderFunc(dve.ObjectIDEncodeValue)).
74		RegisterEncoder(tDecimal, ValueEncoderFunc(dve.Decimal128EncodeValue)).
75		RegisterEncoder(tJSONNumber, ValueEncoderFunc(dve.JSONNumberEncodeValue)).
76		RegisterEncoder(tURL, ValueEncoderFunc(dve.URLEncodeValue)).
77		RegisterEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)).
78		RegisterEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)).
79		RegisterEncoder(tProxy, ValueEncoderFunc(dve.ProxyEncodeValue)).
80		RegisterEncoder(tJavaScript, ValueEncoderFunc(dve.JavaScriptEncodeValue)).
81		RegisterEncoder(tSymbol, ValueEncoderFunc(dve.SymbolEncodeValue)).
82		RegisterEncoder(tBinary, ValueEncoderFunc(dve.BinaryEncodeValue)).
83		RegisterEncoder(tUndefined, ValueEncoderFunc(dve.UndefinedEncodeValue)).
84		RegisterEncoder(tDateTime, ValueEncoderFunc(dve.DateTimeEncodeValue)).
85		RegisterEncoder(tNull, ValueEncoderFunc(dve.NullEncodeValue)).
86		RegisterEncoder(tRegex, ValueEncoderFunc(dve.RegexEncodeValue)).
87		RegisterEncoder(tDBPointer, ValueEncoderFunc(dve.DBPointerEncodeValue)).
88		RegisterEncoder(tTimestamp, ValueEncoderFunc(dve.TimestampEncodeValue)).
89		RegisterEncoder(tMinKey, ValueEncoderFunc(dve.MinKeyEncodeValue)).
90		RegisterEncoder(tMaxKey, ValueEncoderFunc(dve.MaxKeyEncodeValue)).
91		RegisterEncoder(tCoreDocument, ValueEncoderFunc(dve.CoreDocumentEncodeValue)).
92		RegisterEncoder(tCodeWithScope, ValueEncoderFunc(dve.CodeWithScopeEncodeValue)).
93		RegisterDefaultEncoder(reflect.Bool, ValueEncoderFunc(dve.BooleanEncodeValue)).
94		RegisterDefaultEncoder(reflect.Int, ValueEncoderFunc(dve.IntEncodeValue)).
95		RegisterDefaultEncoder(reflect.Int8, ValueEncoderFunc(dve.IntEncodeValue)).
96		RegisterDefaultEncoder(reflect.Int16, ValueEncoderFunc(dve.IntEncodeValue)).
97		RegisterDefaultEncoder(reflect.Int32, ValueEncoderFunc(dve.IntEncodeValue)).
98		RegisterDefaultEncoder(reflect.Int64, ValueEncoderFunc(dve.IntEncodeValue)).
99		RegisterDefaultEncoder(reflect.Uint, ValueEncoderFunc(dve.UintEncodeValue)).
100		RegisterDefaultEncoder(reflect.Uint8, ValueEncoderFunc(dve.UintEncodeValue)).
101		RegisterDefaultEncoder(reflect.Uint16, ValueEncoderFunc(dve.UintEncodeValue)).
102		RegisterDefaultEncoder(reflect.Uint32, ValueEncoderFunc(dve.UintEncodeValue)).
103		RegisterDefaultEncoder(reflect.Uint64, ValueEncoderFunc(dve.UintEncodeValue)).
104		RegisterDefaultEncoder(reflect.Float32, ValueEncoderFunc(dve.FloatEncodeValue)).
105		RegisterDefaultEncoder(reflect.Float64, ValueEncoderFunc(dve.FloatEncodeValue)).
106		RegisterDefaultEncoder(reflect.Array, ValueEncoderFunc(dve.ArrayEncodeValue)).
107		RegisterDefaultEncoder(reflect.Map, defaultMapCodec).
108		RegisterDefaultEncoder(reflect.Slice, ValueEncoderFunc(dve.SliceEncodeValue)).
109		RegisterDefaultEncoder(reflect.String, defaultStringCodec).
110		RegisterDefaultEncoder(reflect.Struct, defaultStructCodec).
111		RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec())
112}
113
114// BooleanEncodeValue is the ValueEncoderFunc for bool types.
115func (dve DefaultValueEncoders) BooleanEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
116	if !val.IsValid() || val.Kind() != reflect.Bool {
117		return ValueEncoderError{Name: "BooleanEncodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val}
118	}
119	return vw.WriteBoolean(val.Bool())
120}
121
122func fitsIn32Bits(i int64) bool {
123	return math.MinInt32 <= i && i <= math.MaxInt32
124}
125
126// IntEncodeValue is the ValueEncoderFunc for int types.
127func (dve DefaultValueEncoders) IntEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
128	switch val.Kind() {
129	case reflect.Int8, reflect.Int16, reflect.Int32:
130		return vw.WriteInt32(int32(val.Int()))
131	case reflect.Int:
132		i64 := val.Int()
133		if fitsIn32Bits(i64) {
134			return vw.WriteInt32(int32(i64))
135		}
136		return vw.WriteInt64(i64)
137	case reflect.Int64:
138		i64 := val.Int()
139		if ec.MinSize && fitsIn32Bits(i64) {
140			return vw.WriteInt32(int32(i64))
141		}
142		return vw.WriteInt64(i64)
143	}
144
145	return ValueEncoderError{
146		Name:     "IntEncodeValue",
147		Kinds:    []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
148		Received: val,
149	}
150}
151
152// UintEncodeValue is the ValueEncoderFunc for uint types.
153func (dve DefaultValueEncoders) UintEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
154	switch val.Kind() {
155	case reflect.Uint8, reflect.Uint16:
156		return vw.WriteInt32(int32(val.Uint()))
157	case reflect.Uint, reflect.Uint32, reflect.Uint64:
158		u64 := val.Uint()
159		if ec.MinSize && u64 <= math.MaxInt32 {
160			return vw.WriteInt32(int32(u64))
161		}
162		if u64 > math.MaxInt64 {
163			return fmt.Errorf("%d overflows int64", u64)
164		}
165		return vw.WriteInt64(int64(u64))
166	}
167
168	return ValueEncoderError{
169		Name:     "UintEncodeValue",
170		Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
171		Received: val,
172	}
173}
174
175// FloatEncodeValue is the ValueEncoderFunc for float types.
176func (dve DefaultValueEncoders) FloatEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
177	switch val.Kind() {
178	case reflect.Float32, reflect.Float64:
179		return vw.WriteDouble(val.Float())
180	}
181
182	return ValueEncoderError{Name: "FloatEncodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val}
183}
184
185// StringEncodeValue is the ValueEncoderFunc for string types.
186func (dve DefaultValueEncoders) StringEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
187	if val.Kind() != reflect.String {
188		return ValueEncoderError{
189			Name:     "StringEncodeValue",
190			Kinds:    []reflect.Kind{reflect.String},
191			Received: val,
192		}
193	}
194
195	return vw.WriteString(val.String())
196}
197
198// ObjectIDEncodeValue is the ValueEncoderFunc for primitive.ObjectID.
199func (dve DefaultValueEncoders) ObjectIDEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
200	if !val.IsValid() || val.Type() != tOID {
201		return ValueEncoderError{Name: "ObjectIDEncodeValue", Types: []reflect.Type{tOID}, Received: val}
202	}
203	return vw.WriteObjectID(val.Interface().(primitive.ObjectID))
204}
205
206// Decimal128EncodeValue is the ValueEncoderFunc for primitive.Decimal128.
207func (dve DefaultValueEncoders) Decimal128EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
208	if !val.IsValid() || val.Type() != tDecimal {
209		return ValueEncoderError{Name: "Decimal128EncodeValue", Types: []reflect.Type{tDecimal}, Received: val}
210	}
211	return vw.WriteDecimal128(val.Interface().(primitive.Decimal128))
212}
213
214// JSONNumberEncodeValue is the ValueEncoderFunc for json.Number.
215func (dve DefaultValueEncoders) JSONNumberEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
216	if !val.IsValid() || val.Type() != tJSONNumber {
217		return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: val}
218	}
219	jsnum := val.Interface().(json.Number)
220
221	// Attempt int first, then float64
222	if i64, err := jsnum.Int64(); err == nil {
223		return dve.IntEncodeValue(ec, vw, reflect.ValueOf(i64))
224	}
225
226	f64, err := jsnum.Float64()
227	if err != nil {
228		return err
229	}
230
231	return dve.FloatEncodeValue(ec, vw, reflect.ValueOf(f64))
232}
233
234// URLEncodeValue is the ValueEncoderFunc for url.URL.
235func (dve DefaultValueEncoders) URLEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
236	if !val.IsValid() || val.Type() != tURL {
237		return ValueEncoderError{Name: "URLEncodeValue", Types: []reflect.Type{tURL}, Received: val}
238	}
239	u := val.Interface().(url.URL)
240	return vw.WriteString(u.String())
241}
242
243// TimeEncodeValue is the ValueEncoderFunc for time.TIme.
244func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
245	if !val.IsValid() || val.Type() != tTime {
246		return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
247	}
248	tt := val.Interface().(time.Time)
249	return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6))
250}
251
252// ByteSliceEncodeValue is the ValueEncoderFunc for []byte.
253func (dve DefaultValueEncoders) ByteSliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
254	if !val.IsValid() || val.Type() != tByteSlice {
255		return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
256	}
257	if val.IsNil() {
258		return vw.WriteNull()
259	}
260	return vw.WriteBinary(val.Interface().([]byte))
261}
262
263// MapEncodeValue is the ValueEncoderFunc for map[string]* types.
264func (dve DefaultValueEncoders) MapEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
265	if !val.IsValid() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String {
266		return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
267	}
268
269	if val.IsNil() {
270		// If we have a nill map but we can't WriteNull, that means we're probably trying to encode
271		// to a TopLevel document. We can't currently tell if this is what actually happened, but if
272		// there's a deeper underlying problem, the error will also be returned from WriteDocument,
273		// so just continue. The operations on a map reflection value are valid, so we can call
274		// MapKeys within mapEncodeValue without a problem.
275		err := vw.WriteNull()
276		if err == nil {
277			return nil
278		}
279	}
280
281	dw, err := vw.WriteDocument()
282	if err != nil {
283		return err
284	}
285
286	return dve.mapEncodeValue(ec, dw, val, nil)
287}
288
289// mapEncodeValue handles encoding of the values of a map. The collisionFn returns
290// true if the provided key exists, this is mainly used for inline maps in the
291// struct codec.
292func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error {
293
294	elemType := val.Type().Elem()
295	encoder, err := ec.LookupEncoder(elemType)
296	if err != nil && elemType.Kind() != reflect.Interface {
297		return err
298	}
299
300	keys := val.MapKeys()
301	for _, key := range keys {
302		if collisionFn != nil && collisionFn(key.String()) {
303			return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key)
304		}
305
306		currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.MapIndex(key))
307		if lookupErr != nil && lookupErr != errInvalidValue {
308			return lookupErr
309		}
310
311		vw, err := dw.WriteDocumentElement(key.String())
312		if err != nil {
313			return err
314		}
315
316		if lookupErr == errInvalidValue {
317			err = vw.WriteNull()
318			if err != nil {
319				return err
320			}
321			continue
322		}
323
324		if enc, ok := currEncoder.(ValueEncoder); ok {
325			err = enc.EncodeValue(ec, vw, currVal)
326			if err != nil {
327				return err
328			}
329			continue
330		}
331		err = encoder.EncodeValue(ec, vw, currVal)
332		if err != nil {
333			return err
334		}
335	}
336
337	return dw.WriteDocumentEnd()
338}
339
340// ArrayEncodeValue is the ValueEncoderFunc for array types.
341func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
342	if !val.IsValid() || val.Kind() != reflect.Array {
343		return ValueEncoderError{Name: "ArrayEncodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val}
344	}
345
346	// If we have a []primitive.E we want to treat it as a document instead of as an array.
347	if val.Type().Elem() == tE {
348		dw, err := vw.WriteDocument()
349		if err != nil {
350			return err
351		}
352
353		for idx := 0; idx < val.Len(); idx++ {
354			e := val.Index(idx).Interface().(primitive.E)
355			err = encodeElement(ec, dw, e)
356			if err != nil {
357				return err
358			}
359		}
360
361		return dw.WriteDocumentEnd()
362	}
363
364	aw, err := vw.WriteArray()
365	if err != nil {
366		return err
367	}
368
369	elemType := val.Type().Elem()
370	encoder, err := ec.LookupEncoder(elemType)
371	if err != nil && elemType.Kind() != reflect.Interface {
372		return err
373	}
374
375	for idx := 0; idx < val.Len(); idx++ {
376		currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx))
377		if lookupErr != nil && lookupErr != errInvalidValue {
378			return lookupErr
379		}
380
381		vw, err := aw.WriteArrayElement()
382		if err != nil {
383			return err
384		}
385
386		if lookupErr == errInvalidValue {
387			err = vw.WriteNull()
388			if err != nil {
389				return err
390			}
391			continue
392		}
393
394		err = currEncoder.EncodeValue(ec, vw, currVal)
395		if err != nil {
396			return err
397		}
398	}
399	return aw.WriteArrayEnd()
400}
401
402// SliceEncodeValue is the ValueEncoderFunc for slice types.
403func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
404	if !val.IsValid() || val.Kind() != reflect.Slice {
405		return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
406	}
407
408	if val.IsNil() {
409		return vw.WriteNull()
410	}
411
412	// If we have a []primitive.E we want to treat it as a document instead of as an array.
413	if val.Type().ConvertibleTo(tD) {
414		d := val.Convert(tD).Interface().(primitive.D)
415
416		dw, err := vw.WriteDocument()
417		if err != nil {
418			return err
419		}
420
421		for _, e := range d {
422			err = encodeElement(ec, dw, e)
423			if err != nil {
424				return err
425			}
426		}
427
428		return dw.WriteDocumentEnd()
429	}
430
431	aw, err := vw.WriteArray()
432	if err != nil {
433		return err
434	}
435
436	elemType := val.Type().Elem()
437	encoder, err := ec.LookupEncoder(elemType)
438	if err != nil && elemType.Kind() != reflect.Interface {
439		return err
440	}
441
442	for idx := 0; idx < val.Len(); idx++ {
443		currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx))
444		if lookupErr != nil && lookupErr != errInvalidValue {
445			return lookupErr
446		}
447
448		vw, err := aw.WriteArrayElement()
449		if err != nil {
450			return err
451		}
452
453		if lookupErr == errInvalidValue {
454			err = vw.WriteNull()
455			if err != nil {
456				return err
457			}
458			continue
459		}
460
461		err = currEncoder.EncodeValue(ec, vw, currVal)
462		if err != nil {
463			return err
464		}
465	}
466	return aw.WriteArrayEnd()
467}
468
469func (dve DefaultValueEncoders) lookupElementEncoder(ec EncodeContext, origEncoder ValueEncoder, currVal reflect.Value) (ValueEncoder, reflect.Value, error) {
470	if origEncoder != nil || (currVal.Kind() != reflect.Interface) {
471		return origEncoder, currVal, nil
472	}
473	currVal = currVal.Elem()
474	if !currVal.IsValid() {
475		return nil, currVal, errInvalidValue
476	}
477	currEncoder, err := ec.LookupEncoder(currVal.Type())
478
479	return currEncoder, currVal, err
480}
481
482// EmptyInterfaceEncodeValue is the ValueEncoderFunc for interface{}.
483func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
484	if !val.IsValid() || val.Type() != tEmpty {
485		return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val}
486	}
487
488	if val.IsNil() {
489		return vw.WriteNull()
490	}
491	encoder, err := ec.LookupEncoder(val.Elem().Type())
492	if err != nil {
493		return err
494	}
495
496	return encoder.EncodeValue(ec, vw, val.Elem())
497}
498
499// ValueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations.
500func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
501	if !val.IsValid() || !val.Type().Implements(tValueMarshaler) {
502		return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val}
503	}
504
505	fn := val.Convert(tValueMarshaler).MethodByName("MarshalBSONValue")
506	returns := fn.Call(nil)
507	if !returns[2].IsNil() {
508		return returns[2].Interface().(error)
509	}
510	t, data := returns[0].Interface().(bsontype.Type), returns[1].Interface().([]byte)
511	return bsonrw.Copier{}.CopyValueFromBytes(vw, t, data)
512}
513
514// MarshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations.
515func (dve DefaultValueEncoders) MarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
516	if !val.IsValid() || !val.Type().Implements(tMarshaler) {
517		return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val}
518	}
519
520	fn := val.Convert(tMarshaler).MethodByName("MarshalBSON")
521	returns := fn.Call(nil)
522	if !returns[1].IsNil() {
523		return returns[1].Interface().(error)
524	}
525	data := returns[0].Interface().([]byte)
526	return bsonrw.Copier{}.CopyValueFromBytes(vw, bsontype.EmbeddedDocument, data)
527}
528
529// ProxyEncodeValue is the ValueEncoderFunc for Proxy implementations.
530func (dve DefaultValueEncoders) ProxyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
531	if !val.IsValid() || !val.Type().Implements(tProxy) {
532		return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val}
533	}
534
535	fn := val.Convert(tProxy).MethodByName("ProxyBSON")
536	returns := fn.Call(nil)
537	if !returns[1].IsNil() {
538		return returns[1].Interface().(error)
539	}
540	data := returns[0]
541	var encoder ValueEncoder
542	var err error
543	if data.Elem().IsValid() {
544		encoder, err = ec.LookupEncoder(data.Elem().Type())
545	} else {
546		encoder, err = ec.LookupEncoder(nil)
547	}
548	if err != nil {
549		return err
550	}
551	return encoder.EncodeValue(ec, vw, data.Elem())
552}
553
554// JavaScriptEncodeValue is the ValueEncoderFunc for the primitive.JavaScript type.
555func (DefaultValueEncoders) JavaScriptEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
556	if !val.IsValid() || val.Type() != tJavaScript {
557		return ValueEncoderError{Name: "JavaScriptEncodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
558	}
559
560	return vw.WriteJavascript(val.String())
561}
562
563// SymbolEncodeValue is the ValueEncoderFunc for the primitive.Symbol type.
564func (DefaultValueEncoders) SymbolEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
565	if !val.IsValid() || val.Type() != tSymbol {
566		return ValueEncoderError{Name: "SymbolEncodeValue", Types: []reflect.Type{tSymbol}, Received: val}
567	}
568
569	return vw.WriteSymbol(val.String())
570}
571
572// BinaryEncodeValue is the ValueEncoderFunc for Binary.
573func (DefaultValueEncoders) BinaryEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
574	if !val.IsValid() || val.Type() != tBinary {
575		return ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val}
576	}
577	b := val.Interface().(primitive.Binary)
578
579	return vw.WriteBinaryWithSubtype(b.Data, b.Subtype)
580}
581
582// UndefinedEncodeValue is the ValueEncoderFunc for Undefined.
583func (DefaultValueEncoders) UndefinedEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
584	if !val.IsValid() || val.Type() != tUndefined {
585		return ValueEncoderError{Name: "UndefinedEncodeValue", Types: []reflect.Type{tUndefined}, Received: val}
586	}
587
588	return vw.WriteUndefined()
589}
590
591// DateTimeEncodeValue is the ValueEncoderFunc for DateTime.
592func (DefaultValueEncoders) DateTimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
593	if !val.IsValid() || val.Type() != tDateTime {
594		return ValueEncoderError{Name: "DateTimeEncodeValue", Types: []reflect.Type{tDateTime}, Received: val}
595	}
596
597	return vw.WriteDateTime(val.Int())
598}
599
600// NullEncodeValue is the ValueEncoderFunc for Null.
601func (DefaultValueEncoders) NullEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
602	if !val.IsValid() || val.Type() != tNull {
603		return ValueEncoderError{Name: "NullEncodeValue", Types: []reflect.Type{tNull}, Received: val}
604	}
605
606	return vw.WriteNull()
607}
608
609// RegexEncodeValue is the ValueEncoderFunc for Regex.
610func (DefaultValueEncoders) RegexEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
611	if !val.IsValid() || val.Type() != tRegex {
612		return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val}
613	}
614
615	regex := val.Interface().(primitive.Regex)
616
617	return vw.WriteRegex(regex.Pattern, regex.Options)
618}
619
620// DBPointerEncodeValue is the ValueEncoderFunc for DBPointer.
621func (DefaultValueEncoders) DBPointerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
622	if !val.IsValid() || val.Type() != tDBPointer {
623		return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val}
624	}
625
626	dbp := val.Interface().(primitive.DBPointer)
627
628	return vw.WriteDBPointer(dbp.DB, dbp.Pointer)
629}
630
631// TimestampEncodeValue is the ValueEncoderFunc for Timestamp.
632func (DefaultValueEncoders) TimestampEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
633	if !val.IsValid() || val.Type() != tTimestamp {
634		return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val}
635	}
636
637	ts := val.Interface().(primitive.Timestamp)
638
639	return vw.WriteTimestamp(ts.T, ts.I)
640}
641
642// MinKeyEncodeValue is the ValueEncoderFunc for MinKey.
643func (DefaultValueEncoders) MinKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
644	if !val.IsValid() || val.Type() != tMinKey {
645		return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: val}
646	}
647
648	return vw.WriteMinKey()
649}
650
651// MaxKeyEncodeValue is the ValueEncoderFunc for MaxKey.
652func (DefaultValueEncoders) MaxKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
653	if !val.IsValid() || val.Type() != tMaxKey {
654		return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: val}
655	}
656
657	return vw.WriteMaxKey()
658}
659
660// CoreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document.
661func (DefaultValueEncoders) CoreDocumentEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
662	if !val.IsValid() || val.Type() != tCoreDocument {
663		return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: val}
664	}
665
666	cdoc := val.Interface().(bsoncore.Document)
667
668	return bsonrw.Copier{}.CopyDocumentFromBytes(vw, cdoc)
669}
670
671// CodeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope.
672func (dve DefaultValueEncoders) CodeWithScopeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
673	if !val.IsValid() || val.Type() != tCodeWithScope {
674		return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val}
675	}
676
677	cws := val.Interface().(primitive.CodeWithScope)
678
679	dw, err := vw.WriteCodeWithScope(string(cws.Code))
680	if err != nil {
681		return err
682	}
683
684	sw := sliceWriterPool.Get().(*bsonrw.SliceWriter)
685	defer sliceWriterPool.Put(sw)
686	*sw = (*sw)[:0]
687
688	scopeVW := bvwPool.Get(sw)
689	defer bvwPool.Put(scopeVW)
690
691	encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope))
692	if err != nil {
693		return err
694	}
695
696	err = encoder.EncodeValue(ec, scopeVW, reflect.ValueOf(cws.Scope))
697	if err != nil {
698		return err
699	}
700
701	err = bsonrw.Copier{}.CopyBytesToDocumentWriter(dw, *sw)
702	if err != nil {
703		return err
704	}
705	return dw.WriteDocumentEnd()
706}
707