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

View as plain text