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