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(t, &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(struct_ reflect.Type, 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  
   593  	// Special case for Go 1.22: the x509.Certificate.Policies
   594  	// field is unencodable but also unused by default.
   595  	// Ignore it, so that x509.Certificate continues to be encodeable.
   596  	// Go 1.23 will add the right methods so that gob can
   597  	// handle the Policies field, and then we can remove this check.
   598  	// See go.dev/issue/65633.
   599  	if field.Name == "Policies" && struct_.PkgPath() == "crypto/x509" && struct_.Name() == "Certificate" {
   600  		return false
   601  	}
   602  
   603  	return true
   604  }
   605  
   606  // getBaseType returns the Gob type describing the given reflect.Type's base type.
   607  // typeLock must be held.
   608  func getBaseType(name string, rt reflect.Type) (gobType, error) {
   609  	ut := userType(rt)
   610  	return getType(name, ut, ut.base)
   611  }
   612  
   613  // getType returns the Gob type describing the given reflect.Type.
   614  // Should be called only when handling GobEncoders/Decoders,
   615  // which may be pointers. All other types are handled through the
   616  // base type, never a pointer.
   617  // typeLock must be held.
   618  func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
   619  	typ, present := types[rt]
   620  	if present {
   621  		return typ, nil
   622  	}
   623  	typ, err := newTypeObject(name, ut, rt)
   624  	if err == nil {
   625  		types[rt] = typ
   626  	}
   627  	return typ, err
   628  }
   629  
   630  func checkId(want, got typeId) {
   631  	if want != got {
   632  		fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
   633  		panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
   634  	}
   635  }
   636  
   637  // used for building the basic types; called only from init().  the incoming
   638  // interface always refers to a pointer.
   639  func bootstrapType(name string, e any) typeId {
   640  	rt := reflect.TypeOf(e).Elem()
   641  	_, present := types[rt]
   642  	if present {
   643  		panic("bootstrap type already present: " + name + ", " + rt.String())
   644  	}
   645  	typ := &CommonType{Name: name}
   646  	types[rt] = typ
   647  	setTypeId(typ)
   648  	return typ.id()
   649  }
   650  
   651  // Representation of the information we send and receive about this type.
   652  // Each value we send is preceded by its type definition: an encoded int.
   653  // However, the very first time we send the value, we first send the pair
   654  // (-id, wireType).
   655  // For bootstrapping purposes, we assume that the recipient knows how
   656  // to decode a wireType; it is exactly the wireType struct here, interpreted
   657  // using the gob rules for sending a structure, except that we assume the
   658  // ids for wireType and structType etc. are known. The relevant pieces
   659  // are built in encode.go's init() function.
   660  // To maintain binary compatibility, if you extend this type, always put
   661  // the new fields last.
   662  type wireType struct {
   663  	ArrayT           *arrayType
   664  	SliceT           *sliceType
   665  	StructT          *structType
   666  	MapT             *mapType
   667  	GobEncoderT      *gobEncoderType
   668  	BinaryMarshalerT *gobEncoderType
   669  	TextMarshalerT   *gobEncoderType
   670  }
   671  
   672  func (w *wireType) string() string {
   673  	const unknown = "unknown type"
   674  	if w == nil {
   675  		return unknown
   676  	}
   677  	switch {
   678  	case w.ArrayT != nil:
   679  		return w.ArrayT.Name
   680  	case w.SliceT != nil:
   681  		return w.SliceT.Name
   682  	case w.StructT != nil:
   683  		return w.StructT.Name
   684  	case w.MapT != nil:
   685  		return w.MapT.Name
   686  	case w.GobEncoderT != nil:
   687  		return w.GobEncoderT.Name
   688  	case w.BinaryMarshalerT != nil:
   689  		return w.BinaryMarshalerT.Name
   690  	case w.TextMarshalerT != nil:
   691  		return w.TextMarshalerT.Name
   692  	}
   693  	return unknown
   694  }
   695  
   696  type typeInfo struct {
   697  	id      typeId
   698  	encInit sync.Mutex // protects creation of encoder
   699  	encoder atomic.Pointer[encEngine]
   700  	wire    wireType
   701  }
   702  
   703  // typeInfoMap is an atomic pointer to map[reflect.Type]*typeInfo.
   704  // It's updated copy-on-write. Readers just do an atomic load
   705  // to get the current version of the map. Writers make a full copy of
   706  // the map and atomically update the pointer to point to the new map.
   707  // Under heavy read contention, this is significantly faster than a map
   708  // protected by a mutex.
   709  var typeInfoMap atomic.Value
   710  
   711  // typeInfoMapInit is used instead of typeInfoMap during init time,
   712  // as types are registered sequentially during init and we can save
   713  // the overhead of making map copies.
   714  // It is saved to typeInfoMap and set to nil before init finishes.
   715  var typeInfoMapInit = make(map[reflect.Type]*typeInfo, 16)
   716  
   717  func lookupTypeInfo(rt reflect.Type) *typeInfo {
   718  	if m := typeInfoMapInit; m != nil {
   719  		return m[rt]
   720  	}
   721  	m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
   722  	return m[rt]
   723  }
   724  
   725  func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
   726  	rt := ut.base
   727  	if ut.externalEnc != 0 {
   728  		// We want the user type, not the base type.
   729  		rt = ut.user
   730  	}
   731  	if info := lookupTypeInfo(rt); info != nil {
   732  		return info, nil
   733  	}
   734  	return buildTypeInfo(ut, rt)
   735  }
   736  
   737  // buildTypeInfo constructs the type information for the type
   738  // and stores it in the type info map.
   739  func buildTypeInfo(ut *userTypeInfo, rt reflect.Type) (*typeInfo, error) {
   740  	typeLock.Lock()
   741  	defer typeLock.Unlock()
   742  
   743  	if info := lookupTypeInfo(rt); info != nil {
   744  		return info, nil
   745  	}
   746  
   747  	gt, err := getBaseType(rt.Name(), rt)
   748  	if err != nil {
   749  		return nil, err
   750  	}
   751  	info := &typeInfo{id: gt.id()}
   752  
   753  	if ut.externalEnc != 0 {
   754  		userType, err := getType(rt.Name(), ut, rt)
   755  		if err != nil {
   756  			return nil, err
   757  		}
   758  		gt := userType.id().gobType().(*gobEncoderType)
   759  		switch ut.externalEnc {
   760  		case xGob:
   761  			info.wire.GobEncoderT = gt
   762  		case xBinary:
   763  			info.wire.BinaryMarshalerT = gt
   764  		case xText:
   765  			info.wire.TextMarshalerT = gt
   766  		}
   767  		rt = ut.user
   768  	} else {
   769  		t := info.id.gobType()
   770  		switch typ := rt; typ.Kind() {
   771  		case reflect.Array:
   772  			info.wire.ArrayT = t.(*arrayType)
   773  		case reflect.Map:
   774  			info.wire.MapT = t.(*mapType)
   775  		case reflect.Slice:
   776  			// []byte == []uint8 is a special case handled separately
   777  			if typ.Elem().Kind() != reflect.Uint8 {
   778  				info.wire.SliceT = t.(*sliceType)
   779  			}
   780  		case reflect.Struct:
   781  			info.wire.StructT = t.(*structType)
   782  		}
   783  	}
   784  
   785  	if m := typeInfoMapInit; m != nil {
   786  		m[rt] = info
   787  		return info, nil
   788  	}
   789  
   790  	// Create new map with old contents plus new entry.
   791  	m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
   792  	newm := make(map[reflect.Type]*typeInfo, len(m))
   793  	for k, v := range m {
   794  		newm[k] = v
   795  	}
   796  	newm[rt] = info
   797  	typeInfoMap.Store(newm)
   798  	return info, nil
   799  }
   800  
   801  // Called only when a panic is acceptable and unexpected.
   802  func mustGetTypeInfo(rt reflect.Type) *typeInfo {
   803  	t, err := getTypeInfo(userType(rt))
   804  	if err != nil {
   805  		panic("getTypeInfo: " + err.Error())
   806  	}
   807  	return t
   808  }
   809  
   810  // GobEncoder is the interface describing data that provides its own
   811  // representation for encoding values for transmission to a GobDecoder.
   812  // A type that implements GobEncoder and GobDecoder has complete
   813  // control over the representation of its data and may therefore
   814  // contain things such as private fields, channels, and functions,
   815  // which are not usually transmissible in gob streams.
   816  //
   817  // Note: Since gobs can be stored permanently, it is good design
   818  // to guarantee the encoding used by a GobEncoder is stable as the
   819  // software evolves. For instance, it might make sense for GobEncode
   820  // to include a version number in the encoding.
   821  type GobEncoder interface {
   822  	// GobEncode returns a byte slice representing the encoding of the
   823  	// receiver for transmission to a GobDecoder, usually of the same
   824  	// concrete type.
   825  	GobEncode() ([]byte, error)
   826  }
   827  
   828  // GobDecoder is the interface describing data that provides its own
   829  // routine for decoding transmitted values sent by a GobEncoder.
   830  type GobDecoder interface {
   831  	// GobDecode overwrites the receiver, which must be a pointer,
   832  	// with the value represented by the byte slice, which was written
   833  	// by GobEncode, usually for the same concrete type.
   834  	GobDecode([]byte) error
   835  }
   836  
   837  var (
   838  	nameToConcreteType sync.Map // map[string]reflect.Type
   839  	concreteTypeToName sync.Map // map[reflect.Type]string
   840  )
   841  
   842  // RegisterName is like [Register] but uses the provided name rather than the
   843  // type's default.
   844  func RegisterName(name string, value any) {
   845  	if name == "" {
   846  		// reserved for nil
   847  		panic("attempt to register empty name")
   848  	}
   849  
   850  	ut := userType(reflect.TypeOf(value))
   851  
   852  	// Check for incompatible duplicates. The name must refer to the
   853  	// same user type, and vice versa.
   854  
   855  	// Store the name and type provided by the user....
   856  	if t, dup := nameToConcreteType.LoadOrStore(name, reflect.TypeOf(value)); dup && t != ut.user {
   857  		panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
   858  	}
   859  
   860  	// but the flattened type in the type table, since that's what decode needs.
   861  	if n, dup := concreteTypeToName.LoadOrStore(ut.base, name); dup && n != name {
   862  		nameToConcreteType.Delete(name)
   863  		panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
   864  	}
   865  }
   866  
   867  // Register records a type, identified by a value for that type, under its
   868  // internal type name. That name will identify the concrete type of a value
   869  // sent or received as an interface variable. Only types that will be
   870  // transferred as implementations of interface values need to be registered.
   871  // Expecting to be used only during initialization, it panics if the mapping
   872  // between types and names is not a bijection.
   873  func Register(value any) {
   874  	// Default to printed representation for unnamed types
   875  	rt := reflect.TypeOf(value)
   876  	name := rt.String()
   877  
   878  	// But for named types (or pointers to them), qualify with import path (but see inner comment).
   879  	// Dereference one pointer looking for a named type.
   880  	star := ""
   881  	if rt.Name() == "" {
   882  		if pt := rt; pt.Kind() == reflect.Pointer {
   883  			star = "*"
   884  			// NOTE: The following line should be rt = pt.Elem() to implement
   885  			// what the comment above claims, but fixing it would break compatibility
   886  			// with existing gobs.
   887  			//
   888  			// Given package p imported as "full/p" with these definitions:
   889  			//     package p
   890  			//     type T1 struct { ... }
   891  			// this table shows the intended and actual strings used by gob to
   892  			// name the types:
   893  			//
   894  			// Type      Correct string     Actual string
   895  			//
   896  			// T1        full/p.T1          full/p.T1
   897  			// *T1       *full/p.T1         *p.T1
   898  			//
   899  			// The missing full path cannot be fixed without breaking existing gob decoders.
   900  			rt = pt
   901  		}
   902  	}
   903  	if rt.Name() != "" {
   904  		if rt.PkgPath() == "" {
   905  			name = star + rt.Name()
   906  		} else {
   907  			name = star + rt.PkgPath() + "." + rt.Name()
   908  		}
   909  	}
   910  
   911  	RegisterName(name, value)
   912  }
   913  
   914  func registerBasics() {
   915  	Register(int(0))
   916  	Register(int8(0))
   917  	Register(int16(0))
   918  	Register(int32(0))
   919  	Register(int64(0))
   920  	Register(uint(0))
   921  	Register(uint8(0))
   922  	Register(uint16(0))
   923  	Register(uint32(0))
   924  	Register(uint64(0))
   925  	Register(float32(0))
   926  	Register(float64(0))
   927  	Register(complex64(0i))
   928  	Register(complex128(0i))
   929  	Register(uintptr(0))
   930  	Register(false)
   931  	Register("")
   932  	Register([]byte(nil))
   933  	Register([]int(nil))
   934  	Register([]int8(nil))
   935  	Register([]int16(nil))
   936  	Register([]int32(nil))
   937  	Register([]int64(nil))
   938  	Register([]uint(nil))
   939  	Register([]uint8(nil))
   940  	Register([]uint16(nil))
   941  	Register([]uint32(nil))
   942  	Register([]uint64(nil))
   943  	Register([]float32(nil))
   944  	Register([]float64(nil))
   945  	Register([]complex64(nil))
   946  	Register([]complex128(nil))
   947  	Register([]uintptr(nil))
   948  	Register([]bool(nil))
   949  	Register([]string(nil))
   950  }
   951  
   952  func init() {
   953  	typeInfoMap.Store(typeInfoMapInit)
   954  	typeInfoMapInit = nil
   955  }
   956  

View as plain text