Source file src/encoding/gob/type.go

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

View as plain text