Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package gob

import (
	
	
	
	
	
	
	
	
	
)
userTypeInfo stores the information associated with a type the user has handed to the package. It's computed once and stored in a map keyed by reflection type.
type userTypeInfo struct {
	user        reflect.Type // the type the user handed us
	base        reflect.Type // the base type after all indirections
	indir       int          // number of indirections to reach the base type
	externalEnc int          // xGob, xBinary, or xText
	externalDec int          // xGob, xBinary or xText
	encIndir    int8         // number of indirections to reach the receiver type; may be negative
	decIndir    int8         // number of indirections to reach the receiver type; may be negative
}
externalEncoding bits
const (
	xGob    = 1 + iota // GobEncoder or GobDecoder
	xBinary            // encoding.BinaryMarshaler or encoding.BinaryUnmarshaler
	xText              // encoding.TextMarshaler or encoding.TextUnmarshaler
)

var userTypeCache sync.Map // map[reflect.Type]*userTypeInfo
validType returns, and saves, the information associated with user-provided type rt. If the user type is not valid, err will be non-nil. To be used when the error handler is not set up.
func ( reflect.Type) (*userTypeInfo, error) {
	if ,  := userTypeCache.Load();  {
		return .(*userTypeInfo), nil
	}
Construct a new userTypeInfo and atomically add it to the userTypeCache. If we lose the race, we'll waste a little CPU and create a little garbage but return the existing value anyway.

	 := new(userTypeInfo)
	.base = 
A type that is just a cycle of pointers (such as type T *T) cannot be represented in gobs, which need some concrete data. We use a cycle detection algorithm from Knuth, Vol 2, Section 3.1, Ex 6, pp 539-540. As we step through indirections, run another type at half speed. If they meet up, there's a cycle.
	 := .base // walks half as fast as ut.base
	for {
		 := .base
		if .Kind() != reflect.Ptr {
			break
		}
		.base = .Elem()
recursive pointer type.
			return nil, errors.New("can't represent recursive pointer type " + .base.String())
		}
		if .indir%2 == 0 {
			 = .Elem()
		}
		.indir++
	}

	if ,  := implementsInterface(.user, gobEncoderInterfaceType);  {
		.externalEnc, .encIndir = xGob, 
	} else if ,  := implementsInterface(.user, binaryMarshalerInterfaceType);  {
		.externalEnc, .encIndir = xBinary, 
	}
NOTE(rsc): Would like to allow MarshalText here, but results in incompatibility with older encodings for net.IP. See golang.org/issue/6760. } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok { ut.externalEnc, ut.encIndir = xText, indir }

	if ,  := implementsInterface(.user, gobDecoderInterfaceType);  {
		.externalDec, .decIndir = xGob, 
	} else if ,  := implementsInterface(.user, binaryUnmarshalerInterfaceType);  {
		.externalDec, .decIndir = xBinary, 
	}
See note above. } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok { ut.externalDec, ut.decIndir = xText, indir }
implementsInterface reports whether the type implements the gobEncoder/gobDecoder interface. It also returns the number of indirections required to get to the implementation.
func (,  reflect.Type) ( bool,  int8) {
	if  == nil {
		return
	}
The type might be a pointer and we need to keep dereferencing to the base type until we find an implementation.
	for {
		if .Implements() {
			return true, 
		}
		if  := ; .Kind() == reflect.Ptr {
			++
			if  > 100 { // insane number of indirections
				return false, 0
			}
			 = .Elem()
			continue
		}
		break
No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
Not a pointer, but does the pointer work?
		if reflect.PtrTo().Implements() {
			return true, -1
		}
	}
	return false, 0
}
userType returns, and saves, the information associated with user-provided type rt. If the user type is not valid, it calls error.
func ( reflect.Type) *userTypeInfo {
	,  := validUserType()
	if  != nil {
		error_()
	}
	return 
}
A typeId represents a gob Type as an integer that can be passed on the wire. Internally, typeIds are used as keys to a map to recover the underlying type info.
type typeId int32

var nextId typeId       // incremented for each new type we build
var typeLock sync.Mutex // set while building a type
const firstUserId = 64  // lowest id number granted to user

type gobType interface {
	id() typeId
	setId(id typeId)
	name() string
	string() string // not public; only for debugging
	safeString(seen map[typeId]bool) string
}

var types = make(map[reflect.Type]gobType)
var idToType = make(map[typeId]gobType)
var builtinIdToType map[typeId]gobType // set in init() after builtins are established

When building recursive types, someone may get there before us.
	if .id() != 0 {
		return
	}
	nextId++
	.setId(nextId)
	idToType[nextId] = 
}

func ( typeId) () gobType {
	if  == 0 {
		return nil
	}
	return idToType[]
}
string returns the string representation of the type associated with the typeId.
func ( typeId) () string {
	if .gobType() == nil {
		return "<nil>"
	}
	return .gobType().string()
}
Name returns the name of the type associated with the typeId.
func ( typeId) () string {
	if .gobType() == nil {
		return "<nil>"
	}
	return .gobType().name()
}
CommonType holds elements of all types. It is a historical artifact, kept for binary compatibility and exported only for the benefit of the package's encoding of type descriptors. It is not intended for direct use by clients.
type CommonType struct {
	Name string
	Id   typeId
}

func ( *CommonType) () typeId { return .Id }

func ( *CommonType) ( typeId) { .Id =  }

func ( *CommonType) () string { return .Name }

func ( *CommonType) ( map[typeId]bool) string {
	return .Name
}

func ( *CommonType) () string { return .Name }
Create and check predefined types The string for tBytes is "bytes" not "[]byte" to signify its specialness.

Primordial types, needed during initialization. Always passed as pointers so the interface{} type goes through without losing its interfaceness.
	tBool      = bootstrapType("bool", (*bool)(nil), 1)
	tInt       = bootstrapType("int", (*int)(nil), 2)
	tUint      = bootstrapType("uint", (*uint)(nil), 3)
	tFloat     = bootstrapType("float", (*float64)(nil), 4)
	tBytes     = bootstrapType("bytes", (*[]byte)(nil), 5)
	tString    = bootstrapType("string", (*string)(nil), 6)
	tComplex   = bootstrapType("complex", (*complex128)(nil), 7)
Reserve some Ids for compatible expansion
	tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil), 9)
	tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil), 10)
	tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil), 11)
	tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil), 12)
	tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil), 13)
	tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil), 14)
	tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil), 15)
)
Predefined because it's needed by the Decoder
var tWireType = mustGetTypeInfo(reflect.TypeOf(wireType{})).id
var wireTypeUserInfo *userTypeInfo // userTypeInfo of (*wireType)

Move the id space upwards to allow for growth in the predefined world without breaking existing files.
Array type
type arrayType struct {
	CommonType
	Elem typeId
	Len  int
}

func ( string) *arrayType {
	 := &arrayType{CommonType{Name: }, 0, 0}
	return 
}

Set our type id before evaluating the element's, in case it's our own.
	setTypeId()
	.Elem = .id()
	.Len = 
}

func ( *arrayType) ( map[typeId]bool) string {
	if [.Id] {
		return .Name
	}
	[.Id] = true
	return fmt.Sprintf("[%d]%s", .Len, .Elem.gobType().safeString())
}

func ( *arrayType) () string { return .safeString(make(map[typeId]bool)) }
GobEncoder type (something that implements the GobEncoder interface)
type gobEncoderType struct {
	CommonType
}

func ( string) *gobEncoderType {
	 := &gobEncoderType{CommonType{Name: }}
	setTypeId()
	return 
}

func ( *gobEncoderType) ( map[typeId]bool) string {
	return .Name
}

func ( *gobEncoderType) () string { return .Name }
Map type
type mapType struct {
	CommonType
	Key  typeId
	Elem typeId
}

func ( string) *mapType {
	 := &mapType{CommonType{Name: }, 0, 0}
	return 
}

Set our type id before evaluating the element's, in case it's our own.
	setTypeId()
	.Key = .id()
	.Elem = .id()
}

func ( *mapType) ( map[typeId]bool) string {
	if [.Id] {
		return .Name
	}
	[.Id] = true
	 := .Key.gobType().safeString()
	 := .Elem.gobType().safeString()
	return fmt.Sprintf("map[%s]%s", , )
}

func ( *mapType) () string { return .safeString(make(map[typeId]bool)) }
Slice type
type sliceType struct {
	CommonType
	Elem typeId
}

func ( string) *sliceType {
	 := &sliceType{CommonType{Name: }, 0}
	return 
}

Set our type id before evaluating the element's, in case it's our own.
See the comments about ids in newTypeObject. Only slices and structs have mutual recursion.
	if .id() == 0 {
		setTypeId()
	}
	.Elem = .id()
}

func ( *sliceType) ( map[typeId]bool) string {
	if [.Id] {
		return .Name
	}
	[.Id] = true
	return fmt.Sprintf("[]%s", .Elem.gobType().safeString())
}

func ( *sliceType) () string { return .safeString(make(map[typeId]bool)) }
Struct type
type fieldType struct {
	Name string
	Id   typeId
}

type structType struct {
	CommonType
	Field []*fieldType
}

func ( *structType) ( map[typeId]bool) string {
	if  == nil {
		return "<nil>"
	}
	if ,  := [.Id];  {
		return .Name
	}
	[.Id] = true
	 := .Name + " = struct { "
	for ,  := range .Field {
		 += fmt.Sprintf("%s %s; ", .Name, .Id.gobType().safeString())
	}
	 += "}"
	return 
}

func ( *structType) () string { return .safeString(make(map[typeId]bool)) }

func ( string) *structType {
For historical reasons we set the id here rather than init. See the comment in newTypeObject for details.
	setTypeId()
	return 
}
newTypeObject allocates a gobType for the reflection type rt. Unless ut represents a GobEncoder, rt should be the base type of ut. This is only called from the encoding side. The decoding side works through typeIds and userTypeInfos alone.
Does this type implement GobEncoder?
	if .externalEnc != 0 {
		return newGobEncoderType(), nil
	}
	var  error
	var ,  gobType
	defer func() {
		if  != nil {
			delete(types, )
		}
Install the top-level type before the subtypes (e.g. struct before fields) so recursive types can be constructed safely.
All basic types are easy: they are predefined.
Historical aside: For arrays, maps, and slices, we set the type id after the elements are constructed. This is to retain the order of type id allocation after a fix made to handle recursive types, which changed the order in which types are built. Delaying the setting in this way preserves type ids while allowing recursive types to be described. Structs, done below, were already handling recursion correctly so they assign the top-level id before those of the field.
		.init(, .Len())
		return , nil

	case reflect.Map:
		 := newMapType()
		types[] = 
		,  = getBaseType("", .Key())
		if  != nil {
			return nil, 
		}
		,  = getBaseType("", .Elem())
		if  != nil {
			return nil, 
		}
		.init(, )
		return , nil

[]byte == []uint8 is a special case
		if .Elem().Kind() == reflect.Uint8 {
			return tBytes.gobType(), nil
		}
		 := newSliceType()
		types[] = 
		,  = getBaseType(.Elem().Name(), .Elem())
		if  != nil {
			return nil, 
		}
		.init()
		return , nil

	case reflect.Struct:
		 := newStructType()
		types[] = 
		idToType[.id()] = 
		for  := 0;  < .NumField(); ++ {
			 := .Field()
			if !isSent(&) {
				continue
			}
			 := userType(.Type).base
			 := .Name()
			if  == "" {
				 := userType(.Type).base
				 = .String()
			}
			,  := getBaseType(, .Type)
			if  != nil {
				return nil, 
Some mutually recursive types can cause us to be here while still defining the element. Fix the element type id here. We could do this more neatly by setting the id at the start of building every type, but that would break binary compatibility.
			if .id() == 0 {
				setTypeId()
			}
			.Field = append(.Field, &fieldType{.Name, .id()})
		}
		return , nil

	default:
		return nil, errors.New("gob NewTypeObject can't handle type: " + .String())
	}
}
isExported reports whether this is an exported - upper case - name.
func ( string) bool {
	,  := utf8.DecodeRuneInString()
	return unicode.IsUpper()
}
isSent reports whether this struct field is to be transmitted. It will be transmitted only if it is exported and not a chan or func field or pointer to chan or func.
func ( *reflect.StructField) bool {
	if !isExported(.Name) {
		return false
If the field is a chan or func or pointer thereto, don't send it. That is, treat it like an unexported field.
	 := .Type
	for .Kind() == reflect.Ptr {
		 = .Elem()
	}
	if .Kind() == reflect.Chan || .Kind() == reflect.Func {
		return false
	}
	return true
}
getBaseType returns the Gob type describing the given reflect.Type's base type. typeLock must be held.
func ( string,  reflect.Type) (gobType, error) {
	 := userType()
	return getType(, , .base)
}
getType returns the Gob type describing the given reflect.Type. Should be called only when handling GobEncoders/Decoders, which may be pointers. All other types are handled through the base type, never a pointer. typeLock must be held.
func ( string,  *userTypeInfo,  reflect.Type) (gobType, error) {
	,  := types[]
	if  {
		return , nil
	}
	,  := newTypeObject(, , )
	if  == nil {
		types[] = 
	}
	return , 
}

func (,  typeId) {
	if  !=  {
		fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(), int())
		panic("bootstrap type wrong id: " + .name() + " " + .string() + " not " + .string())
	}
}
used for building the basic types; called only from init(). the incoming interface always refers to a pointer.
func ( string,  interface{},  typeId) typeId {
	 := reflect.TypeOf().Elem()
	,  := types[]
	if  {
		panic("bootstrap type already present: " +  + ", " + .String())
	}
	 := &CommonType{Name: }
	types[] = 
	setTypeId()
	checkId(, nextId)
	userType() // might as well cache it now
	return nextId
}
Representation of the information we send and receive about this type. Each value we send is preceded by its type definition: an encoded int. However, the very first time we send the value, we first send the pair (-id, wireType). For bootstrapping purposes, we assume that the recipient knows how to decode a wireType; it is exactly the wireType struct here, interpreted using the gob rules for sending a structure, except that we assume the ids for wireType and structType etc. are known. The relevant pieces are built in encode.go's init() function. To maintain binary compatibility, if you extend this type, always put the new fields last.
type wireType struct {
	ArrayT           *arrayType
	SliceT           *sliceType
	StructT          *structType
	MapT             *mapType
	GobEncoderT      *gobEncoderType
	BinaryMarshalerT *gobEncoderType
	TextMarshalerT   *gobEncoderType
}

func ( *wireType) () string {
	const  = "unknown type"
	if  == nil {
		return 
	}
	switch {
	case .ArrayT != nil:
		return .ArrayT.Name
	case .SliceT != nil:
		return .SliceT.Name
	case .StructT != nil:
		return .StructT.Name
	case .MapT != nil:
		return .MapT.Name
	case .GobEncoderT != nil:
		return .GobEncoderT.Name
	case .BinaryMarshalerT != nil:
		return .BinaryMarshalerT.Name
	case .TextMarshalerT != nil:
		return .TextMarshalerT.Name
	}
	return 
}

type typeInfo struct {
	id      typeId
	encInit sync.Mutex   // protects creation of encoder
	encoder atomic.Value // *encEngine
	wire    *wireType
}
typeInfoMap is an atomic pointer to map[reflect.Type]*typeInfo. It's updated copy-on-write. Readers just do an atomic load to get the current version of the map. Writers make a full copy of the map and atomically update the pointer to point to the new map. Under heavy read contention, this is significantly faster than a map protected by a mutex.
var typeInfoMap atomic.Value

func ( reflect.Type) *typeInfo {
	,  := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
	return []
}

func ( *userTypeInfo) (*typeInfo, error) {
	 := .base
We want the user type, not the base type.
		 = .user
	}
	if  := lookupTypeInfo();  != nil {
		return , nil
	}
	return buildTypeInfo(, )
}
buildTypeInfo constructs the type information for the type and stores it in the type info map.
func ( *userTypeInfo,  reflect.Type) (*typeInfo, error) {
	typeLock.Lock()
	defer typeLock.Unlock()

	if  := lookupTypeInfo();  != nil {
		return , nil
	}

	,  := getBaseType(.Name(), )
	if  != nil {
		return nil, 
	}
	 := &typeInfo{id: .id()}

	if .externalEnc != 0 {
		,  := getType(.Name(), , )
		if  != nil {
			return nil, 
		}
		 := .id().gobType().(*gobEncoderType)
		switch .externalEnc {
		case xGob:
			.wire = &wireType{GobEncoderT: }
		case xBinary:
			.wire = &wireType{BinaryMarshalerT: }
		case xText:
			.wire = &wireType{TextMarshalerT: }
		}
		 = .user
	} else {
		 := .id.gobType()
		switch  := ; .Kind() {
		case reflect.Array:
			.wire = &wireType{ArrayT: .(*arrayType)}
		case reflect.Map:
			.wire = &wireType{MapT: .(*mapType)}
[]byte == []uint8 is a special case handled separately
			if .Elem().Kind() != reflect.Uint8 {
				.wire = &wireType{SliceT: .(*sliceType)}
			}
		case reflect.Struct:
			.wire = &wireType{StructT: .(*structType)}
		}
	}
Create new map with old contents plus new entry.
	 := make(map[reflect.Type]*typeInfo)
	,  := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
	for ,  := range  {
		[] = 
	}
	[] = 
	typeInfoMap.Store()
	return , nil
}
Called only when a panic is acceptable and unexpected.
func ( reflect.Type) *typeInfo {
	,  := getTypeInfo(userType())
	if  != nil {
		panic("getTypeInfo: " + .Error())
	}
	return 
}
GobEncoder is the interface describing data that provides its own representation for encoding values for transmission to a GobDecoder. A type that implements GobEncoder and GobDecoder has complete control over the representation of its data and may therefore contain things such as private fields, channels, and functions, which are not usually transmissible in gob streams. Note: Since gobs can be stored permanently, it is good design to guarantee the encoding used by a GobEncoder is stable as the software evolves. For instance, it might make sense for GobEncode to include a version number in the encoding.
GobEncode returns a byte slice representing the encoding of the receiver for transmission to a GobDecoder, usually of the same concrete type.
	GobEncode() ([]byte, error)
}
GobDecoder is the interface describing data that provides its own routine for decoding transmitted values sent by a GobEncoder.
GobDecode overwrites the receiver, which must be a pointer, with the value represented by the byte slice, which was written by GobEncode, usually for the same concrete type.
	GobDecode([]byte) error
}

var (
	nameToConcreteType sync.Map // map[string]reflect.Type
	concreteTypeToName sync.Map // map[reflect.Type]string
)
RegisterName is like Register but uses the provided name rather than the type's default.
func ( string,  interface{}) {
reserved for nil
		panic("attempt to register empty name")
	}

	 := userType(reflect.TypeOf())
Check for incompatible duplicates. The name must refer to the same user type, and vice versa.
Store the name and type provided by the user....
	if ,  := nameToConcreteType.LoadOrStore(, reflect.TypeOf());  &&  != .user {
		panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", , , .user))
	}
but the flattened type in the type table, since that's what decode needs.
	if ,  := concreteTypeToName.LoadOrStore(.base, );  &&  !=  {
		nameToConcreteType.Delete()
		panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", .user, , ))
	}
}
Register records a type, identified by a value for that type, under its internal type name. That name will identify the concrete type of a value sent or received as an interface variable. Only types that will be transferred as implementations of interface values need to be registered. Expecting to be used only during initialization, it panics if the mapping between types and names is not a bijection.
Default to printed representation for unnamed types
	 := reflect.TypeOf()
	 := .String()
But for named types (or pointers to them), qualify with import path (but see inner comment). Dereference one pointer looking for a named type.
	 := ""
	if .Name() == "" {
		if  := ; .Kind() == reflect.Ptr {
NOTE: The following line should be rt = pt.Elem() to implement what the comment above claims, but fixing it would break compatibility with existing gobs. Given package p imported as "full/p" with these definitions: package p type T1 struct { ... } this table shows the intended and actual strings used by gob to name the types: Type Correct string Actual string T1 full/p.T1 full/p.T1 *T1 *full/p.T1 *p.T1 The missing full path cannot be fixed without breaking existing gob decoders.