registry.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  	"errors"
  11  	"fmt"
  12  	"reflect"
  13  	"sync"
  14  
  15  	"go.mongodb.org/mongo-driver/bson/bsontype"
  16  )
  17  
  18  // ErrNilType is returned when nil is passed to either LookupEncoder or LookupDecoder.
  19  //
  20  // Deprecated: ErrNilType will not be supported in Go Driver 2.0.
  21  var ErrNilType = errors.New("cannot perform a decoder lookup on <nil>")
  22  
  23  // ErrNotPointer is returned when a non-pointer type is provided to LookupDecoder.
  24  //
  25  // Deprecated: ErrNotPointer will not be supported in Go Driver 2.0.
  26  var ErrNotPointer = errors.New("non-pointer provided to LookupDecoder")
  27  
  28  // ErrNoEncoder is returned when there wasn't an encoder available for a type.
  29  //
  30  // Deprecated: ErrNoEncoder will not be supported in Go Driver 2.0.
  31  type ErrNoEncoder struct {
  32  	Type reflect.Type
  33  }
  34  
  35  func (ene ErrNoEncoder) Error() string {
  36  	if ene.Type == nil {
  37  		return "no encoder found for <nil>"
  38  	}
  39  	return "no encoder found for " + ene.Type.String()
  40  }
  41  
  42  // ErrNoDecoder is returned when there wasn't a decoder available for a type.
  43  //
  44  // Deprecated: ErrNoDecoder will not be supported in Go Driver 2.0.
  45  type ErrNoDecoder struct {
  46  	Type reflect.Type
  47  }
  48  
  49  func (end ErrNoDecoder) Error() string {
  50  	return "no decoder found for " + end.Type.String()
  51  }
  52  
  53  // ErrNoTypeMapEntry is returned when there wasn't a type available for the provided BSON type.
  54  //
  55  // Deprecated: ErrNoTypeMapEntry will not be supported in Go Driver 2.0.
  56  type ErrNoTypeMapEntry struct {
  57  	Type bsontype.Type
  58  }
  59  
  60  func (entme ErrNoTypeMapEntry) Error() string {
  61  	return "no type map entry found for " + entme.Type.String()
  62  }
  63  
  64  // ErrNotInterface is returned when the provided type is not an interface.
  65  //
  66  // Deprecated: ErrNotInterface will not be supported in Go Driver 2.0.
  67  var ErrNotInterface = errors.New("The provided type is not an interface")
  68  
  69  // A RegistryBuilder is used to build a Registry. This type is not goroutine
  70  // safe.
  71  //
  72  // Deprecated: Use Registry instead.
  73  type RegistryBuilder struct {
  74  	registry *Registry
  75  }
  76  
  77  // NewRegistryBuilder creates a new empty RegistryBuilder.
  78  //
  79  // Deprecated: Use NewRegistry instead.
  80  func NewRegistryBuilder() *RegistryBuilder {
  81  	return &RegistryBuilder{
  82  		registry: NewRegistry(),
  83  	}
  84  }
  85  
  86  // RegisterCodec will register the provided ValueCodec for the provided type.
  87  //
  88  // Deprecated: Use Registry.RegisterTypeEncoder and Registry.RegisterTypeDecoder instead.
  89  func (rb *RegistryBuilder) RegisterCodec(t reflect.Type, codec ValueCodec) *RegistryBuilder {
  90  	rb.RegisterTypeEncoder(t, codec)
  91  	rb.RegisterTypeDecoder(t, codec)
  92  	return rb
  93  }
  94  
  95  // RegisterTypeEncoder will register the provided ValueEncoder for the provided type.
  96  //
  97  // The type will be used directly, so an encoder can be registered for a type and a different encoder can be registered
  98  // for a pointer to that type.
  99  //
 100  // If the given type is an interface, the encoder will be called when marshaling a type that is that interface. It
 101  // will not be called when marshaling a non-interface type that implements the interface.
 102  //
 103  // Deprecated: Use Registry.RegisterTypeEncoder instead.
 104  func (rb *RegistryBuilder) RegisterTypeEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
 105  	rb.registry.RegisterTypeEncoder(t, enc)
 106  	return rb
 107  }
 108  
 109  // RegisterHookEncoder will register an encoder for the provided interface type t. This encoder will be called when
 110  // marshaling a type if the type implements t or a pointer to the type implements t. If the provided type is not
 111  // an interface (i.e. t.Kind() != reflect.Interface), this method will panic.
 112  //
 113  // Deprecated: Use Registry.RegisterInterfaceEncoder instead.
 114  func (rb *RegistryBuilder) RegisterHookEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
 115  	rb.registry.RegisterInterfaceEncoder(t, enc)
 116  	return rb
 117  }
 118  
 119  // RegisterTypeDecoder will register the provided ValueDecoder for the provided type.
 120  //
 121  // The type will be used directly, so a decoder can be registered for a type and a different decoder can be registered
 122  // for a pointer to that type.
 123  //
 124  // If the given type is an interface, the decoder will be called when unmarshaling into a type that is that interface.
 125  // It will not be called when unmarshaling into a non-interface type that implements the interface.
 126  //
 127  // Deprecated: Use Registry.RegisterTypeDecoder instead.
 128  func (rb *RegistryBuilder) RegisterTypeDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
 129  	rb.registry.RegisterTypeDecoder(t, dec)
 130  	return rb
 131  }
 132  
 133  // RegisterHookDecoder will register an decoder for the provided interface type t. This decoder will be called when
 134  // unmarshaling into a type if the type implements t or a pointer to the type implements t. If the provided type is not
 135  // an interface (i.e. t.Kind() != reflect.Interface), this method will panic.
 136  //
 137  // Deprecated: Use Registry.RegisterInterfaceDecoder instead.
 138  func (rb *RegistryBuilder) RegisterHookDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
 139  	rb.registry.RegisterInterfaceDecoder(t, dec)
 140  	return rb
 141  }
 142  
 143  // RegisterEncoder registers the provided type and encoder pair.
 144  //
 145  // Deprecated: Use Registry.RegisterTypeEncoder or Registry.RegisterInterfaceEncoder instead.
 146  func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
 147  	if t == tEmpty {
 148  		rb.registry.RegisterTypeEncoder(t, enc)
 149  		return rb
 150  	}
 151  	switch t.Kind() {
 152  	case reflect.Interface:
 153  		rb.registry.RegisterInterfaceEncoder(t, enc)
 154  	default:
 155  		rb.registry.RegisterTypeEncoder(t, enc)
 156  	}
 157  	return rb
 158  }
 159  
 160  // RegisterDecoder registers the provided type and decoder pair.
 161  //
 162  // Deprecated: Use Registry.RegisterTypeDecoder or Registry.RegisterInterfaceDecoder instead.
 163  func (rb *RegistryBuilder) RegisterDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
 164  	if t == nil {
 165  		rb.registry.RegisterTypeDecoder(t, dec)
 166  		return rb
 167  	}
 168  	if t == tEmpty {
 169  		rb.registry.RegisterTypeDecoder(t, dec)
 170  		return rb
 171  	}
 172  	switch t.Kind() {
 173  	case reflect.Interface:
 174  		rb.registry.RegisterInterfaceDecoder(t, dec)
 175  	default:
 176  		rb.registry.RegisterTypeDecoder(t, dec)
 177  	}
 178  	return rb
 179  }
 180  
 181  // RegisterDefaultEncoder will register the provided ValueEncoder to the provided
 182  // kind.
 183  //
 184  // Deprecated: Use Registry.RegisterKindEncoder instead.
 185  func (rb *RegistryBuilder) RegisterDefaultEncoder(kind reflect.Kind, enc ValueEncoder) *RegistryBuilder {
 186  	rb.registry.RegisterKindEncoder(kind, enc)
 187  	return rb
 188  }
 189  
 190  // RegisterDefaultDecoder will register the provided ValueDecoder to the
 191  // provided kind.
 192  //
 193  // Deprecated: Use Registry.RegisterKindDecoder instead.
 194  func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDecoder) *RegistryBuilder {
 195  	rb.registry.RegisterKindDecoder(kind, dec)
 196  	return rb
 197  }
 198  
 199  // RegisterTypeMapEntry will register the provided type to the BSON type. The primary usage for this
 200  // mapping is decoding situations where an empty interface is used and a default type needs to be
 201  // created and decoded into.
 202  //
 203  // By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON
 204  // documents, a type map entry for bsontype.EmbeddedDocument should be registered. For example, to force BSON documents
 205  // to decode to bson.Raw, use the following code:
 206  //
 207  //	rb.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{}))
 208  //
 209  // Deprecated: Use Registry.RegisterTypeMapEntry instead.
 210  func (rb *RegistryBuilder) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) *RegistryBuilder {
 211  	rb.registry.RegisterTypeMapEntry(bt, rt)
 212  	return rb
 213  }
 214  
 215  // Build creates a Registry from the current state of this RegistryBuilder.
 216  //
 217  // Deprecated: Use NewRegistry instead.
 218  func (rb *RegistryBuilder) Build() *Registry {
 219  	r := &Registry{
 220  		interfaceEncoders: append([]interfaceValueEncoder(nil), rb.registry.interfaceEncoders...),
 221  		interfaceDecoders: append([]interfaceValueDecoder(nil), rb.registry.interfaceDecoders...),
 222  		typeEncoders:      rb.registry.typeEncoders.Clone(),
 223  		typeDecoders:      rb.registry.typeDecoders.Clone(),
 224  		kindEncoders:      rb.registry.kindEncoders.Clone(),
 225  		kindDecoders:      rb.registry.kindDecoders.Clone(),
 226  	}
 227  	rb.registry.typeMap.Range(func(k, v interface{}) bool {
 228  		if k != nil && v != nil {
 229  			r.typeMap.Store(k, v)
 230  		}
 231  		return true
 232  	})
 233  	return r
 234  }
 235  
 236  // A Registry is used to store and retrieve codecs for types and interfaces. This type is the main
 237  // typed passed around and Encoders and Decoders are constructed from it.
 238  type Registry struct {
 239  	interfaceEncoders []interfaceValueEncoder
 240  	interfaceDecoders []interfaceValueDecoder
 241  	typeEncoders      *typeEncoderCache
 242  	typeDecoders      *typeDecoderCache
 243  	kindEncoders      *kindEncoderCache
 244  	kindDecoders      *kindDecoderCache
 245  	typeMap           sync.Map // map[bsontype.Type]reflect.Type
 246  }
 247  
 248  // NewRegistry creates a new empty Registry.
 249  func NewRegistry() *Registry {
 250  	return &Registry{
 251  		typeEncoders: new(typeEncoderCache),
 252  		typeDecoders: new(typeDecoderCache),
 253  		kindEncoders: new(kindEncoderCache),
 254  		kindDecoders: new(kindDecoderCache),
 255  	}
 256  }
 257  
 258  // RegisterTypeEncoder registers the provided ValueEncoder for the provided type.
 259  //
 260  // The type will be used as provided, so an encoder can be registered for a type and a different
 261  // encoder can be registered for a pointer to that type.
 262  //
 263  // If the given type is an interface, the encoder will be called when marshaling a type that is
 264  // that interface. It will not be called when marshaling a non-interface type that implements the
 265  // interface. To get the latter behavior, call RegisterHookEncoder instead.
 266  //
 267  // RegisterTypeEncoder should not be called concurrently with any other Registry method.
 268  func (r *Registry) RegisterTypeEncoder(valueType reflect.Type, enc ValueEncoder) {
 269  	r.typeEncoders.Store(valueType, enc)
 270  }
 271  
 272  // RegisterTypeDecoder registers the provided ValueDecoder for the provided type.
 273  //
 274  // The type will be used as provided, so a decoder can be registered for a type and a different
 275  // decoder can be registered for a pointer to that type.
 276  //
 277  // If the given type is an interface, the decoder will be called when unmarshaling into a type that
 278  // is that interface. It will not be called when unmarshaling into a non-interface type that
 279  // implements the interface. To get the latter behavior, call RegisterHookDecoder instead.
 280  //
 281  // RegisterTypeDecoder should not be called concurrently with any other Registry method.
 282  func (r *Registry) RegisterTypeDecoder(valueType reflect.Type, dec ValueDecoder) {
 283  	r.typeDecoders.Store(valueType, dec)
 284  }
 285  
 286  // RegisterKindEncoder registers the provided ValueEncoder for the provided kind.
 287  //
 288  // Use RegisterKindEncoder to register an encoder for any type with the same underlying kind. For
 289  // example, consider the type MyInt defined as
 290  //
 291  //	type MyInt int32
 292  //
 293  // To define an encoder for MyInt and int32, use RegisterKindEncoder like
 294  //
 295  //	reg.RegisterKindEncoder(reflect.Int32, myEncoder)
 296  //
 297  // RegisterKindEncoder should not be called concurrently with any other Registry method.
 298  func (r *Registry) RegisterKindEncoder(kind reflect.Kind, enc ValueEncoder) {
 299  	r.kindEncoders.Store(kind, enc)
 300  }
 301  
 302  // RegisterKindDecoder registers the provided ValueDecoder for the provided kind.
 303  //
 304  // Use RegisterKindDecoder to register a decoder for any type with the same underlying kind. For
 305  // example, consider the type MyInt defined as
 306  //
 307  //	type MyInt int32
 308  //
 309  // To define an decoder for MyInt and int32, use RegisterKindDecoder like
 310  //
 311  //	reg.RegisterKindDecoder(reflect.Int32, myDecoder)
 312  //
 313  // RegisterKindDecoder should not be called concurrently with any other Registry method.
 314  func (r *Registry) RegisterKindDecoder(kind reflect.Kind, dec ValueDecoder) {
 315  	r.kindDecoders.Store(kind, dec)
 316  }
 317  
 318  // RegisterInterfaceEncoder registers an encoder for the provided interface type iface. This encoder will
 319  // be called when marshaling a type if the type implements iface or a pointer to the type
 320  // implements iface. If the provided type is not an interface
 321  // (i.e. iface.Kind() != reflect.Interface), this method will panic.
 322  //
 323  // RegisterInterfaceEncoder should not be called concurrently with any other Registry method.
 324  func (r *Registry) RegisterInterfaceEncoder(iface reflect.Type, enc ValueEncoder) {
 325  	if iface.Kind() != reflect.Interface {
 326  		panicStr := fmt.Errorf("RegisterInterfaceEncoder expects a type with kind reflect.Interface, "+
 327  			"got type %s with kind %s", iface, iface.Kind())
 328  		panic(panicStr)
 329  	}
 330  
 331  	for idx, encoder := range r.interfaceEncoders {
 332  		if encoder.i == iface {
 333  			r.interfaceEncoders[idx].ve = enc
 334  			return
 335  		}
 336  	}
 337  
 338  	r.interfaceEncoders = append(r.interfaceEncoders, interfaceValueEncoder{i: iface, ve: enc})
 339  }
 340  
 341  // RegisterInterfaceDecoder registers an decoder for the provided interface type iface. This decoder will
 342  // be called when unmarshaling into a type if the type implements iface or a pointer to the type
 343  // implements iface. If the provided type is not an interface (i.e. iface.Kind() != reflect.Interface),
 344  // this method will panic.
 345  //
 346  // RegisterInterfaceDecoder should not be called concurrently with any other Registry method.
 347  func (r *Registry) RegisterInterfaceDecoder(iface reflect.Type, dec ValueDecoder) {
 348  	if iface.Kind() != reflect.Interface {
 349  		panicStr := fmt.Errorf("RegisterInterfaceDecoder expects a type with kind reflect.Interface, "+
 350  			"got type %s with kind %s", iface, iface.Kind())
 351  		panic(panicStr)
 352  	}
 353  
 354  	for idx, decoder := range r.interfaceDecoders {
 355  		if decoder.i == iface {
 356  			r.interfaceDecoders[idx].vd = dec
 357  			return
 358  		}
 359  	}
 360  
 361  	r.interfaceDecoders = append(r.interfaceDecoders, interfaceValueDecoder{i: iface, vd: dec})
 362  }
 363  
 364  // RegisterTypeMapEntry will register the provided type to the BSON type. The primary usage for this
 365  // mapping is decoding situations where an empty interface is used and a default type needs to be
 366  // created and decoded into.
 367  //
 368  // By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON
 369  // documents, a type map entry for bsontype.EmbeddedDocument should be registered. For example, to force BSON documents
 370  // to decode to bson.Raw, use the following code:
 371  //
 372  //	reg.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{}))
 373  func (r *Registry) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) {
 374  	r.typeMap.Store(bt, rt)
 375  }
 376  
 377  // LookupEncoder returns the first matching encoder in the Registry. It uses the following lookup
 378  // order:
 379  //
 380  // 1. An encoder registered for the exact type. If the given type is an interface, an encoder
 381  // registered using RegisterTypeEncoder for that interface will be selected.
 382  //
 383  // 2. An encoder registered using RegisterInterfaceEncoder for an interface implemented by the type
 384  // or by a pointer to the type.
 385  //
 386  // 3. An encoder registered using RegisterKindEncoder for the kind of value.
 387  //
 388  // If no encoder is found, an error of type ErrNoEncoder is returned. LookupEncoder is safe for
 389  // concurrent use by multiple goroutines after all codecs and encoders are registered.
 390  func (r *Registry) LookupEncoder(valueType reflect.Type) (ValueEncoder, error) {
 391  	if valueType == nil {
 392  		return nil, ErrNoEncoder{Type: valueType}
 393  	}
 394  	enc, found := r.lookupTypeEncoder(valueType)
 395  	if found {
 396  		if enc == nil {
 397  			return nil, ErrNoEncoder{Type: valueType}
 398  		}
 399  		return enc, nil
 400  	}
 401  
 402  	enc, found = r.lookupInterfaceEncoder(valueType, true)
 403  	if found {
 404  		return r.typeEncoders.LoadOrStore(valueType, enc), nil
 405  	}
 406  
 407  	if v, ok := r.kindEncoders.Load(valueType.Kind()); ok {
 408  		return r.storeTypeEncoder(valueType, v), nil
 409  	}
 410  	return nil, ErrNoEncoder{Type: valueType}
 411  }
 412  
 413  func (r *Registry) storeTypeEncoder(rt reflect.Type, enc ValueEncoder) ValueEncoder {
 414  	return r.typeEncoders.LoadOrStore(rt, enc)
 415  }
 416  
 417  func (r *Registry) lookupTypeEncoder(rt reflect.Type) (ValueEncoder, bool) {
 418  	return r.typeEncoders.Load(rt)
 419  }
 420  
 421  func (r *Registry) lookupInterfaceEncoder(valueType reflect.Type, allowAddr bool) (ValueEncoder, bool) {
 422  	if valueType == nil {
 423  		return nil, false
 424  	}
 425  	for _, ienc := range r.interfaceEncoders {
 426  		if valueType.Implements(ienc.i) {
 427  			return ienc.ve, true
 428  		}
 429  		if allowAddr && valueType.Kind() != reflect.Ptr && reflect.PtrTo(valueType).Implements(ienc.i) {
 430  			// if *t implements an interface, this will catch if t implements an interface further
 431  			// ahead in interfaceEncoders
 432  			defaultEnc, found := r.lookupInterfaceEncoder(valueType, false)
 433  			if !found {
 434  				defaultEnc, _ = r.kindEncoders.Load(valueType.Kind())
 435  			}
 436  			return newCondAddrEncoder(ienc.ve, defaultEnc), true
 437  		}
 438  	}
 439  	return nil, false
 440  }
 441  
 442  // LookupDecoder returns the first matching decoder in the Registry. It uses the following lookup
 443  // order:
 444  //
 445  // 1. A decoder registered for the exact type. If the given type is an interface, a decoder
 446  // registered using RegisterTypeDecoder for that interface will be selected.
 447  //
 448  // 2. A decoder registered using RegisterInterfaceDecoder for an interface implemented by the type or by
 449  // a pointer to the type.
 450  //
 451  // 3. A decoder registered using RegisterKindDecoder for the kind of value.
 452  //
 453  // If no decoder is found, an error of type ErrNoDecoder is returned. LookupDecoder is safe for
 454  // concurrent use by multiple goroutines after all codecs and decoders are registered.
 455  func (r *Registry) LookupDecoder(valueType reflect.Type) (ValueDecoder, error) {
 456  	if valueType == nil {
 457  		return nil, ErrNilType
 458  	}
 459  	dec, found := r.lookupTypeDecoder(valueType)
 460  	if found {
 461  		if dec == nil {
 462  			return nil, ErrNoDecoder{Type: valueType}
 463  		}
 464  		return dec, nil
 465  	}
 466  
 467  	dec, found = r.lookupInterfaceDecoder(valueType, true)
 468  	if found {
 469  		return r.storeTypeDecoder(valueType, dec), nil
 470  	}
 471  
 472  	if v, ok := r.kindDecoders.Load(valueType.Kind()); ok {
 473  		return r.storeTypeDecoder(valueType, v), nil
 474  	}
 475  	return nil, ErrNoDecoder{Type: valueType}
 476  }
 477  
 478  func (r *Registry) lookupTypeDecoder(valueType reflect.Type) (ValueDecoder, bool) {
 479  	return r.typeDecoders.Load(valueType)
 480  }
 481  
 482  func (r *Registry) storeTypeDecoder(typ reflect.Type, dec ValueDecoder) ValueDecoder {
 483  	return r.typeDecoders.LoadOrStore(typ, dec)
 484  }
 485  
 486  func (r *Registry) lookupInterfaceDecoder(valueType reflect.Type, allowAddr bool) (ValueDecoder, bool) {
 487  	for _, idec := range r.interfaceDecoders {
 488  		if valueType.Implements(idec.i) {
 489  			return idec.vd, true
 490  		}
 491  		if allowAddr && valueType.Kind() != reflect.Ptr && reflect.PtrTo(valueType).Implements(idec.i) {
 492  			// if *t implements an interface, this will catch if t implements an interface further
 493  			// ahead in interfaceDecoders
 494  			defaultDec, found := r.lookupInterfaceDecoder(valueType, false)
 495  			if !found {
 496  				defaultDec, _ = r.kindDecoders.Load(valueType.Kind())
 497  			}
 498  			return newCondAddrDecoder(idec.vd, defaultDec), true
 499  		}
 500  	}
 501  	return nil, false
 502  }
 503  
 504  // LookupTypeMapEntry inspects the registry's type map for a Go type for the corresponding BSON
 505  // type. If no type is found, ErrNoTypeMapEntry is returned.
 506  //
 507  // LookupTypeMapEntry should not be called concurrently with any other Registry method.
 508  func (r *Registry) LookupTypeMapEntry(bt bsontype.Type) (reflect.Type, error) {
 509  	v, ok := r.typeMap.Load(bt)
 510  	if v == nil || !ok {
 511  		return nil, ErrNoTypeMapEntry{Type: bt}
 512  	}
 513  	return v.(reflect.Type), nil
 514  }
 515  
 516  type interfaceValueEncoder struct {
 517  	i  reflect.Type
 518  	ve ValueEncoder
 519  }
 520  
 521  type interfaceValueDecoder struct {
 522  	i  reflect.Type
 523  	vd ValueDecoder
 524  }
 525