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