...

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

View as plain text