podman

Форк
0
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

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
var ErrNilType = errors.New("cannot perform a decoder lookup on <nil>")
20

21
// ErrNotPointer is returned when a non-pointer type is provided to LookupDecoder.
22
var ErrNotPointer = errors.New("non-pointer provided to LookupDecoder")
23

24
// ErrNoEncoder is returned when there wasn't an encoder available for a type.
25
type ErrNoEncoder struct {
26
	Type reflect.Type
27
}
28

29
func (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.
37
type ErrNoDecoder struct {
38
	Type reflect.Type
39
}
40

41
func (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.
46
type ErrNoTypeMapEntry struct {
47
	Type bsontype.Type
48
}
49

50
func (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.
55
var 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.
59
type RegistryBuilder struct {
60
	typeEncoders      map[reflect.Type]ValueEncoder
61
	interfaceEncoders []interfaceValueEncoder
62
	kindEncoders      map[reflect.Kind]ValueEncoder
63

64
	typeDecoders      map[reflect.Type]ValueDecoder
65
	interfaceDecoders []interfaceValueDecoder
66
	kindDecoders      map[reflect.Kind]ValueDecoder
67

68
	typeMap 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.
73
type Registry struct {
74
	typeEncoders map[reflect.Type]ValueEncoder
75
	typeDecoders map[reflect.Type]ValueDecoder
76

77
	interfaceEncoders []interfaceValueEncoder
78
	interfaceDecoders []interfaceValueDecoder
79

80
	kindEncoders map[reflect.Kind]ValueEncoder
81
	kindDecoders map[reflect.Kind]ValueDecoder
82

83
	typeMap map[bsontype.Type]reflect.Type
84

85
	mu sync.RWMutex
86
}
87

88
// NewRegistryBuilder creates a new empty RegistryBuilder.
89
func NewRegistryBuilder() *RegistryBuilder {
90
	return &RegistryBuilder{
91
		typeEncoders: make(map[reflect.Type]ValueEncoder),
92
		typeDecoders: make(map[reflect.Type]ValueDecoder),
93

94
		interfaceEncoders: make([]interfaceValueEncoder, 0),
95
		interfaceDecoders: make([]interfaceValueDecoder, 0),
96

97
		kindEncoders: make(map[reflect.Kind]ValueEncoder),
98
		kindDecoders: make(map[reflect.Kind]ValueDecoder),
99

100
		typeMap: make(map[bsontype.Type]reflect.Type),
101
	}
102
}
103

104
func buildDefaultRegistry() *Registry {
105
	rb := NewRegistryBuilder()
106
	defaultValueEncoders.RegisterDefaultEncoders(rb)
107
	defaultValueDecoders.RegisterDefaultDecoders(rb)
108
	return rb.Build()
109
}
110

111
// RegisterCodec will register the provided ValueCodec for the provided type.
112
func (rb *RegistryBuilder) RegisterCodec(t reflect.Type, codec ValueCodec) *RegistryBuilder {
113
	rb.RegisterTypeEncoder(t, codec)
114
	rb.RegisterTypeDecoder(t, codec)
115
	return 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.
125
func (rb *RegistryBuilder) RegisterTypeEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
126
	rb.typeEncoders[t] = enc
127
	return 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.
133
func (rb *RegistryBuilder) RegisterHookEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
134
	if t.Kind() != reflect.Interface {
135
		panicStr := fmt.Sprintf("RegisterHookEncoder expects a type with kind reflect.Interface, "+
136
			"got type %s with kind %s", t, t.Kind())
137
		panic(panicStr)
138
	}
139

140
	for idx, encoder := range rb.interfaceEncoders {
141
		if encoder.i == t {
142
			rb.interfaceEncoders[idx].ve = enc
143
			return rb
144
		}
145
	}
146

147
	rb.interfaceEncoders = append(rb.interfaceEncoders, interfaceValueEncoder{i: t, ve: enc})
148
	return 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.
158
func (rb *RegistryBuilder) RegisterTypeDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
159
	rb.typeDecoders[t] = dec
160
	return 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.
166
func (rb *RegistryBuilder) RegisterHookDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
167
	if t.Kind() != reflect.Interface {
168
		panicStr := fmt.Sprintf("RegisterHookDecoder expects a type with kind reflect.Interface, "+
169
			"got type %s with kind %s", t, t.Kind())
170
		panic(panicStr)
171
	}
172

173
	for idx, decoder := range rb.interfaceDecoders {
174
		if decoder.i == t {
175
			rb.interfaceDecoders[idx].vd = dec
176
			return rb
177
		}
178
	}
179

180
	rb.interfaceDecoders = append(rb.interfaceDecoders, interfaceValueDecoder{i: t, vd: dec})
181
	return rb
182
}
183

184
// RegisterEncoder registers the provided type and encoder pair.
185
//
186
// Deprecated: Use RegisterTypeEncoder or RegisterHookEncoder instead.
187
func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
188
	if t == tEmpty {
189
		rb.typeEncoders[t] = enc
190
		return rb
191
	}
192
	switch t.Kind() {
193
	case reflect.Interface:
194
		for idx, ir := range rb.interfaceEncoders {
195
			if ir.i == t {
196
				rb.interfaceEncoders[idx].ve = enc
197
				return rb
198
			}
199
		}
200

201
		rb.interfaceEncoders = append(rb.interfaceEncoders, interfaceValueEncoder{i: t, ve: enc})
202
	default:
203
		rb.typeEncoders[t] = enc
204
	}
205
	return rb
206
}
207

208
// RegisterDecoder registers the provided type and decoder pair.
209
//
210
// Deprecated: Use RegisterTypeDecoder or RegisterHookDecoder instead.
211
func (rb *RegistryBuilder) RegisterDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
212
	if t == nil {
213
		rb.typeDecoders[nil] = dec
214
		return rb
215
	}
216
	if t == tEmpty {
217
		rb.typeDecoders[t] = dec
218
		return rb
219
	}
220
	switch t.Kind() {
221
	case reflect.Interface:
222
		for idx, ir := range rb.interfaceDecoders {
223
			if ir.i == t {
224
				rb.interfaceDecoders[idx].vd = dec
225
				return rb
226
			}
227
		}
228

229
		rb.interfaceDecoders = append(rb.interfaceDecoders, interfaceValueDecoder{i: t, vd: dec})
230
	default:
231
		rb.typeDecoders[t] = dec
232
	}
233
	return rb
234
}
235

236
// RegisterDefaultEncoder will registr the provided ValueEncoder to the provided
237
// kind.
238
func (rb *RegistryBuilder) RegisterDefaultEncoder(kind reflect.Kind, enc ValueEncoder) *RegistryBuilder {
239
	rb.kindEncoders[kind] = enc
240
	return rb
241
}
242

243
// RegisterDefaultDecoder will register the provided ValueDecoder to the
244
// provided kind.
245
func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDecoder) *RegistryBuilder {
246
	rb.kindDecoders[kind] = dec
247
	return 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{}))
259
func (rb *RegistryBuilder) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) *RegistryBuilder {
260
	rb.typeMap[bt] = rt
261
	return rb
262
}
263

264
// Build creates a Registry from the current state of this RegistryBuilder.
265
func (rb *RegistryBuilder) Build() *Registry {
266
	registry := new(Registry)
267

268
	registry.typeEncoders = make(map[reflect.Type]ValueEncoder)
269
	for t, enc := range rb.typeEncoders {
270
		registry.typeEncoders[t] = enc
271
	}
272

273
	registry.typeDecoders = make(map[reflect.Type]ValueDecoder)
274
	for t, dec := range rb.typeDecoders {
275
		registry.typeDecoders[t] = dec
276
	}
277

278
	registry.interfaceEncoders = make([]interfaceValueEncoder, len(rb.interfaceEncoders))
279
	copy(registry.interfaceEncoders, rb.interfaceEncoders)
280

281
	registry.interfaceDecoders = make([]interfaceValueDecoder, len(rb.interfaceDecoders))
282
	copy(registry.interfaceDecoders, rb.interfaceDecoders)
283

284
	registry.kindEncoders = make(map[reflect.Kind]ValueEncoder)
285
	for kind, enc := range rb.kindEncoders {
286
		registry.kindEncoders[kind] = enc
287
	}
288

289
	registry.kindDecoders = make(map[reflect.Kind]ValueDecoder)
290
	for kind, dec := range rb.kindDecoders {
291
		registry.kindDecoders[kind] = dec
292
	}
293

294
	registry.typeMap = make(map[bsontype.Type]reflect.Type)
295
	for bt, rt := range rb.typeMap {
296
		registry.typeMap[bt] = rt
297
	}
298

299
	return 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.
313
func (r *Registry) LookupEncoder(t reflect.Type) (ValueEncoder, error) {
314
	encodererr := ErrNoEncoder{Type: t}
315
	r.mu.RLock()
316
	enc, found := r.lookupTypeEncoder(t)
317
	r.mu.RUnlock()
318
	if found {
319
		if enc == nil {
320
			return nil, ErrNoEncoder{Type: t}
321
		}
322
		return enc, nil
323
	}
324

325
	enc, found = r.lookupInterfaceEncoder(t, true)
326
	if found {
327
		r.mu.Lock()
328
		r.typeEncoders[t] = enc
329
		r.mu.Unlock()
330
		return enc, nil
331
	}
332

333
	if t == nil {
334
		r.mu.Lock()
335
		r.typeEncoders[t] = nil
336
		r.mu.Unlock()
337
		return nil, encodererr
338
	}
339

340
	enc, found = r.kindEncoders[t.Kind()]
341
	if !found {
342
		r.mu.Lock()
343
		r.typeEncoders[t] = nil
344
		r.mu.Unlock()
345
		return nil, encodererr
346
	}
347

348
	r.mu.Lock()
349
	r.typeEncoders[t] = enc
350
	r.mu.Unlock()
351
	return enc, nil
352
}
353

354
func (r *Registry) lookupTypeEncoder(t reflect.Type) (ValueEncoder, bool) {
355
	enc, found := r.typeEncoders[t]
356
	return enc, found
357
}
358

359
func (r *Registry) lookupInterfaceEncoder(t reflect.Type, allowAddr bool) (ValueEncoder, bool) {
360
	if t == nil {
361
		return nil, false
362
	}
363
	for _, ienc := range r.interfaceEncoders {
364
		if t.Implements(ienc.i) {
365
			return ienc.ve, true
366
		}
367
		if 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
370
			defaultEnc, found := r.lookupInterfaceEncoder(t, false)
371
			if !found {
372
				defaultEnc = r.kindEncoders[t.Kind()]
373
			}
374
			return newCondAddrEncoder(ienc.ve, defaultEnc), true
375
		}
376
	}
377
	return 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.
391
func (r *Registry) LookupDecoder(t reflect.Type) (ValueDecoder, error) {
392
	if t == nil {
393
		return nil, ErrNilType
394
	}
395
	decodererr := ErrNoDecoder{Type: t}
396
	r.mu.RLock()
397
	dec, found := r.lookupTypeDecoder(t)
398
	r.mu.RUnlock()
399
	if found {
400
		if dec == nil {
401
			return nil, ErrNoDecoder{Type: t}
402
		}
403
		return dec, nil
404
	}
405

406
	dec, found = r.lookupInterfaceDecoder(t, true)
407
	if found {
408
		r.mu.Lock()
409
		r.typeDecoders[t] = dec
410
		r.mu.Unlock()
411
		return dec, nil
412
	}
413

414
	dec, found = r.kindDecoders[t.Kind()]
415
	if !found {
416
		r.mu.Lock()
417
		r.typeDecoders[t] = nil
418
		r.mu.Unlock()
419
		return nil, decodererr
420
	}
421

422
	r.mu.Lock()
423
	r.typeDecoders[t] = dec
424
	r.mu.Unlock()
425
	return dec, nil
426
}
427

428
func (r *Registry) lookupTypeDecoder(t reflect.Type) (ValueDecoder, bool) {
429
	dec, found := r.typeDecoders[t]
430
	return dec, found
431
}
432

433
func (r *Registry) lookupInterfaceDecoder(t reflect.Type, allowAddr bool) (ValueDecoder, bool) {
434
	for _, idec := range r.interfaceDecoders {
435
		if t.Implements(idec.i) {
436
			return idec.vd, true
437
		}
438
		if 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
441
			defaultDec, found := r.lookupInterfaceDecoder(t, false)
442
			if !found {
443
				defaultDec = r.kindDecoders[t.Kind()]
444
			}
445
			return newCondAddrDecoder(idec.vd, defaultDec), true
446
		}
447
	}
448
	return 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.
453
func (r *Registry) LookupTypeMapEntry(bt bsontype.Type) (reflect.Type, error) {
454
	t, ok := r.typeMap[bt]
455
	if !ok || t == nil {
456
		return nil, ErrNoTypeMapEntry{Type: bt}
457
	}
458
	return t, nil
459
}
460

461
type interfaceValueEncoder struct {
462
	i  reflect.Type
463
	ve ValueEncoder
464
}
465

466
type interfaceValueDecoder struct {
467
	i  reflect.Type
468
	vd ValueDecoder
469
}
470

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.