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.
16 // userTypeInfo stores the information associated with a type the user has handed
17 // to the package. It's computed once and stored in a map keyed by reflection
19 type userTypeInfo
struct {
20 user reflect
.Type
// the type the user handed us
21 base reflect
.Type
// the base type after all indirections
22 indir
int // number of indirections to reach the base type
23 isGobEncoder
bool // does the type implement GobEncoder?
24 isGobDecoder
bool // does the type implement GobDecoder?
25 encIndir
int8 // number of indirections to reach the receiver type; may be negative
26 decIndir
int8 // number of indirections to reach the receiver type; may be negative
30 // Protected by an RWMutex because we read it a lot and write
31 // it only when we see a new type, typically when compiling.
32 userTypeLock sync
.RWMutex
33 userTypeCache
= make(map[reflect
.Type
]*userTypeInfo
)
36 // validType returns, and saves, the information associated with user-provided type rt.
37 // If the user type is not valid, err will be non-nil. To be used when the error handler
39 func validUserType(rt reflect
.Type
) (ut
*userTypeInfo
, err os
.Error
) {
41 ut
= userTypeCache
[rt
]
42 userTypeLock
.RUnlock()
46 // Now set the value under the write lock.
48 defer userTypeLock
.Unlock()
49 if ut
= userTypeCache
[rt
]; ut
!= nil {
50 // Lost the race; not a problem.
53 ut
= new(userTypeInfo
)
56 // A type that is just a cycle of pointers (such as type T *T) cannot
57 // be represented in gobs, which need some concrete data. We use a
58 // cycle detection algorithm from Knuth, Vol 2, Section 3.1, Ex 6,
59 // pp 539-540. As we step through indirections, run another type at
60 // half speed. If they meet up, there's a cycle.
61 slowpoke
:= ut
.base
// walks half as fast as ut.base
63 pt
, ok
:= ut
.base
.(*reflect
.PtrType
)
68 if ut
.base
== slowpoke
{ // ut.base lapped slowpoke
69 // recursive pointer type.
70 return nil, os
.ErrorString("can't represent recursive pointer type " + ut
.base
.String())
73 slowpoke
= slowpoke
.(*reflect
.PtrType
).Elem()
77 ut
.isGobEncoder
, ut
.encIndir
= implementsInterface(ut
.user
, gobEncoderCheck
)
78 ut
.isGobDecoder
, ut
.decIndir
= implementsInterface(ut
.user
, gobDecoderCheck
)
79 userTypeCache
[rt
] = ut
84 gobEncodeMethodName
= "GobEncode"
85 gobDecodeMethodName
= "GobDecode"
88 // implements returns whether the type implements the interface, as encoded
89 // in the check function.
90 func implements(typ reflect
.Type
, check
func(typ reflect
.Type
) bool) bool {
91 if typ
.NumMethod() == 0 { // avoid allocations etc. unless there's some chance
97 // gobEncoderCheck makes the type assertion a boolean function.
98 func gobEncoderCheck(typ reflect
.Type
) bool {
99 _
, ok
:= reflect
.MakeZero(typ
).Interface().(GobEncoder
)
103 // gobDecoderCheck makes the type assertion a boolean function.
104 func gobDecoderCheck(typ reflect
.Type
) bool {
105 _
, ok
:= reflect
.MakeZero(typ
).Interface().(GobDecoder
)
109 // implementsInterface reports whether the type implements the
110 // interface. (The actual check is done through the provided function.)
111 // It also returns the number of indirections required to get to the
113 func implementsInterface(typ reflect
.Type
, check
func(typ reflect
.Type
) bool) (success
bool, indir
int8) {
118 // The type might be a pointer and we need to keep
119 // dereferencing to the base type until we find an implementation.
121 if implements(rt
, check
) {
124 if p
, ok
:= rt
.(*reflect
.PtrType
); ok
{
126 if indir
> 100 { // insane number of indirections
134 // No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
135 if _
, ok
:= typ
.(*reflect
.PtrType
); !ok
{
136 // Not a pointer, but does the pointer work?
137 if implements(reflect
.PtrTo(typ
), check
) {
144 // userType returns, and saves, the information associated with user-provided type rt.
145 // If the user type is not valid, it calls error.
146 func userType(rt reflect
.Type
) *userTypeInfo
{
147 ut
, err
:= validUserType(rt
)
153 // A typeId represents a gob Type as an integer that can be passed on the wire.
154 // Internally, typeIds are used as keys to a map to recover the underlying type info.
157 var nextId typeId
// incremented for each new type we build
158 var typeLock sync
.Mutex
// set while building a type
159 const firstUserId
= 64 // lowest id number granted to user
161 type gobType
interface {
165 string() string // not public; only for debugging
166 safeString(seen
map[typeId
]bool) string
169 var types
= make(map[reflect
.Type
]gobType
)
170 var idToType
= make(map[typeId
]gobType
)
171 var builtinIdToType
map[typeId
]gobType
// set in init() after builtins are established
173 func setTypeId(typ gobType
) {
176 idToType
[nextId
] = typ
179 func (t typeId
) gobType() gobType
{
186 // string returns the string representation of the type associated with the typeId.
187 func (t typeId
) string() string {
188 if t
.gobType() == nil {
191 return t
.gobType().string()
194 // Name returns the name of the type associated with the typeId.
195 func (t typeId
) name() string {
196 if t
.gobType() == nil {
199 return t
.gobType().name()
202 // Common elements of all types.
203 type CommonType
struct {
208 func (t
*CommonType
) id() typeId
{ return t
.Id
}
210 func (t
*CommonType
) setId(id typeId
) { t
.Id
= id
}
212 func (t
*CommonType
) string() string { return t
.Name
}
214 func (t
*CommonType
) safeString(seen
map[typeId
]bool) string {
218 func (t
*CommonType
) name() string { return t
.Name
}
220 // Create and check predefined types
221 // The string for tBytes is "bytes" not "[]byte" to signify its specialness.
224 // Primordial types, needed during initialization.
225 // Always passed as pointers so the interface{} type
226 // goes through without losing its interfaceness.
227 tBool
= bootstrapType("bool", (*bool)(nil), 1)
228 tInt
= bootstrapType("int", (*int)(nil), 2)
229 tUint
= bootstrapType("uint", (*uint)(nil), 3)
230 tFloat
= bootstrapType("float", (*float64)(nil), 4)
231 tBytes
= bootstrapType("bytes", (*[]byte)(nil), 5)
232 tString
= bootstrapType("string", (*string)(nil), 6)
233 tComplex
= bootstrapType("complex", (*complex128
)(nil), 7)
234 tInterface
= bootstrapType("interface", (*interface{})(nil), 8)
235 // Reserve some Ids for compatible expansion
236 tReserved7
= bootstrapType("_reserved1", (*struct{ r7
int })(nil), 9)
237 tReserved6
= bootstrapType("_reserved1", (*struct{ r6
int })(nil), 10)
238 tReserved5
= bootstrapType("_reserved1", (*struct{ r5
int })(nil), 11)
239 tReserved4
= bootstrapType("_reserved1", (*struct{ r4
int })(nil), 12)
240 tReserved3
= bootstrapType("_reserved1", (*struct{ r3
int })(nil), 13)
241 tReserved2
= bootstrapType("_reserved1", (*struct{ r2
int })(nil), 14)
242 tReserved1
= bootstrapType("_reserved1", (*struct{ r1
int })(nil), 15)
245 // Predefined because it's needed by the Decoder
246 var tWireType
= mustGetTypeInfo(reflect
.Typeof(wireType
{})).id
247 var wireTypeUserInfo
*userTypeInfo
// userTypeInfo of (*wireType)
250 // Some magic numbers to make sure there are no surprises.
251 checkId(16, tWireType
)
252 checkId(17, mustGetTypeInfo(reflect
.Typeof(arrayType
{})).id
)
253 checkId(18, mustGetTypeInfo(reflect
.Typeof(CommonType
{})).id
)
254 checkId(19, mustGetTypeInfo(reflect
.Typeof(sliceType
{})).id
)
255 checkId(20, mustGetTypeInfo(reflect
.Typeof(structType
{})).id
)
256 checkId(21, mustGetTypeInfo(reflect
.Typeof(fieldType
{})).id
)
257 checkId(23, mustGetTypeInfo(reflect
.Typeof(mapType
{})).id
)
259 builtinIdToType
= make(map[typeId
]gobType
)
260 for k
, v
:= range idToType
{
261 builtinIdToType
[k
] = v
264 // Move the id space upwards to allow for growth in the predefined world
265 // without breaking existing files.
266 if nextId
> firstUserId
{
267 panic(fmt
.Sprintln("nextId too large:", nextId
))
271 wireTypeUserInfo
= userType(reflect
.Typeof((*wireType
)(nil)))
275 type arrayType
struct {
281 func newArrayType(name
string) *arrayType
{
282 a
:= &arrayType
{CommonType
{Name
: name
}, 0, 0}
286 func (a
*arrayType
) init(elem gobType
, len int) {
287 // Set our type id before evaluating the element's, in case it's our own.
293 func (a
*arrayType
) safeString(seen
map[typeId
]bool) string {
298 return fmt
.Sprintf("[%d]%s", a
.Len
, a
.Elem
.gobType().safeString(seen
))
301 func (a
*arrayType
) string() string { return a
.safeString(make(map[typeId
]bool)) }
303 // GobEncoder type (something that implements the GobEncoder interface)
304 type gobEncoderType
struct {
308 func newGobEncoderType(name
string) *gobEncoderType
{
309 g
:= &gobEncoderType
{CommonType
{Name
: name
}}
314 func (g
*gobEncoderType
) safeString(seen
map[typeId
]bool) string {
318 func (g
*gobEncoderType
) string() string { return g
.Name
}
321 type mapType
struct {
327 func newMapType(name
string) *mapType
{
328 m
:= &mapType
{CommonType
{Name
: name
}, 0, 0}
332 func (m
*mapType
) init(key
, elem gobType
) {
333 // Set our type id before evaluating the element's, in case it's our own.
339 func (m
*mapType
) safeString(seen
map[typeId
]bool) string {
344 key
:= m
.Key
.gobType().safeString(seen
)
345 elem
:= m
.Elem
.gobType().safeString(seen
)
346 return fmt
.Sprintf("map[%s]%s", key
, elem
)
349 func (m
*mapType
) string() string { return m
.safeString(make(map[typeId
]bool)) }
352 type sliceType
struct {
357 func newSliceType(name
string) *sliceType
{
358 s
:= &sliceType
{CommonType
{Name
: name
}, 0}
362 func (s
*sliceType
) init(elem gobType
) {
363 // Set our type id before evaluating the element's, in case it's our own.
368 func (s
*sliceType
) safeString(seen
map[typeId
]bool) string {
373 return fmt
.Sprintf("[]%s", s
.Elem
.gobType().safeString(seen
))
376 func (s
*sliceType
) string() string { return s
.safeString(make(map[typeId
]bool)) }
379 type fieldType
struct {
384 type structType
struct {
389 func (s
*structType
) safeString(seen
map[typeId
]bool) string {
393 if _
, ok
:= seen
[s
.Id
]; ok
{
397 str
:= s
.Name
+ " = struct { "
398 for _
, f
:= range s
.Field
{
399 str
+= fmt
.Sprintf("%s %s; ", f
.Name
, f
.Id
.gobType().safeString(seen
))
405 func (s
*structType
) string() string { return s
.safeString(make(map[typeId
]bool)) }
407 func newStructType(name
string) *structType
{
408 s
:= &structType
{CommonType
{Name
: name
}, nil}
409 // For historical reasons we set the id here rather than init.
410 // See the comment in newTypeObject for details.
415 // newTypeObject allocates a gobType for the reflection type rt.
416 // Unless ut represents a GobEncoder, rt should be the base type
418 // This is only called from the encoding side. The decoding side
419 // works through typeIds and userTypeInfos alone.
420 func newTypeObject(name
string, ut
*userTypeInfo
, rt reflect
.Type
) (gobType
, os
.Error
) {
421 // Does this type implement GobEncoder?
423 return newGobEncoderType(name
), nil
426 var type0
, type1 gobType
429 types
[rt
] = nil, false
432 // Install the top-level type before the subtypes (e.g. struct before
433 // fields) so recursive types can be constructed safely.
434 switch t
:= rt
.(type) {
435 // All basic types are easy: they are predefined.
436 case *reflect
.BoolType
:
437 return tBool
.gobType(), nil
439 case *reflect
.IntType
:
440 return tInt
.gobType(), nil
442 case *reflect
.UintType
:
443 return tUint
.gobType(), nil
445 case *reflect
.FloatType
:
446 return tFloat
.gobType(), nil
448 case *reflect
.ComplexType
:
449 return tComplex
.gobType(), nil
451 case *reflect
.StringType
:
452 return tString
.gobType(), nil
454 case *reflect
.InterfaceType
:
455 return tInterface
.gobType(), nil
457 case *reflect
.ArrayType
:
458 at
:= newArrayType(name
)
460 type0
, err
= getBaseType("", t
.Elem())
465 // For arrays, maps, and slices, we set the type id after the elements
466 // are constructed. This is to retain the order of type id allocation after
467 // a fix made to handle recursive types, which changed the order in
468 // which types are built. Delaying the setting in this way preserves
469 // type ids while allowing recursive types to be described. Structs,
470 // done below, were already handling recursion correctly so they
471 // assign the top-level id before those of the field.
472 at
.init(type0
, t
.Len())
475 case *reflect
.MapType
:
476 mt
:= newMapType(name
)
478 type0
, err
= getBaseType("", t
.Key())
482 type1
, err
= getBaseType("", t
.Elem())
486 mt
.init(type0
, type1
)
489 case *reflect
.SliceType
:
490 // []byte == []uint8 is a special case
491 if t
.Elem().Kind() == reflect
.Uint8
{
492 return tBytes
.gobType(), nil
494 st
:= newSliceType(name
)
496 type0
, err
= getBaseType(t
.Elem().Name(), t
.Elem())
503 case *reflect
.StructType
:
504 st
:= newStructType(name
)
506 idToType
[st
.id()] = st
507 for i
:= 0; i
< t
.NumField(); i
++ {
509 if !isExported(f
.Name
) {
512 typ
:= userType(f
.Type
).base
515 t
:= userType(f
.Type
).base
518 gt
, err
:= getBaseType(tname
, f
.Type
)
522 st
.Field
= append(st
.Field
, &fieldType
{f
.Name
, gt
.id()})
527 return nil, os
.ErrorString("gob NewTypeObject can't handle type: " + rt
.String())
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
)
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
, os
.Error
) {
542 return getType(name
, ut
, ut
.base
)
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
, os
.Error
) {
551 typ
, present
:= types
[rt
]
555 typ
, err
:= newTypeObject(name
, ut
, rt
)
562 func checkId(want
, got typeId
) {
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())
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
).(*reflect
.PtrType
).Elem()
573 _
, present
:= types
[rt
]
575 panic("bootstrap type already present: " + name
+ ", " + rt
.String())
577 typ
:= &CommonType
{Name
: name
}
580 checkId(expect
, nextId
)
581 userType(rt
) // might as well cache it now
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
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 {
601 GobEncoderT
*gobEncoderType
604 func (w
*wireType
) string() string {
605 const unknown
= "unknown type"
610 case w
.ArrayT
!= nil:
612 case w
.SliceT
!= nil:
614 case w
.StructT
!= nil:
615 return w
.StructT
.Name
618 case w
.GobEncoderT
!= nil:
619 return w
.GobEncoderT
.Name
624 type typeInfo
struct {
630 var typeInfoMap
= make(map[reflect
.Type
]*typeInfo
) // protected by typeLock
632 // typeLock must be held.
633 func getTypeInfo(ut
*userTypeInfo
) (*typeInfo
, os
.Error
) {
636 // We want the user type, not the base type.
639 info
, ok
:= typeInfoMap
[rt
]
644 gt
, err
:= getBaseType(rt
.Name(), rt
)
651 userType
, err
:= getType(rt
.Name(), ut
, rt
)
655 info
.wire
= &wireType
{GobEncoderT
: userType
.id().gobType().(*gobEncoderType
)}
656 typeInfoMap
[ut
.user
] = info
660 t
:= info
.id
.gobType()
661 switch typ
:= rt
.(type) {
662 case *reflect
.ArrayType
:
663 info
.wire
= &wireType
{ArrayT
: t
.(*arrayType
)}
664 case *reflect
.MapType
:
665 info
.wire
= &wireType
{MapT
: t
.(*mapType
)}
666 case *reflect
.SliceType
:
667 // []byte == []uint8 is a special case handled separately
668 if typ
.Elem().Kind() != reflect
.Uint8
{
669 info
.wire
= &wireType
{SliceT
: t
.(*sliceType
)}
671 case *reflect
.StructType
:
672 info
.wire
= &wireType
{StructT
: t
.(*structType
)}
674 typeInfoMap
[rt
] = info
678 // Called only when a panic is acceptable and unexpected.
679 func mustGetTypeInfo(rt reflect
.Type
) *typeInfo
{
680 t
, err
:= getTypeInfo(userType(rt
))
682 panic("getTypeInfo: " + err
.String())
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 transmissable in gob streams.
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
702 GobEncode() ([]byte, os
.Error
)
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) os
.Error
715 nameToConcreteType
= make(map[string]reflect
.Type
)
716 concreteTypeToName
= make(map[reflect
.Type
]string)
719 // RegisterName is like Register but uses the provided name rather than the
721 func RegisterName(name
string, value
interface{}) {
724 panic("attempt to register empty name")
726 base
:= userType(reflect
.Typeof(value
)).base
727 // Check for incompatible duplicates.
728 if t
, ok
:= nameToConcreteType
[name
]; ok
&& t
!= base
{
729 panic("gob: registering duplicate types for " + name
)
731 if n
, ok
:= concreteTypeToName
[base
]; ok
&& n
!= name
{
732 panic("gob: registering duplicate names for " + base
.String())
734 // Store the name and type provided by the user....
735 nameToConcreteType
[name
] = reflect
.Typeof(value
)
736 // but the flattened type in the type table, since that's what decode needs.
737 concreteTypeToName
[base
] = name
740 // Register records a type, identified by a value for that type, under its
741 // internal type name. That name will identify the concrete type of a value
742 // sent or received as an interface variable. Only types that will be
743 // transferred as implementations of interface values need to be registered.
744 // Expecting to be used only during initialization, it panics if the mapping
745 // between types and names is not a bijection.
746 func Register(value
interface{}) {
747 // Default to printed representation for unnamed types
748 rt
:= reflect
.Typeof(value
)
751 // But for named types (or pointers to them), qualify with import path.
752 // Dereference one pointer looking for a named type.
755 if pt
, ok
:= rt
.(*reflect
.PtrType
); ok
{
761 if rt
.PkgPath() == "" {
762 name
= star
+ rt
.Name()
764 name
= star
+ rt
.PkgPath() + "." + rt
.Name()
768 RegisterName(name
, value
)
771 func registerBasics() {
784 Register(complex64(0i
))
785 Register(complex128(0i
))
788 Register([]byte(nil))