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

View as plain text