blob: 741deb8c24f856a6ec73eb4e078d3bc3ad307fd2 [file] [log] [blame]
Don Newton379ae252019-04-01 12:17:06 -04001// 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 "reflect"
12 "sync"
13
14 "github.com/mongodb/mongo-go-driver/bson/bsontype"
15)
16
17// ErrNilType is returned when nil is passed to either LookupEncoder or LookupDecoder.
18var ErrNilType = errors.New("cannot perform a decoder lookup on <nil>")
19
20// ErrNotPointer is returned when a non-pointer type is provided to LookupDecoder.
21var ErrNotPointer = errors.New("non-pointer provided to LookupDecoder")
22
23// ErrNoEncoder is returned when there wasn't an encoder available for a type.
24type ErrNoEncoder struct {
25 Type reflect.Type
26}
27
28func (ene ErrNoEncoder) Error() string {
29 if ene.Type == nil {
30 return "no encoder found for <nil>"
31 }
32 return "no encoder found for " + ene.Type.String()
33}
34
35// ErrNoDecoder is returned when there wasn't a decoder available for a type.
36type ErrNoDecoder struct {
37 Type reflect.Type
38}
39
40func (end ErrNoDecoder) Error() string {
41 return "no decoder found for " + end.Type.String()
42}
43
44// ErrNoTypeMapEntry is returned when there wasn't a type available for the provided BSON type.
45type ErrNoTypeMapEntry struct {
46 Type bsontype.Type
47}
48
49func (entme ErrNoTypeMapEntry) Error() string {
50 return "no type map entry found for " + entme.Type.String()
51}
52
53// ErrNotInterface is returned when the provided type is not an interface.
54var ErrNotInterface = errors.New("The provided type is not an interface")
55
56var defaultRegistry *Registry
57
58func init() {
59 defaultRegistry = buildDefaultRegistry()
60}
61
62// A RegistryBuilder is used to build a Registry. This type is not goroutine
63// safe.
64type RegistryBuilder struct {
65 typeEncoders map[reflect.Type]ValueEncoder
66 interfaceEncoders []interfaceValueEncoder
67 kindEncoders map[reflect.Kind]ValueEncoder
68
69 typeDecoders map[reflect.Type]ValueDecoder
70 interfaceDecoders []interfaceValueDecoder
71 kindDecoders map[reflect.Kind]ValueDecoder
72
73 typeMap map[bsontype.Type]reflect.Type
74}
75
76// A Registry is used to store and retrieve codecs for types and interfaces. This type is the main
77// typed passed around and Encoders and Decoders are constructed from it.
78type Registry struct {
79 typeEncoders map[reflect.Type]ValueEncoder
80 typeDecoders map[reflect.Type]ValueDecoder
81
82 interfaceEncoders []interfaceValueEncoder
83 interfaceDecoders []interfaceValueDecoder
84
85 kindEncoders map[reflect.Kind]ValueEncoder
86 kindDecoders map[reflect.Kind]ValueDecoder
87
88 typeMap map[bsontype.Type]reflect.Type
89
90 mu sync.RWMutex
91}
92
93// NewRegistryBuilder creates a new empty RegistryBuilder.
94func NewRegistryBuilder() *RegistryBuilder {
95 return &RegistryBuilder{
96 typeEncoders: make(map[reflect.Type]ValueEncoder),
97 typeDecoders: make(map[reflect.Type]ValueDecoder),
98
99 interfaceEncoders: make([]interfaceValueEncoder, 0),
100 interfaceDecoders: make([]interfaceValueDecoder, 0),
101
102 kindEncoders: make(map[reflect.Kind]ValueEncoder),
103 kindDecoders: make(map[reflect.Kind]ValueDecoder),
104
105 typeMap: make(map[bsontype.Type]reflect.Type),
106 }
107}
108
109func buildDefaultRegistry() *Registry {
110 rb := NewRegistryBuilder()
111 defaultValueEncoders.RegisterDefaultEncoders(rb)
112 defaultValueDecoders.RegisterDefaultDecoders(rb)
113 return rb.Build()
114}
115
116// RegisterCodec will register the provided ValueCodec for the provided type.
117func (rb *RegistryBuilder) RegisterCodec(t reflect.Type, codec ValueCodec) *RegistryBuilder {
118 rb.RegisterEncoder(t, codec)
119 rb.RegisterDecoder(t, codec)
120 return rb
121}
122
123// RegisterEncoder will register the provided ValueEncoder to the provided type.
124//
125// The type registered will be used directly, so an encoder can be registered for a type and a
126// different encoder can be registered for a pointer to that type.
127func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
128 if t == tEmpty {
129 rb.typeEncoders[t] = enc
130 return rb
131 }
132 switch t.Kind() {
133 case reflect.Interface:
134 for idx, ir := range rb.interfaceEncoders {
135 if ir.i == t {
136 rb.interfaceEncoders[idx].ve = enc
137 return rb
138 }
139 }
140
141 rb.interfaceEncoders = append(rb.interfaceEncoders, interfaceValueEncoder{i: t, ve: enc})
142 default:
143 rb.typeEncoders[t] = enc
144 }
145 return rb
146}
147
148// RegisterDecoder will register the provided ValueDecoder to the provided type.
149//
150// The type registered will be used directly, so a decoder can be registered for a type and a
151// different decoder can be registered for a pointer to that type.
152func (rb *RegistryBuilder) RegisterDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
153 if t == nil {
154 rb.typeDecoders[nil] = dec
155 return rb
156 }
157 if t == tEmpty {
158 rb.typeDecoders[t] = dec
159 return rb
160 }
161 switch t.Kind() {
162 case reflect.Interface:
163 for idx, ir := range rb.interfaceDecoders {
164 if ir.i == t {
165 rb.interfaceDecoders[idx].vd = dec
166 return rb
167 }
168 }
169
170 rb.interfaceDecoders = append(rb.interfaceDecoders, interfaceValueDecoder{i: t, vd: dec})
171 default:
172 rb.typeDecoders[t] = dec
173 }
174 return rb
175}
176
177// RegisterDefaultEncoder will registr the provided ValueEncoder to the provided
178// kind.
179func (rb *RegistryBuilder) RegisterDefaultEncoder(kind reflect.Kind, enc ValueEncoder) *RegistryBuilder {
180 rb.kindEncoders[kind] = enc
181 return rb
182}
183
184// RegisterDefaultDecoder will register the provided ValueDecoder to the
185// provided kind.
186func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDecoder) *RegistryBuilder {
187 rb.kindDecoders[kind] = dec
188 return rb
189}
190
191// RegisterTypeMapEntry will register the provided type to the BSON type. The primary usage for this
192// mapping is decoding situations where an empty interface is used and a default type needs to be
193// created and decoded into.
194//
195// NOTE: It is unlikely that registering a type for BSON Embedded Document is actually desired. By
196// registering a type map entry for BSON Embedded Document the type registered will be used in any
197// case where a BSON Embedded Document will be decoded into an empty interface. For example, if you
198// register primitive.M, the EmptyInterface decoder will always use primitive.M, even if an ancestor
199// was a primitive.D.
200func (rb *RegistryBuilder) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) *RegistryBuilder {
201 rb.typeMap[bt] = rt
202 return rb
203}
204
205// Build creates a Registry from the current state of this RegistryBuilder.
206func (rb *RegistryBuilder) Build() *Registry {
207 registry := new(Registry)
208
209 registry.typeEncoders = make(map[reflect.Type]ValueEncoder)
210 for t, enc := range rb.typeEncoders {
211 registry.typeEncoders[t] = enc
212 }
213
214 registry.typeDecoders = make(map[reflect.Type]ValueDecoder)
215 for t, dec := range rb.typeDecoders {
216 registry.typeDecoders[t] = dec
217 }
218
219 registry.interfaceEncoders = make([]interfaceValueEncoder, len(rb.interfaceEncoders))
220 copy(registry.interfaceEncoders, rb.interfaceEncoders)
221
222 registry.interfaceDecoders = make([]interfaceValueDecoder, len(rb.interfaceDecoders))
223 copy(registry.interfaceDecoders, rb.interfaceDecoders)
224
225 registry.kindEncoders = make(map[reflect.Kind]ValueEncoder)
226 for kind, enc := range rb.kindEncoders {
227 registry.kindEncoders[kind] = enc
228 }
229
230 registry.kindDecoders = make(map[reflect.Kind]ValueDecoder)
231 for kind, dec := range rb.kindDecoders {
232 registry.kindDecoders[kind] = dec
233 }
234
235 registry.typeMap = make(map[bsontype.Type]reflect.Type)
236 for bt, rt := range rb.typeMap {
237 registry.typeMap[bt] = rt
238 }
239
240 return registry
241}
242
243// LookupEncoder will inspect the registry for an encoder that satisfies the
244// type provided. An encoder registered for a specific type will take
245// precedence over an encoder registered for an interface the type satisfies,
246// which takes precedence over an encoder for the reflect.Kind of the value. If
247// no encoder can be found, an error is returned.
248func (r *Registry) LookupEncoder(t reflect.Type) (ValueEncoder, error) {
249 encodererr := ErrNoEncoder{Type: t}
250 r.mu.RLock()
251 enc, found := r.lookupTypeEncoder(t)
252 r.mu.RUnlock()
253 if found {
254 if enc == nil {
255 return nil, ErrNoEncoder{Type: t}
256 }
257 return enc, nil
258 }
259
260 enc, found = r.lookupInterfaceEncoder(t)
261 if found {
262 r.mu.Lock()
263 r.typeEncoders[t] = enc
264 r.mu.Unlock()
265 return enc, nil
266 }
267
268 if t == nil {
269 r.mu.Lock()
270 r.typeEncoders[t] = nil
271 r.mu.Unlock()
272 return nil, encodererr
273 }
274
275 enc, found = r.kindEncoders[t.Kind()]
276 if !found {
277 r.mu.Lock()
278 r.typeEncoders[t] = nil
279 r.mu.Unlock()
280 return nil, encodererr
281 }
282
283 r.mu.Lock()
284 r.typeEncoders[t] = enc
285 r.mu.Unlock()
286 return enc, nil
287}
288
289func (r *Registry) lookupTypeEncoder(t reflect.Type) (ValueEncoder, bool) {
290 enc, found := r.typeEncoders[t]
291 return enc, found
292}
293
294func (r *Registry) lookupInterfaceEncoder(t reflect.Type) (ValueEncoder, bool) {
295 if t == nil {
296 return nil, false
297 }
298 for _, ienc := range r.interfaceEncoders {
299 if !t.Implements(ienc.i) {
300 continue
301 }
302
303 return ienc.ve, true
304 }
305 return nil, false
306}
307
308// LookupDecoder will inspect the registry for a decoder that satisfies the
309// type provided. A decoder registered for a specific type will take
310// precedence over a decoder registered for an interface the type satisfies,
311// which takes precedence over a decoder for the reflect.Kind of the value. If
312// no decoder can be found, an error is returned.
313func (r *Registry) LookupDecoder(t reflect.Type) (ValueDecoder, error) {
314 if t == nil {
315 return nil, ErrNilType
316 }
317 decodererr := ErrNoDecoder{Type: t}
318 r.mu.RLock()
319 dec, found := r.lookupTypeDecoder(t)
320 r.mu.RUnlock()
321 if found {
322 if dec == nil {
323 return nil, ErrNoDecoder{Type: t}
324 }
325 return dec, nil
326 }
327
328 dec, found = r.lookupInterfaceDecoder(t)
329 if found {
330 r.mu.Lock()
331 r.typeDecoders[t] = dec
332 r.mu.Unlock()
333 return dec, nil
334 }
335
336 dec, found = r.kindDecoders[t.Kind()]
337 if !found {
338 r.mu.Lock()
339 r.typeDecoders[t] = nil
340 r.mu.Unlock()
341 return nil, decodererr
342 }
343
344 r.mu.Lock()
345 r.typeDecoders[t] = dec
346 r.mu.Unlock()
347 return dec, nil
348}
349
350func (r *Registry) lookupTypeDecoder(t reflect.Type) (ValueDecoder, bool) {
351 dec, found := r.typeDecoders[t]
352 return dec, found
353}
354
355func (r *Registry) lookupInterfaceDecoder(t reflect.Type) (ValueDecoder, bool) {
356 for _, idec := range r.interfaceDecoders {
357 if !t.Implements(idec.i) && !reflect.PtrTo(t).Implements(idec.i) {
358 continue
359 }
360
361 return idec.vd, true
362 }
363 return nil, false
364}
365
366// LookupTypeMapEntry inspects the registry's type map for a Go type for the corresponding BSON
367// type. If no type is found, ErrNoTypeMapEntry is returned.
368func (r *Registry) LookupTypeMapEntry(bt bsontype.Type) (reflect.Type, error) {
369 t, ok := r.typeMap[bt]
370 if !ok || t == nil {
371 return nil, ErrNoTypeMapEntry{Type: bt}
372 }
373 return t, nil
374}
375
376type interfaceValueEncoder struct {
377 i reflect.Type
378 ve ValueEncoder
379}
380
381type interfaceValueDecoder struct {
382 i reflect.Type
383 vd ValueDecoder
384}