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.
14 // Reflection types are themselves interface values holding structs
15 // describing the type. Each type has a different struct so that struct can
16 // be the kind. For example, if typ is the reflect type for an int8, typ is
17 // a pointer to a reflect.Int8Type struct; if typ is the reflect type for a
18 // function, typ is a pointer to a reflect.FuncType struct; we use the type
19 // of that pointer as the kind.
21 // A typeId represents a gob Type as an integer that can be passed on the wire.
22 // Internally, typeIds are used as keys to a map to recover the underlying type info.
25 var nextId typeId
// incremented for each new type we build
26 var typeLock sync
.Mutex
// set while building a type
27 const firstUserId
= 64 // lowest id number granted to user
29 type gobType
interface {
33 string() string // not public; only for debugging
34 safeString(seen
map[typeId
]bool) string
37 var types
= make(map[reflect
.Type
]gobType
)
38 var idToType
= make(map[typeId
]gobType
)
39 var builtinIdToType
map[typeId
]gobType
// set in init() after builtins are established
41 func setTypeId(typ gobType
) {
44 idToType
[nextId
] = typ
47 func (t typeId
) gobType() gobType
{
54 // string returns the string representation of the type associated with the typeId.
55 func (t typeId
) string() string {
56 if t
.gobType() == nil {
59 return t
.gobType().string()
62 // Name returns the name of the type associated with the typeId.
63 func (t typeId
) Name() string {
64 if t
.gobType() == nil {
67 return t
.gobType().Name()
70 // Common elements of all types.
71 type commonType
struct {
76 func (t
*commonType
) id() typeId
{ return t
._id
}
78 func (t
*commonType
) setId(id typeId
) { t
._id
= id
}
80 func (t
*commonType
) string() string { return t
.name
}
82 func (t
*commonType
) safeString(seen
map[typeId
]bool) string {
86 func (t
*commonType
) Name() string { return t
.name
}
88 // Create and check predefined types
89 // The string for tBytes is "bytes" not "[]byte" to signify its specialness.
92 // Primordial types, needed during initialization.
93 tBool
= bootstrapType("bool", false, 1)
94 tInt
= bootstrapType("int", int(0), 2)
95 tUint
= bootstrapType("uint", uint(0), 3)
96 tFloat
= bootstrapType("float", float64(0), 4)
97 tBytes
= bootstrapType("bytes", make([]byte, 0), 5)
98 tString
= bootstrapType("string", "", 6)
99 tComplex
= bootstrapType("complex", 0+0i
, 7)
100 tInterface
= bootstrapType("interface", interface{}(nil), 8)
101 // Reserve some Ids for compatible expansion
102 tReserved7
= bootstrapType("_reserved1", struct{ r7
int }{}, 9)
103 tReserved6
= bootstrapType("_reserved1", struct{ r6
int }{}, 10)
104 tReserved5
= bootstrapType("_reserved1", struct{ r5
int }{}, 11)
105 tReserved4
= bootstrapType("_reserved1", struct{ r4
int }{}, 12)
106 tReserved3
= bootstrapType("_reserved1", struct{ r3
int }{}, 13)
107 tReserved2
= bootstrapType("_reserved1", struct{ r2
int }{}, 14)
108 tReserved1
= bootstrapType("_reserved1", struct{ r1
int }{}, 15)
111 // Predefined because it's needed by the Decoder
112 var tWireType
= mustGetTypeInfo(reflect
.Typeof(wireType
{})).id
115 // Some magic numbers to make sure there are no surprises.
116 checkId(16, tWireType
)
117 checkId(17, mustGetTypeInfo(reflect
.Typeof(arrayType
{})).id
)
118 checkId(18, mustGetTypeInfo(reflect
.Typeof(commonType
{})).id
)
119 checkId(19, mustGetTypeInfo(reflect
.Typeof(sliceType
{})).id
)
120 checkId(20, mustGetTypeInfo(reflect
.Typeof(structType
{})).id
)
121 checkId(21, mustGetTypeInfo(reflect
.Typeof(fieldType
{})).id
)
122 checkId(23, mustGetTypeInfo(reflect
.Typeof(mapType
{})).id
)
124 builtinIdToType
= make(map[typeId
]gobType
)
125 for k
, v
:= range idToType
{
126 builtinIdToType
[k
] = v
129 // Move the id space upwards to allow for growth in the predefined world
130 // without breaking existing files.
131 if nextId
> firstUserId
{
132 panic(fmt
.Sprintln("nextId too large:", nextId
))
139 type arrayType
struct {
145 func newArrayType(name
string, elem gobType
, length
int) *arrayType
{
146 a
:= &arrayType
{commonType
{name
: name
}, elem
.id(), length
}
151 func (a
*arrayType
) safeString(seen
map[typeId
]bool) string {
156 return fmt
.Sprintf("[%d]%s", a
.Len
, a
.Elem
.gobType().safeString(seen
))
159 func (a
*arrayType
) string() string { return a
.safeString(make(map[typeId
]bool)) }
162 type mapType
struct {
168 func newMapType(name
string, key
, elem gobType
) *mapType
{
169 m
:= &mapType
{commonType
{name
: name
}, key
.id(), elem
.id()}
174 func (m
*mapType
) safeString(seen
map[typeId
]bool) string {
179 key
:= m
.Key
.gobType().safeString(seen
)
180 elem
:= m
.Elem
.gobType().safeString(seen
)
181 return fmt
.Sprintf("map[%s]%s", key
, elem
)
184 func (m
*mapType
) string() string { return m
.safeString(make(map[typeId
]bool)) }
187 type sliceType
struct {
192 func newSliceType(name
string, elem gobType
) *sliceType
{
193 s
:= &sliceType
{commonType
{name
: name
}, elem
.id()}
198 func (s
*sliceType
) safeString(seen
map[typeId
]bool) string {
203 return fmt
.Sprintf("[]%s", s
.Elem
.gobType().safeString(seen
))
206 func (s
*sliceType
) string() string { return s
.safeString(make(map[typeId
]bool)) }
209 type fieldType
struct {
214 type structType
struct {
219 func (s
*structType
) safeString(seen
map[typeId
]bool) string {
223 if _
, ok
:= seen
[s
._id
]; ok
{
227 str
:= s
.name
+ " = struct { "
228 for _
, f
:= range s
.field
{
229 str
+= fmt
.Sprintf("%s %s; ", f
.name
, f
.id
.gobType().safeString(seen
))
235 func (s
*structType
) string() string { return s
.safeString(make(map[typeId
]bool)) }
237 func newStructType(name
string) *structType
{
238 s
:= &structType
{commonType
{name
: name
}, nil}
243 // Step through the indirections on a type to discover the base type.
244 // Return the base type and the number of indirections.
245 func indirect(t reflect
.Type
) (rt reflect
.Type
, count
int) {
248 pt
, ok
:= rt
.(*reflect
.PtrType
)
258 func newTypeObject(name
string, rt reflect
.Type
) (gobType
, os
.Error
) {
259 switch t
:= rt
.(type) {
260 // All basic types are easy: they are predefined.
261 case *reflect
.BoolType
:
262 return tBool
.gobType(), nil
264 case *reflect
.IntType
:
265 return tInt
.gobType(), nil
267 case *reflect
.UintType
:
268 return tUint
.gobType(), nil
270 case *reflect
.FloatType
:
271 return tFloat
.gobType(), nil
273 case *reflect
.ComplexType
:
274 return tComplex
.gobType(), nil
276 case *reflect
.StringType
:
277 return tString
.gobType(), nil
279 case *reflect
.InterfaceType
:
280 return tInterface
.gobType(), nil
282 case *reflect
.ArrayType
:
283 gt
, err
:= getType("", t
.Elem())
287 return newArrayType(name
, gt
, t
.Len()), nil
289 case *reflect
.MapType
:
290 kt
, err
:= getType("", t
.Key())
294 vt
, err
:= getType("", t
.Elem())
298 return newMapType(name
, kt
, vt
), nil
300 case *reflect
.SliceType
:
301 // []byte == []uint8 is a special case
302 if t
.Elem().Kind() == reflect
.Uint8
{
303 return tBytes
.gobType(), nil
305 gt
, err
:= getType(t
.Elem().Name(), t
.Elem())
309 return newSliceType(name
, gt
), nil
311 case *reflect
.StructType
:
312 // Install the struct type itself before the fields so recursive
313 // structures can be constructed safely.
314 strType
:= newStructType(name
)
316 idToType
[strType
.id()] = strType
317 field
:= make([]*fieldType
, t
.NumField())
318 for i
:= 0; i
< t
.NumField(); i
++ {
320 typ
, _
:= indirect(f
.Type
)
323 t
, _
:= indirect(f
.Type
)
326 gt
, err
:= getType(tname
, f
.Type
)
330 field
[i
] = &fieldType
{f
.Name
, gt
.id()}
332 strType
.field
= field
336 return nil, os
.ErrorString("gob NewTypeObject can't handle type: " + rt
.String())
341 // getType returns the Gob type describing the given reflect.Type.
342 // typeLock must be held.
343 func getType(name
string, rt reflect
.Type
) (gobType
, os
.Error
) {
345 typ
, present
:= types
[rt
]
349 typ
, err
:= newTypeObject(name
, rt
)
356 func checkId(want
, got typeId
) {
358 fmt
.Fprintf(os
.Stderr
, "checkId: %d should be %d\n", int(want
), int(got
))
359 panic("bootstrap type wrong id: " + got
.Name() + " " + got
.string() + " not " + want
.string())
363 // used for building the basic types; called only from init()
364 func bootstrapType(name
string, e
interface{}, expect typeId
) typeId
{
365 rt
:= reflect
.Typeof(e
)
366 _
, present
:= types
[rt
]
368 panic("bootstrap type already present: " + name
+ ", " + rt
.String())
370 typ
:= &commonType
{name
: name
}
373 checkId(expect
, nextId
)
377 // Representation of the information we send and receive about this type.
378 // Each value we send is preceded by its type definition: an encoded int.
379 // However, the very first time we send the value, we first send the pair
381 // For bootstrapping purposes, we assume that the recipient knows how
382 // to decode a wireType; it is exactly the wireType struct here, interpreted
383 // using the gob rules for sending a structure, except that we assume the
384 // ids for wireType and structType are known. The relevant pieces
385 // are built in encode.go's init() function.
386 // To maintain binary compatibility, if you extend this type, always put
387 // the new fields last.
388 type wireType
struct {
395 func (w
*wireType
) name() string {
396 if w
.structT
!= nil {
397 return w
.structT
.name
402 type typeInfo
struct {
408 var typeInfoMap
= make(map[reflect
.Type
]*typeInfo
) // protected by typeLock
410 // The reflection type must have all its indirections processed out.
411 // typeLock must be held.
412 func getTypeInfo(rt reflect
.Type
) (*typeInfo
, os
.Error
) {
413 if rt
.Kind() == reflect
.Ptr
{
414 panic("pointer type in getTypeInfo: " + rt
.String())
416 info
, ok
:= typeInfoMap
[rt
]
420 gt
, err
:= getType(name
, rt
)
425 t
:= info
.id
.gobType()
426 switch typ
:= rt
.(type) {
427 case *reflect
.ArrayType
:
428 info
.wire
= &wireType
{arrayT
: t
.(*arrayType
)}
429 case *reflect
.MapType
:
430 info
.wire
= &wireType
{mapT
: t
.(*mapType
)}
431 case *reflect
.SliceType
:
432 // []byte == []uint8 is a special case handled separately
433 if typ
.Elem().Kind() != reflect
.Uint8
{
434 info
.wire
= &wireType
{sliceT
: t
.(*sliceType
)}
436 case *reflect
.StructType
:
437 info
.wire
= &wireType
{structT
: t
.(*structType
)}
439 typeInfoMap
[rt
] = info
444 // Called only when a panic is acceptable and unexpected.
445 func mustGetTypeInfo(rt reflect
.Type
) *typeInfo
{
446 t
, err
:= getTypeInfo(rt
)
448 panic("getTypeInfo: " + err
.String())
454 nameToConcreteType
= make(map[string]reflect
.Type
)
455 concreteTypeToName
= make(map[reflect
.Type
]string)
458 // RegisterName is like Register but uses the provided name rather than the
460 func RegisterName(name
string, value
interface{}) {
463 panic("attempt to register empty name")
465 rt
, _
:= indirect(reflect
.Typeof(value
))
466 // Check for incompatible duplicates.
467 if t
, ok
:= nameToConcreteType
[name
]; ok
&& t
!= rt
{
468 panic("gob: registering duplicate types for " + name
)
470 if n
, ok
:= concreteTypeToName
[rt
]; ok
&& n
!= name
{
471 panic("gob: registering duplicate names for " + rt
.String())
473 nameToConcreteType
[name
] = rt
474 concreteTypeToName
[rt
] = name
477 // Register records a type, identified by a value for that type, under its
478 // internal type name. That name will identify the concrete type of a value
479 // sent or received as an interface variable. Only types that will be
480 // transferred as implementations of interface values need to be registered.
481 // Expecting to be used only during initialization, it panics if the mapping
482 // between types and names is not a bijection.
483 func Register(value
interface{}) {
484 // Default to printed representation for unnamed types
485 rt
:= reflect
.Typeof(value
)
488 // But for named types (or pointers to them), qualify with import path.
489 // Dereference one pointer looking for a named type.
492 if pt
, ok
:= rt
.(*reflect
.PtrType
); ok
{
498 if rt
.PkgPath() == "" {
499 name
= star
+ rt
.Name()
501 name
= star
+ rt
.PkgPath() + "." + rt
.Name()
505 RegisterName(name
, value
)
508 func registerBasics() {
522 Register(complex(0i
))
523 Register(complex64(0i
))
524 Register(complex128(0i
))
527 Register([]byte(nil))