github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/encoding/gob/type.go (about)

     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  }
   530  
   531  // isExported reports whether this is an exported - upper case - name.
   532  func isExported(name string) bool {
   533  	rune, _ := utf8.DecodeRuneInString(name)
   534  	return unicode.IsUpper(rune)
   535  }
   536  
   537  // getBaseType returns the Gob type describing the given reflect.Type's base type.
   538  // typeLock must be held.
   539  func getBaseType(name string, rt reflect.Type) (gobType, error) {
   540  	ut := userType(rt)
   541  	return getType(name, ut, ut.base)
   542  }
   543  
   544  // getType returns the Gob type describing the given reflect.Type.
   545  // Should be called only when handling GobEncoders/Decoders,
   546  // which may be pointers.  All other types are handled through the
   547  // base type, never a pointer.
   548  // typeLock must be held.
   549  func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
   550  	typ, present := types[rt]
   551  	if present {
   552  		return typ, nil
   553  	}
   554  	typ, err := newTypeObject(name, ut, rt)
   555  	if err == nil {
   556  		types[rt] = typ
   557  	}
   558  	return typ, err
   559  }
   560  
   561  func checkId(want, got typeId) {
   562  	if want != got {
   563  		fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
   564  		panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
   565  	}
   566  }
   567  
   568  // used for building the basic types; called only from init().  the incoming
   569  // interface always refers to a pointer.
   570  func bootstrapType(name string, e interface{}, expect typeId) typeId {
   571  	rt := reflect.TypeOf(e).Elem()
   572  	_, present := types[rt]
   573  	if present {
   574  		panic("bootstrap type already present: " + name + ", " + rt.String())
   575  	}
   576  	typ := &CommonType{Name: name}
   577  	types[rt] = typ
   578  	setTypeId(typ)
   579  	checkId(expect, nextId)
   580  	userType(rt) // might as well cache it now
   581  	return nextId
   582  }
   583  
   584  // Representation of the information we send and receive about this type.
   585  // Each value we send is preceded by its type definition: an encoded int.
   586  // However, the very first time we send the value, we first send the pair
   587  // (-id, wireType).
   588  // For bootstrapping purposes, we assume that the recipient knows how
   589  // to decode a wireType; it is exactly the wireType struct here, interpreted
   590  // using the gob rules for sending a structure, except that we assume the
   591  // ids for wireType and structType etc. are known.  The relevant pieces
   592  // are built in encode.go's init() function.
   593  // To maintain binary compatibility, if you extend this type, always put
   594  // the new fields last.
   595  type wireType struct {
   596  	ArrayT      *arrayType
   597  	SliceT      *sliceType
   598  	StructT     *structType
   599  	MapT        *mapType
   600  	GobEncoderT *gobEncoderType
   601  }
   602  
   603  func (w *wireType) string() string {
   604  	const unknown = "unknown type"
   605  	if w == nil {
   606  		return unknown
   607  	}
   608  	switch {
   609  	case w.ArrayT != nil:
   610  		return w.ArrayT.Name
   611  	case w.SliceT != nil:
   612  		return w.SliceT.Name
   613  	case w.StructT != nil:
   614  		return w.StructT.Name
   615  	case w.MapT != nil:
   616  		return w.MapT.Name
   617  	case w.GobEncoderT != nil:
   618  		return w.GobEncoderT.Name
   619  	}
   620  	return unknown
   621  }
   622  
   623  type typeInfo struct {
   624  	id      typeId
   625  	encoder *encEngine
   626  	wire    *wireType
   627  }
   628  
   629  var typeInfoMap = make(map[reflect.Type]*typeInfo) // protected by typeLock
   630  
   631  // typeLock must be held.
   632  func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
   633  	rt := ut.base
   634  	if ut.isGobEncoder {
   635  		// We want the user type, not the base type.
   636  		rt = ut.user
   637  	}
   638  	info, ok := typeInfoMap[rt]
   639  	if ok {
   640  		return info, nil
   641  	}
   642  	info = new(typeInfo)
   643  	gt, err := getBaseType(rt.Name(), rt)
   644  	if err != nil {
   645  		return nil, err
   646  	}
   647  	info.id = gt.id()
   648  
   649  	if ut.isGobEncoder {
   650  		userType, err := getType(rt.Name(), ut, rt)
   651  		if err != nil {
   652  			return nil, err
   653  		}
   654  		info.wire = &wireType{GobEncoderT: userType.id().gobType().(*gobEncoderType)}
   655  		typeInfoMap[ut.user] = info
   656  		return info, nil
   657  	}
   658  
   659  	t := info.id.gobType()
   660  	switch typ := rt; typ.Kind() {
   661  	case reflect.Array:
   662  		info.wire = &wireType{ArrayT: t.(*arrayType)}
   663  	case reflect.Map:
   664  		info.wire = &wireType{MapT: t.(*mapType)}
   665  	case reflect.Slice:
   666  		// []byte == []uint8 is a special case handled separately
   667  		if typ.Elem().Kind() != reflect.Uint8 {
   668  			info.wire = &wireType{SliceT: t.(*sliceType)}
   669  		}
   670  	case reflect.Struct:
   671  		info.wire = &wireType{StructT: t.(*structType)}
   672  	}
   673  	typeInfoMap[rt] = info
   674  	return info, nil
   675  }
   676  
   677  // Called only when a panic is acceptable and unexpected.
   678  func mustGetTypeInfo(rt reflect.Type) *typeInfo {
   679  	t, err := getTypeInfo(userType(rt))
   680  	if err != nil {
   681  		panic("getTypeInfo: " + err.Error())
   682  	}
   683  	return t
   684  }
   685  
   686  // GobEncoder is the interface describing data that provides its own
   687  // representation for encoding values for transmission to a GobDecoder.
   688  // A type that implements GobEncoder and GobDecoder has complete
   689  // control over the representation of its data and may therefore
   690  // contain things such as private fields, channels, and functions,
   691  // which are not usually transmissible in gob streams.
   692  //
   693  // Note: Since gobs can be stored permanently, It is good design
   694  // to guarantee the encoding used by a GobEncoder is stable as the
   695  // software evolves.  For instance, it might make sense for GobEncode
   696  // to include a version number in the encoding.
   697  type GobEncoder interface {
   698  	// GobEncode returns a byte slice representing the encoding of the
   699  	// receiver for transmission to a GobDecoder, usually of the same
   700  	// concrete type.
   701  	GobEncode() ([]byte, error)
   702  }
   703  
   704  // GobDecoder is the interface describing data that provides its own
   705  // routine for decoding transmitted values sent by a GobEncoder.
   706  type GobDecoder interface {
   707  	// GobDecode overwrites the receiver, which must be a pointer,
   708  	// with the value represented by the byte slice, which was written
   709  	// by GobEncode, usually for the same concrete type.
   710  	GobDecode([]byte) error
   711  }
   712  
   713  var (
   714  	registerLock       sync.RWMutex
   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  	registerLock.Lock()
   727  	defer registerLock.Unlock()
   728  	ut := userType(reflect.TypeOf(value))
   729  	// Check for incompatible duplicates. The name must refer to the
   730  	// same user type, and vice versa.
   731  	if t, ok := nameToConcreteType[name]; ok && t != ut.user {
   732  		panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
   733  	}
   734  	if n, ok := concreteTypeToName[ut.base]; ok && n != name {
   735  		panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
   736  	}
   737  	// Store the name and type provided by the user....
   738  	nameToConcreteType[name] = reflect.TypeOf(value)
   739  	// but the flattened type in the type table, since that's what decode needs.
   740  	concreteTypeToName[ut.base] = name
   741  }
   742  
   743  // Register records a type, identified by a value for that type, under its
   744  // internal type name.  That name will identify the concrete type of a value
   745  // sent or received as an interface variable.  Only types that will be
   746  // transferred as implementations of interface values need to be registered.
   747  // Expecting to be used only during initialization, it panics if the mapping
   748  // between types and names is not a bijection.
   749  func Register(value interface{}) {
   750  	// Default to printed representation for unnamed types
   751  	rt := reflect.TypeOf(value)
   752  	name := rt.String()
   753  
   754  	// But for named types (or pointers to them), qualify with import path (but see inner comment).
   755  	// Dereference one pointer looking for a named type.
   756  	star := ""
   757  	if rt.Name() == "" {
   758  		if pt := rt; pt.Kind() == reflect.Ptr {
   759  			star = "*"
   760  			// NOTE: The following line should be rt = pt.Elem() to implement
   761  			// what the comment above claims, but fixing it would break compatibility
   762  			// with existing gobs.
   763  			//
   764  			// Given package p imported as "full/p" with these definitions:
   765  			//     package p
   766  			//     type T1 struct { ... }
   767  			// this table shows the intended and actual strings used by gob to
   768  			// name the types:
   769  			//
   770  			// Type      Correct string     Actual string
   771  			//
   772  			// T1        full/p.T1          full/p.T1
   773  			// *T1       *full/p.T1         *p.T1
   774  			//
   775  			// The missing full path cannot be fixed without breaking existing gob decoders.
   776  			rt = pt
   777  		}
   778  	}
   779  	if rt.Name() != "" {
   780  		if rt.PkgPath() == "" {
   781  			name = star + rt.Name()
   782  		} else {
   783  			name = star + rt.PkgPath() + "." + rt.Name()
   784  		}
   785  	}
   786  
   787  	RegisterName(name, value)
   788  }
   789  
   790  func registerBasics() {
   791  	Register(int(0))
   792  	Register(int8(0))
   793  	Register(int16(0))
   794  	Register(int32(0))
   795  	Register(int64(0))
   796  	Register(uint(0))
   797  	Register(uint8(0))
   798  	Register(uint16(0))
   799  	Register(uint32(0))
   800  	Register(uint64(0))
   801  	Register(float32(0))
   802  	Register(float64(0))
   803  	Register(complex64(0i))
   804  	Register(complex128(0i))
   805  	Register(uintptr(0))
   806  	Register(false)
   807  	Register("")
   808  	Register([]byte(nil))
   809  	Register([]int(nil))
   810  	Register([]int8(nil))
   811  	Register([]int16(nil))
   812  	Register([]int32(nil))
   813  	Register([]int64(nil))
   814  	Register([]uint(nil))
   815  	Register([]uint8(nil))
   816  	Register([]uint16(nil))
   817  	Register([]uint32(nil))
   818  	Register([]uint64(nil))
   819  	Register([]float32(nil))
   820  	Register([]float64(nil))
   821  	Register([]complex64(nil))
   822  	Register([]complex128(nil))
   823  	Register([]uintptr(nil))
   824  	Register([]bool(nil))
   825  	Register([]string(nil))
   826  }