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