Source file src/encoding/gob/type.go

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

View as plain text