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