github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/encoding/gob/type.go (about)

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