Source file src/pkg/encoding/gob/type.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package gob
6
7 import (
8 "errors"
9 "fmt"
10 "os"
11 "reflect"
12 "sync"
13 "unicode"
14 "unicode/utf8"
15 )
16
17 // userTypeInfo stores the information associated with a type the user has handed
18 // to the package. It's computed once and stored in a map keyed by reflection
19 // type.
20 type userTypeInfo struct {
21 user reflect.Type // the type the user handed us
22 base reflect.Type // the base type after all indirections
23 indir int // number of indirections to reach the base type
24 isGobEncoder bool // does the type implement GobEncoder?
25 isGobDecoder bool // does the type implement GobDecoder?
26 encIndir int8 // number of indirections to reach the receiver type; may be negative
27 decIndir int8 // number of indirections to reach the receiver type; may be negative
28 }
29
30 var (
31 // Protected by an RWMutex because we read it a lot and write
32 // it only when we see a new type, typically when compiling.
33 userTypeLock sync.RWMutex
34 userTypeCache = make(map[reflect.Type]*userTypeInfo)
35 )
36
37 // validType returns, and saves, the information associated with user-provided type rt.
38 // If the user type is not valid, err will be non-nil. To be used when the error handler
39 // is not set up.
40 func validUserType(rt reflect.Type) (ut *userTypeInfo, err error) {
41 userTypeLock.RLock()
42 ut = userTypeCache[rt]
43 userTypeLock.RUnlock()
44 if ut != nil {
45 return
46 }
47 // Now set the value under the write lock.
48 userTypeLock.Lock()
49 defer userTypeLock.Unlock()
50 if ut = userTypeCache[rt]; ut != nil {
51 // Lost the race; not a problem.
52 return
53 }
54 ut = new(userTypeInfo)
55 ut.base = rt
56 ut.user = rt
57 // A type that is just a cycle of pointers (such as type T *T) cannot
58 // be represented in gobs, which need some concrete data. We use a
59 // cycle detection algorithm from Knuth, Vol 2, Section 3.1, Ex 6,
60 // pp 539-540. As we step through indirections, run another type at
61 // half speed. If they meet up, there's a cycle.
62 slowpoke := ut.base // walks half as fast as ut.base
63 for {
64 pt := ut.base
65 if pt.Kind() != reflect.Ptr {
66 break
67 }
68 ut.base = pt.Elem()
69 if ut.base == slowpoke { // ut.base lapped slowpoke
70 // recursive pointer type.
71 return nil, errors.New("can't represent recursive pointer type " + ut.base.String())
72 }
73 if ut.indir%2 == 0 {
74 slowpoke = slowpoke.Elem()
75 }
76 ut.indir++
77 }
78 ut.isGobEncoder, ut.encIndir = implementsInterface(ut.user, gobEncoderInterfaceType)
79 ut.isGobDecoder, ut.decIndir = implementsInterface(ut.user, gobDecoderInterfaceType)
80 userTypeCache[rt] = ut
81 return
82 }
83
84 var (
85 gobEncoderInterfaceType = reflect.TypeOf((*GobEncoder)(nil)).Elem()
86 gobDecoderInterfaceType = reflect.TypeOf((*GobDecoder)(nil)).Elem()
87 )
88
89 // implementsInterface reports whether the type implements the
90 // gobEncoder/gobDecoder interface.
91 // It also returns the number of indirections required to get to the
92 // implementation.
93 func implementsInterface(typ, gobEncDecType reflect.Type) (success bool, indir int8) {
94 if typ == nil {
95 return
96 }
97 rt := typ
98 // The type might be a pointer and we need to keep
99 // dereferencing to the base type until we find an implementation.
100 for {
101 if rt.Implements(gobEncDecType) {
102 return true, indir
103 }
104 if p := rt; p.Kind() == reflect.Ptr {
105 indir++
106 if indir > 100 { // insane number of indirections
107 return false, 0
108 }
109 rt = p.Elem()
110 continue
111 }
112 break
113 }
114 // No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
115 if typ.Kind() != reflect.Ptr {
116 // Not a pointer, but does the pointer work?
117 if reflect.PtrTo(typ).Implements(gobEncDecType) {
118 return true, -1
119 }
120 }
121 return false, 0
122 }
123
124 // userType returns, and saves, the information associated with user-provided type rt.
125 // If the user type is not valid, it calls error.
126 func userType(rt reflect.Type) *userTypeInfo {
127 ut, err := validUserType(rt)
128 if err != nil {
129 error_(err)
130 }
131 return ut
132 }
133
134 // A typeId represents a gob Type as an integer that can be passed on the wire.
135 // Internally, typeIds are used as keys to a map to recover the underlying type info.
136 type typeId int32
137
138 var nextId typeId // incremented for each new type we build
139 var typeLock sync.Mutex // set while building a type
140 const firstUserId = 64 // lowest id number granted to user
141
142 type gobType interface {
143 id() typeId
144 setId(id typeId)
145 name() string
146 string() string // not public; only for debugging
147 safeString(seen map[typeId]bool) string
148 }
149
150 var types = make(map[reflect.Type]gobType)
151 var idToType = make(map[typeId]gobType)
152 var builtinIdToType map[typeId]gobType // set in init() after builtins are established
153
154 func setTypeId(typ gobType) {
155 // When building recursive types, someone may get there before us.
156 if typ.id() != 0 {
157 return
158 }
159 nextId++
160 typ.setId(nextId)
161 idToType[nextId] = typ
162 }
163
164 func (t typeId) gobType() gobType {
165 if t == 0 {
166 return nil
167 }
168 return idToType[t]
169 }
170
171 // string returns the string representation of the type associated with the typeId.
172 func (t typeId) string() string {
173 if t.gobType() == nil {
174 return "<nil>"
175 }
176 return t.gobType().string()
177 }
178
179 // Name returns the name of the type associated with the typeId.
180 func (t typeId) name() string {
181 if t.gobType() == nil {
182 return "<nil>"
183 }
184 return t.gobType().name()
185 }
186
187 // CommonType holds elements of all types.
188 // It is a historical artifact, kept for binary compatibility and exported
189 // only for the benefit of the package's encoding of type descriptors. It is
190 // not intended for direct use by clients.
191 type CommonType struct {
192 Name string
193 Id typeId
194 }
195
196 func (t *CommonType) id() typeId { return t.Id }
197
198 func (t *CommonType) setId(id typeId) { t.Id = id }
199
200 func (t *CommonType) string() string { return t.Name }
201
202 func (t *CommonType) safeString(seen map[typeId]bool) string {
203 return t.Name
204 }
205
206 func (t *CommonType) name() string { return t.Name }
207
208 // Create and check predefined types
209 // The string for tBytes is "bytes" not "[]byte" to signify its specialness.
210
211 var (
212 // Primordial types, needed during initialization.
213 // Always passed as pointers so the interface{} type
214 // goes through without losing its interfaceness.
215 tBool = bootstrapType("bool", (*bool)(nil), 1)
216 tInt = bootstrapType("int", (*int)(nil), 2)
217 tUint = bootstrapType("uint", (*uint)(nil), 3)
218 tFloat = bootstrapType("float", (*float64)(nil), 4)
219 tBytes = bootstrapType("bytes", (*[]byte)(nil), 5)
220 tString = bootstrapType("string", (*string)(nil), 6)
221 tComplex = bootstrapType("complex", (*complex128)(nil), 7)
222 tInterface = bootstrapType("interface", (*interface{})(nil), 8)
223 // Reserve some Ids for compatible expansion
224 tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil), 9)
225 tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil), 10)
226 tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil), 11)
227 tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil), 12)
228 tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil), 13)
229 tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil), 14)
230 tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil), 15)
231 )
232
233 // Predefined because it's needed by the Decoder
234 var tWireType = mustGetTypeInfo(reflect.TypeOf(wireType{})).id
235 var wireTypeUserInfo *userTypeInfo // userTypeInfo of (*wireType)
236
237 func init() {
238 // Some magic numbers to make sure there are no surprises.
239 checkId(16, tWireType)
240 checkId(17, mustGetTypeInfo(reflect.TypeOf(arrayType{})).id)
241 checkId(18, mustGetTypeInfo(reflect.TypeOf(CommonType{})).id)
242 checkId(19, mustGetTypeInfo(reflect.TypeOf(sliceType{})).id)
243 checkId(20, mustGetTypeInfo(reflect.TypeOf(structType{})).id)
244 checkId(21, mustGetTypeInfo(reflect.TypeOf(fieldType{})).id)
245 checkId(23, mustGetTypeInfo(reflect.TypeOf(mapType{})).id)
246
247 builtinIdToType = make(map[typeId]gobType)
248 for k, v := range idToType {
249 builtinIdToType[k] = v
250 }
251
252 // Move the id space upwards to allow for growth in the predefined world
253 // without breaking existing files.
254 if nextId > firstUserId {
255 panic(fmt.Sprintln("nextId too large:", nextId))
256 }
257 nextId = firstUserId
258 registerBasics()
259 wireTypeUserInfo = userType(reflect.TypeOf((*wireType)(nil)))
260 }
261
262 // Array type
263 type arrayType struct {
264 CommonType
265 Elem typeId
266 Len int
267 }
268
269 func newArrayType(name string) *arrayType {
270 a := &arrayType{CommonType{Name: name}, 0, 0}
271 return a
272 }
273
274 func (a *arrayType) init(elem gobType, len int) {
275 // Set our type id before evaluating the element's, in case it's our own.
276 setTypeId(a)
277 a.Elem = elem.id()
278 a.Len = len
279 }
280
281 func (a *arrayType) safeString(seen map[typeId]bool) string {
282 if seen[a.Id] {
283 return a.Name
284 }
285 seen[a.Id] = true
286 return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen))
287 }
288
289 func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) }
290
291 // GobEncoder type (something that implements the GobEncoder interface)
292 type gobEncoderType struct {
293 CommonType
294 }
295
296 func newGobEncoderType(name string) *gobEncoderType {
297 g := &gobEncoderType{CommonType{Name: name}}
298 setTypeId(g)
299 return g
300 }
301
302 func (g *gobEncoderType) safeString(seen map[typeId]bool) string {
303 return g.Name
304 }
305
306 func (g *gobEncoderType) string() string { return g.Name }
307
308 // Map type
309 type mapType struct {
310 CommonType
311 Key typeId
312 Elem typeId
313 }
314
315 func newMapType(name string) *mapType {
316 m := &mapType{CommonType{Name: name}, 0, 0}
317 return m
318 }
319
320 func (m *mapType) init(key, elem gobType) {
321 // Set our type id before evaluating the element's, in case it's our own.
322 setTypeId(m)
323 m.Key = key.id()
324 m.Elem = elem.id()
325 }
326
327 func (m *mapType) safeString(seen map[typeId]bool) string {
328 if seen[m.Id] {
329 return m.Name
330 }
331 seen[m.Id] = true
332 key := m.Key.gobType().safeString(seen)
333 elem := m.Elem.gobType().safeString(seen)
334 return fmt.Sprintf("map[%s]%s", key, elem)
335 }
336
337 func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) }
338
339 // Slice type
340 type sliceType struct {
341 CommonType
342 Elem typeId
343 }
344
345 func newSliceType(name string) *sliceType {
346 s := &sliceType{CommonType{Name: name}, 0}
347 return s
348 }
349
350 func (s *sliceType) init(elem gobType) {
351 // Set our type id before evaluating the element's, in case it's our own.
352 setTypeId(s)
353 // See the comments about ids in newTypeObject. Only slices and
354 // structs have mutual recursion.
355 if elem.id() == 0 {
356 setTypeId(elem)
357 }
358 s.Elem = elem.id()
359 }
360
361 func (s *sliceType) safeString(seen map[typeId]bool) string {
362 if seen[s.Id] {
363 return s.Name
364 }
365 seen[s.Id] = true
366 return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen))
367 }
368
369 func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) }
370
371 // Struct type
372 type fieldType struct {
373 Name string
374 Id typeId
375 }
376
377 type structType struct {
378 CommonType
379 Field []*fieldType
380 }
381
382 func (s *structType) safeString(seen map[typeId]bool) string {
383 if s == nil {
384 return "<nil>"
385 }
386 if _, ok := seen[s.Id]; ok {
387 return s.Name
388 }
389 seen[s.Id] = true
390 str := s.Name + " = struct { "
391 for _, f := range s.Field {
392 str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen))
393 }
394 str += "}"
395 return str
396 }
397
398 func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) }
399
400 func newStructType(name string) *structType {
401 s := &structType{CommonType{Name: name}, nil}
402 // For historical reasons we set the id here rather than init.
403 // See the comment in newTypeObject for details.
404 setTypeId(s)
405 return s
406 }
407
408 // newTypeObject allocates a gobType for the reflection type rt.
409 // Unless ut represents a GobEncoder, rt should be the base type
410 // of ut.
411 // This is only called from the encoding side. The decoding side
412 // works through typeIds and userTypeInfos alone.
413 func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
414 // Does this type implement GobEncoder?
415 if ut.isGobEncoder {
416 return newGobEncoderType(name), nil
417 }
418 var err error
419 var type0, type1 gobType
420 defer func() {
421 if err != nil {
422 delete(types, rt)
423 }
424 }()
425 // Install the top-level type before the subtypes (e.g. struct before
426 // fields) so recursive types can be constructed safely.
427 switch t := rt; t.Kind() {
428 // All basic types are easy: they are predefined.
429 case reflect.Bool:
430 return tBool.gobType(), nil
431
432 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
433 return tInt.gobType(), nil
434
435 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
436 return tUint.gobType(), nil
437
438 case reflect.Float32, reflect.Float64:
439 return tFloat.gobType(), nil
440
441 case reflect.Complex64, reflect.Complex128:
442 return tComplex.gobType(), nil
443
444 case reflect.String:
445 return tString.gobType(), nil
446
447 case reflect.Interface:
448 return tInterface.gobType(), nil
449
450 case reflect.Array:
451 at := newArrayType(name)
452 types[rt] = at
453 type0, err = getBaseType("", t.Elem())
454 if err != nil {
455 return nil, err
456 }
457 // Historical aside:
458 // For arrays, maps, and slices, we set the type id after the elements
459 // are constructed. This is to retain the order of type id allocation after
460 // a fix made to handle recursive types, which changed the order in
461 // which types are built. Delaying the setting in this way preserves
462 // type ids while allowing recursive types to be described. Structs,
463 // done below, were already handling recursion correctly so they
464 // assign the top-level id before those of the field.
465 at.init(type0, t.Len())
466 return at, nil
467
468 case reflect.Map:
469 mt := newMapType(name)
470 types[rt] = mt
471 type0, err = getBaseType("", t.Key())
472 if err != nil {
473 return nil, err
474 }
475 type1, err = getBaseType("", t.Elem())
476 if err != nil {
477 return nil, err
478 }
479 mt.init(type0, type1)
480 return mt, nil
481
482 case reflect.Slice:
483 // []byte == []uint8 is a special case
484 if t.Elem().Kind() == reflect.Uint8 {
485 return tBytes.gobType(), nil
486 }
487 st := newSliceType(name)
488 types[rt] = st
489 type0, err = getBaseType(t.Elem().Name(), t.Elem())
490 if err != nil {
491 return nil, err
492 }
493 st.init(type0)
494 return st, nil
495
496 case reflect.Struct:
497 st := newStructType(name)
498 types[rt] = st
499 idToType[st.id()] = st
500 for i := 0; i < t.NumField(); i++ {
501 f := t.Field(i)
502 if !isExported(f.Name) {
503 continue
504 }
505 typ := userType(f.Type).base
506 tname := typ.Name()
507 if tname == "" {
508 t := userType(f.Type).base
509 tname = t.String()
510 }
511 gt, err := getBaseType(tname, f.Type)
512 if err != nil {
513 return nil, err
514 }
515 // Some mutually recursive types can cause us to be here while
516 // still defining the element. Fix the element type id here.
517 // We could do this more neatly by setting the id at the start of
518 // building every type, but that would break binary compatibility.
519 if gt.id() == 0 {
520 setTypeId(gt)
521 }
522 st.Field = append(st.Field, &fieldType{f.Name, gt.id()})
523 }
524 return st, nil
525
526 default:
527 return nil, errors.New("gob NewTypeObject can't handle type: " + rt.String())
528 }
529 return nil, nil
530 }
531
532 // isExported reports whether this is an exported - upper case - name.
533 func isExported(name string) bool {
534 rune, _ := utf8.DecodeRuneInString(name)
535 return unicode.IsUpper(rune)
536 }
537
538 // getBaseType returns the Gob type describing the given reflect.Type's base type.
539 // typeLock must be held.
540 func getBaseType(name string, rt reflect.Type) (gobType, error) {
541 ut := userType(rt)
542 return getType(name, ut, ut.base)
543 }
544
545 // getType returns the Gob type describing the given reflect.Type.
546 // Should be called only when handling GobEncoders/Decoders,
547 // which may be pointers. All other types are handled through the
548 // base type, never a pointer.
549 // typeLock must be held.
550 func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
551 typ, present := types[rt]
552 if present {
553 return typ, nil
554 }
555 typ, err := newTypeObject(name, ut, rt)
556 if err == nil {
557 types[rt] = typ
558 }
559 return typ, err
560 }
561
562 func checkId(want, got typeId) {
563 if want != got {
564 fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
565 panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
566 }
567 }
568
569 // used for building the basic types; called only from init(). the incoming
570 // interface always refers to a pointer.
571 func bootstrapType(name string, e interface{}, expect typeId) typeId {
572 rt := reflect.TypeOf(e).Elem()
573 _, present := types[rt]
574 if present {
575 panic("bootstrap type already present: " + name + ", " + rt.String())
576 }
577 typ := &CommonType{Name: name}
578 types[rt] = typ
579 setTypeId(typ)
580 checkId(expect, nextId)
581 userType(rt) // might as well cache it now
582 return nextId
583 }
584
585 // Representation of the information we send and receive about this type.
586 // Each value we send is preceded by its type definition: an encoded int.
587 // However, the very first time we send the value, we first send the pair
588 // (-id, wireType).
589 // For bootstrapping purposes, we assume that the recipient knows how
590 // to decode a wireType; it is exactly the wireType struct here, interpreted
591 // using the gob rules for sending a structure, except that we assume the
592 // ids for wireType and structType etc. are known. The relevant pieces
593 // are built in encode.go's init() function.
594 // To maintain binary compatibility, if you extend this type, always put
595 // the new fields last.
596 type wireType struct {
597 ArrayT *arrayType
598 SliceT *sliceType
599 StructT *structType
600 MapT *mapType
601 GobEncoderT *gobEncoderType
602 }
603
604 func (w *wireType) string() string {
605 const unknown = "unknown type"
606 if w == nil {
607 return unknown
608 }
609 switch {
610 case w.ArrayT != nil:
611 return w.ArrayT.Name
612 case w.SliceT != nil:
613 return w.SliceT.Name
614 case w.StructT != nil:
615 return w.StructT.Name
616 case w.MapT != nil:
617 return w.MapT.Name
618 case w.GobEncoderT != nil:
619 return w.GobEncoderT.Name
620 }
621 return unknown
622 }
623
624 type typeInfo struct {
625 id typeId
626 encoder *encEngine
627 wire *wireType
628 }
629
630 var typeInfoMap = make(map[reflect.Type]*typeInfo) // protected by typeLock
631
632 // typeLock must be held.
633 func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
634 rt := ut.base
635 if ut.isGobEncoder {
636 // We want the user type, not the base type.
637 rt = ut.user
638 }
639 info, ok := typeInfoMap[rt]
640 if ok {
641 return info, nil
642 }
643 info = new(typeInfo)
644 gt, err := getBaseType(rt.Name(), rt)
645 if err != nil {
646 return nil, err
647 }
648 info.id = gt.id()
649
650 if ut.isGobEncoder {
651 userType, err := getType(rt.Name(), ut, rt)
652 if err != nil {
653 return nil, err
654 }
655 info.wire = &wireType{GobEncoderT: userType.id().gobType().(*gobEncoderType)}
656 typeInfoMap[ut.user] = info
657 return info, nil
658 }
659
660 t := info.id.gobType()
661 switch typ := rt; typ.Kind() {
662 case reflect.Array:
663 info.wire = &wireType{ArrayT: t.(*arrayType)}
664 case reflect.Map:
665 info.wire = &wireType{MapT: t.(*mapType)}
666 case reflect.Slice:
667 // []byte == []uint8 is a special case handled separately
668 if typ.Elem().Kind() != reflect.Uint8 {
669 info.wire = &wireType{SliceT: t.(*sliceType)}
670 }
671 case reflect.Struct:
672 info.wire = &wireType{StructT: t.(*structType)}
673 }
674 typeInfoMap[rt] = info
675 return info, nil
676 }
677
678 // Called only when a panic is acceptable and unexpected.
679 func mustGetTypeInfo(rt reflect.Type) *typeInfo {
680 t, err := getTypeInfo(userType(rt))
681 if err != nil {
682 panic("getTypeInfo: " + err.Error())
683 }
684 return t
685 }
686
687 // GobEncoder is the interface describing data that provides its own
688 // representation for encoding values for transmission to a GobDecoder.
689 // A type that implements GobEncoder and GobDecoder has complete
690 // control over the representation of its data and may therefore
691 // contain things such as private fields, channels, and functions,
692 // which are not usually transmissible in gob streams.
693 //
694 // Note: Since gobs can be stored permanently, It is good design
695 // to guarantee the encoding used by a GobEncoder is stable as the
696 // software evolves. For instance, it might make sense for GobEncode
697 // to include a version number in the encoding.
698 type GobEncoder interface {
699 // GobEncode returns a byte slice representing the encoding of the
700 // receiver for transmission to a GobDecoder, usually of the same
701 // concrete type.
702 GobEncode() ([]byte, error)
703 }
704
705 // GobDecoder is the interface describing data that provides its own
706 // routine for decoding transmitted values sent by a GobEncoder.
707 type GobDecoder interface {
708 // GobDecode overwrites the receiver, which must be a pointer,
709 // with the value represented by the byte slice, which was written
710 // by GobEncode, usually for the same concrete type.
711 GobDecode([]byte) error
712 }
713
714 var (
715 nameToConcreteType = make(map[string]reflect.Type)
716 concreteTypeToName = make(map[reflect.Type]string)
717 )
718
719 // RegisterName is like Register but uses the provided name rather than the
720 // type's default.
721 func RegisterName(name string, value interface{}) {
722 if name == "" {
723 // reserved for nil
724 panic("attempt to register empty name")
725 }
726 ut := userType(reflect.TypeOf(value))
727 // Check for incompatible duplicates. The name must refer to the
728 // same user type, and vice versa.
729 if t, ok := nameToConcreteType[name]; ok && t != ut.user {
730 panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
731 }
732 if n, ok := concreteTypeToName[ut.base]; ok && n != name {
733 panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
734 }
735 // Store the name and type provided by the user....
736 nameToConcreteType[name] = reflect.TypeOf(value)
737 // but the flattened type in the type table, since that's what decode needs.
738 concreteTypeToName[ut.base] = name
739 }
740
741 // Register records a type, identified by a value for that type, under its
742 // internal type name. That name will identify the concrete type of a value
743 // sent or received as an interface variable. Only types that will be
744 // transferred as implementations of interface values need to be registered.
745 // Expecting to be used only during initialization, it panics if the mapping
746 // between types and names is not a bijection.
747 func Register(value interface{}) {
748 // Default to printed representation for unnamed types
749 rt := reflect.TypeOf(value)
750 name := rt.String()
751
752 // But for named types (or pointers to them), qualify with import path.
753 // Dereference one pointer looking for a named type.
754 star := ""
755 if rt.Name() == "" {
756 if pt := rt; pt.Kind() == reflect.Ptr {
757 star = "*"
758 rt = pt
759 }
760 }
761 if rt.Name() != "" {
762 if rt.PkgPath() == "" {
763 name = star + rt.Name()
764 } else {
765 name = star + rt.PkgPath() + "." + rt.Name()
766 }
767 }
768
769 RegisterName(name, value)
770 }
771
772 func registerBasics() {
773 Register(int(0))
774 Register(int8(0))
775 Register(int16(0))
776 Register(int32(0))
777 Register(int64(0))
778 Register(uint(0))
779 Register(uint8(0))
780 Register(uint16(0))
781 Register(uint32(0))
782 Register(uint64(0))
783 Register(float32(0))
784 Register(float64(0))
785 Register(complex64(0i))
786 Register(complex128(0i))
787 Register(uintptr(0))
788 Register(false)
789 Register("")
790 Register([]byte(nil))
791 Register([]int(nil))
792 Register([]int8(nil))
793 Register([]int16(nil))
794 Register([]int32(nil))
795 Register([]int64(nil))
796 Register([]uint(nil))
797 Register([]uint8(nil))
798 Register([]uint16(nil))
799 Register([]uint32(nil))
800 Register([]uint64(nil))
801 Register([]float32(nil))
802 Register([]float64(nil))
803 Register([]complex64(nil))
804 Register([]complex128(nil))
805 Register([]uintptr(nil))
806 Register([]bool(nil))
807 Register([]string(nil))
808 }