Skip to content

Commit 760fe05

Browse files
GODRIVER-3455 Order LookupEncoder correctly
1 parent 4bc3b1e commit 760fe05

File tree

3 files changed

+32
-155
lines changed

3 files changed

+32
-155
lines changed

bson/default_value_encoders.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func registerDefaultEncoders(reg *Registry) {
6363
// Register the reflect-free default type encoders.
6464
reg.registerReflectFreeTypeEncoder(tByteSlice, byteSliceEncodeValueRF(false))
6565
reg.registerReflectFreeTypeEncoder(tTime, reflectFreeValueEncoderFunc(timeEncodeValueRF))
66+
reg.registerReflectFreeTypeEncoder(tEmpty, reflectFreeValueEncoderFunc(emptyInterfaceValueRF))
6667
reg.registerReflectFreeTypeEncoder(tCoreArray, reflectFreeValueEncoderFunc(coreArrayEncodeValueRF))
6768
reg.registerReflectFreeTypeEncoder(tNull, reflectFreeValueEncoderFunc(nullEncodeValueX))
6869
reg.registerReflectFreeTypeEncoder(tOID, reflectFreeValueEncoderFunc(objectIDEncodeValueX))
@@ -89,7 +90,7 @@ func registerDefaultEncoders(reg *Registry) {
8990
//
9091
reg.RegisterTypeEncoder(tByteSlice, byteSliceEncodeValue(false))
9192
reg.RegisterTypeEncoder(tTime, defaultValueEncoderFunc(timeEncodeValue))
92-
reg.RegisterTypeEncoder(tEmpty, &emptyInterfaceCodec{}) // TODO: extend this to reflection free
93+
reg.RegisterTypeEncoder(tEmpty, defaultValueEncoderFunc(emptyInterfaceValue)) // TODO: extend this to reflection free
9394
reg.RegisterTypeEncoder(tCoreArray, defaultValueEncoderFunc(coreArrayEncodeValue))
9495
reg.RegisterTypeEncoder(tOID, defaultValueEncoderFunc(objectIDEncodeValue))
9596
reg.RegisterTypeEncoder(tDecimal, defaultValueEncoderFunc(decimal128EncodeValue))
@@ -258,10 +259,6 @@ func jsonNumberEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value)
258259
}
259260

260261
func jsonNumberEncodeValueX(ec EncodeContext, vw ValueWriter, val any) error {
261-
//if !val.IsValid() || val.Type() != tJSONNumber {
262-
// return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: val}
263-
//}
264-
//jsnum := val.Interface().(json.Number)
265262
jsnum, ok := val.(json.Number)
266263
if !ok {
267264
return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: reflect.ValueOf(val)}
@@ -708,7 +705,6 @@ func codeWithScopeEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Valu
708705
scopeVW.reset(scopeVW.buf[:0])
709706
scopeVW.w = sw
710707
defer bvwPool.Put(scopeVW)
711-
712708
encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope))
713709
if err != nil {
714710
return err
@@ -745,7 +741,6 @@ func codeWithScopeEncodeValueX(ec EncodeContext, vw ValueWriter, val any) error
745741
scopeVW.reset(scopeVW.buf[:0])
746742
scopeVW.w = sw
747743
defer bvwPool.Put(scopeVW)
748-
749744
encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope))
750745
if err != nil {
751746
return err
@@ -823,3 +818,19 @@ func coreArrayEncodeValueRF(ec EncodeContext, vw ValueWriter, val any) error {
823818
func coreArrayEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
824819
return coreArrayEncodeValueRF(ec, vw, val.Interface())
825820
}
821+
822+
func emptyInterfaceValueRF(ec EncodeContext, vw ValueWriter, val any) error {
823+
if val == nil {
824+
return vw.WriteNull()
825+
}
826+
encoder, err := ec.LookupEncoder(reflect.TypeOf(val))
827+
if err != nil {
828+
return err
829+
}
830+
831+
return encoder.EncodeValue(ec, vw, reflect.ValueOf(val))
832+
}
833+
834+
func emptyInterfaceValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
835+
return emptyInterfaceValueRF(ec, vw, val.Interface())
836+
}

bson/mgoregistry.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ func NewMgoRegistry() *Registry {
4444
reg.RegisterKindDecoder(reflect.String, ValueDecoderFunc(mgoStringDecodeValue))
4545
reg.RegisterKindDecoder(reflect.Struct, structCodec)
4646
reg.RegisterKindDecoder(reflect.Map, mapCodec)
47-
//reg.RegisterTypeEncoder(tByteSlice, &byteSliceCodec{encodeNilAsEmpty: true})
4847
reg.RegisterKindEncoder(reflect.Struct, structCodec)
4948
reg.RegisterKindEncoder(reflect.Slice, &sliceCodec{encodeNilAsEmpty: true})
5049
reg.RegisterKindEncoder(reflect.Map, mapCodec)
@@ -74,7 +73,6 @@ func NewRespectNilValuesMgoRegistry() *Registry {
7473
reg.registerReflectFreeTypeEncoder(tByteSlice, byteSliceEncodeValueRF(false))
7574

7675
reg.RegisterKindDecoder(reflect.Map, mapCodec)
77-
//reg.RegisterTypeEncoder(tByteSlice, &byteSliceCodec{encodeNilAsEmpty: false})
7876
reg.RegisterKindEncoder(reflect.Slice, &sliceCodec{})
7977
reg.RegisterKindEncoder(reflect.Map, mapCodec)
8078
return reg

bson/registry.go

Lines changed: 14 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,10 @@
77
package bson
88

99
import (
10-
"encoding/json"
1110
"errors"
1211
"fmt"
13-
"net/url"
1412
"reflect"
1513
"sync"
16-
"time"
17-
18-
"go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
1914
)
2015

2116
// defaultRegistry is the default Registry. It contains the default codecs and the
@@ -246,130 +241,6 @@ func (r *Registry) RegisterTypeMapEntry(bt Type, rt reflect.Type) {
246241
r.typeMap.Store(bt, rt)
247242
}
248243

249-
func getReflectTypeFromAny(val any) (reflect.Type, error) {
250-
switch v := val.(type) {
251-
case bool:
252-
return tBool, nil
253-
case float64:
254-
return tFloat64, nil
255-
case int32:
256-
return tInt32, nil
257-
case int64:
258-
return tInt64, nil
259-
case string:
260-
return tString, nil
261-
case time.Time:
262-
return tTime, nil
263-
case interface{}:
264-
return tEmpty, nil
265-
case []byte:
266-
return tByteSlice, nil
267-
case byte:
268-
return tByte, nil
269-
case url.URL:
270-
return tURL, nil
271-
case json.Number:
272-
return tJSONNumber, nil
273-
case ValueMarshaler:
274-
return tValueMarshaler, nil
275-
case ValueUnmarshaler:
276-
return tValueUnmarshaler, nil
277-
case Marshaler:
278-
return tMarshaler, nil
279-
case Unmarshaler:
280-
return tUnmarshaler, nil
281-
case Zeroer:
282-
return tZeroer, nil
283-
case Binary:
284-
return tBinary, nil
285-
case Undefined:
286-
return tUndefined, nil
287-
case ObjectID:
288-
return tOID, nil
289-
case DateTime:
290-
return tDateTime, nil
291-
case Null:
292-
return tNull, nil
293-
case Regex:
294-
return tRegex, nil
295-
case CodeWithScope:
296-
return tCodeWithScope, nil
297-
case DBPointer:
298-
return tDBPointer, nil
299-
case JavaScript:
300-
return tJavaScript, nil
301-
case Symbol:
302-
return tSymbol, nil
303-
case Timestamp:
304-
return tTimestamp, nil
305-
case Decimal128:
306-
return tDecimal, nil
307-
case Vector:
308-
return tVector, nil
309-
case MinKey:
310-
return tMinKey, nil
311-
case MaxKey:
312-
return tMaxKey, nil
313-
case D:
314-
return tD, nil
315-
case A:
316-
return tA, nil
317-
case E:
318-
return tE, nil
319-
case bsoncore.Document:
320-
return tCoreDocument, nil
321-
case bsoncore.Array:
322-
return tCoreArray, nil
323-
default:
324-
return nil, fmt.Errorf("no default encoder for type %T", v)
325-
}
326-
}
327-
328-
//func lookupReflectFreeEncoder(r *Registry, typ reflect.Type) (reflectFreeValueEncoder, error) {
329-
//}
330-
331-
func lookupEncoderReflectFree(r *Registry, typ reflect.Type, val any) (reflectFreeValueEncoder, error) {
332-
if typ == nil {
333-
var err error
334-
335-
typ, err = getReflectTypeFromAny(val)
336-
if err != nil {
337-
return nil, err
338-
}
339-
}
340-
341-
rfeEnc, found := r.reflectFreeTypeEncoders.Load(typ)
342-
if !found {
343-
return nil, errNoEncoder{Type: typ}
344-
}
345-
346-
return rfeEnc, nil
347-
}
348-
349-
func lookupUserDefinedEncoder(r *Registry, val any) (ValueEncoder, reflect.Type, bool, error) {
350-
typ, err := getReflectTypeFromAny(val)
351-
if err != nil {
352-
return nil, nil, false, err
353-
}
354-
355-
enc, found := r.lookupTypeEncoder(typ)
356-
if found {
357-
if enc == nil {
358-
return nil, typ, false, errNoEncoder{Type: typ}
359-
}
360-
361-
// We do not use ValueEncoder in the default case, preferring a reflect-free
362-
// solution.
363-
if _, ok := enc.(defaultValueEncoderFunc); ok {
364-
return nil, typ, false, nil
365-
}
366-
367-
return enc, typ, true, nil
368-
}
369-
370-
return nil, typ, false, nil
371-
}
372-
373244
// LookupEncoder returns the first matching encoder in the Registry. It uses the following lookup
374245
// order:
375246
//
@@ -392,30 +263,27 @@ func (r *Registry) LookupEncoder(valueType reflect.Type) (ValueEncoder, error) {
392263
return nil, errNoEncoder{Type: valueType}
393264
}
394265

395-
// First attempt to lookup a reflect-free default encoder.
396-
// TODO: This will be moved in favor of the lookup* solution.
397-
rfeEnc, found := r.reflectFreeTypeEncoders.Load(valueType)
398-
if found {
399-
if rfeEnc != nil {
400-
wrapper := func(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
401-
return rfeEnc.EncodeValue(ec, vw, val.Interface())
402-
}
266+
// First attempt to get a user-defined type encoder.
267+
if enc, found := r.lookupTypeEncoder(valueType); found {
268+
if enc == nil {
269+
return nil, errNoEncoder{Type: valueType}
270+
}
403271

404-
return ValueEncoderFunc(wrapper), nil
272+
if _, ok := enc.(defaultValueEncoderFunc); !ok {
273+
return enc, nil
405274
}
406275
}
407276

408-
// Then lookup a user-defined encoder.
409-
enc, found := r.lookupTypeEncoder(valueType)
410-
if found {
411-
if enc == nil {
412-
return nil, errNoEncoder{Type: valueType}
277+
// Next try to get a reflection-free encoder.
278+
if rfeEnc, found := r.reflectFreeTypeEncoders.Load(valueType); found && rfeEnc != nil {
279+
wrapper := func(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
280+
return rfeEnc.EncodeValue(ec, vw, val.Interface())
413281
}
414-
return enc, nil
282+
283+
return ValueEncoderFunc(wrapper), nil
415284
}
416285

417-
enc, found = r.lookupInterfaceEncoder(valueType, true)
418-
if found {
286+
if enc, found := r.lookupInterfaceEncoder(valueType, true); found {
419287
return r.typeEncoders.LoadOrStore(valueType, enc), nil
420288
}
421289

0 commit comments

Comments
 (0)