github.com/huandu/go@v0.0.0-20151114150818-04e615e41150/src/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  	"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  }