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