github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/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 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 }