github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/fix/testdata/reflect.type.go.out (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 "fmt" 9 "os" 10 "reflect" 11 "sync" 12 "unicode" 13 "utf8" 14 ) 15 16 // userTypeInfo stores the information associated with a type the user has handed 17 // to the package. It's computed once and stored in a map keyed by reflection 18 // type. 19 type userTypeInfo struct { 20 user reflect.Type // the type the user handed us 21 base reflect.Type // the base type after all indirections 22 indir int // number of indirections to reach the base type 23 isGobEncoder bool // does the type implement GobEncoder? 24 isGobDecoder bool // does the type implement GobDecoder? 25 encIndir int8 // number of indirections to reach the receiver type; may be negative 26 decIndir int8 // number of indirections to reach the receiver type; may be negative 27 } 28 29 var ( 30 // Protected by an RWMutex because we read it a lot and write 31 // it only when we see a new type, typically when compiling. 32 userTypeLock sync.RWMutex 33 userTypeCache = make(map[reflect.Type]*userTypeInfo) 34 ) 35 36 // validType returns, and saves, the information associated with user-provided type rt. 37 // If the user type is not valid, err will be non-nil. To be used when the error handler 38 // is not set up. 39 func validUserType(rt reflect.Type) (ut *userTypeInfo, err os.Error) { 40 userTypeLock.RLock() 41 ut = userTypeCache[rt] 42 userTypeLock.RUnlock() 43 if ut != nil { 44 return 45 } 46 // Now set the value under the write lock. 47 userTypeLock.Lock() 48 defer userTypeLock.Unlock() 49 if ut = userTypeCache[rt]; ut != nil { 50 // Lost the race; not a problem. 51 return 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, os.NewError("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 ut.isGobEncoder, ut.encIndir = implementsInterface(ut.user, gobEncoderCheck) 78 ut.isGobDecoder, ut.decIndir = implementsInterface(ut.user, gobDecoderCheck) 79 userTypeCache[rt] = ut 80 return 81 } 82 83 const ( 84 gobEncodeMethodName = "GobEncode" 85 gobDecodeMethodName = "GobDecode" 86 ) 87 88 // implements returns whether the type implements the interface, as encoded 89 // in the check function. 90 func implements(typ reflect.Type, check func(typ reflect.Type) bool) bool { 91 if typ.NumMethod() == 0 { // avoid allocations etc. unless there's some chance 92 return false 93 } 94 return check(typ) 95 } 96 97 // gobEncoderCheck makes the type assertion a boolean function. 98 func gobEncoderCheck(typ reflect.Type) bool { 99 _, ok := reflect.Zero(typ).Interface().(GobEncoder) 100 return ok 101 } 102 103 // gobDecoderCheck makes the type assertion a boolean function. 104 func gobDecoderCheck(typ reflect.Type) bool { 105 _, ok := reflect.Zero(typ).Interface().(GobDecoder) 106 return ok 107 } 108 109 // implementsInterface reports whether the type implements the 110 // interface. (The actual check is done through the provided function.) 111 // It also returns the number of indirections required to get to the 112 // implementation. 113 func implementsInterface(typ reflect.Type, check func(typ reflect.Type) bool) (success bool, indir int8) { 114 if typ == nil { 115 return 116 } 117 rt := typ 118 // The type might be a pointer and we need to keep 119 // dereferencing to the base type until we find an implementation. 120 for { 121 if implements(rt, check) { 122 return true, indir 123 } 124 if p := rt; p.Kind() == reflect.Ptr { 125 indir++ 126 if indir > 100 { // insane number of indirections 127 return false, 0 128 } 129 rt = p.Elem() 130 continue 131 } 132 break 133 } 134 // No luck yet, but if this is a base type (non-pointer), the pointer might satisfy. 135 if typ.Kind() != reflect.Ptr { 136 // Not a pointer, but does the pointer work? 137 if implements(reflect.PtrTo(typ), check) { 138 return true, -1 139 } 140 } 141 return false, 0 142 } 143 144 // userType returns, and saves, the information associated with user-provided type rt. 145 // If the user type is not valid, it calls error. 146 func userType(rt reflect.Type) *userTypeInfo { 147 ut, err := validUserType(rt) 148 if err != nil { 149 error(err) 150 } 151 return ut 152 } 153 154 // A typeId represents a gob Type as an integer that can be passed on the wire. 155 // Internally, typeIds are used as keys to a map to recover the underlying type info. 156 type typeId int32 157 158 var nextId typeId // incremented for each new type we build 159 var typeLock sync.Mutex // set while building a type 160 const firstUserId = 64 // lowest id number granted to user 161 162 type gobType interface { 163 id() typeId 164 setId(id typeId) 165 name() string 166 string() string // not public; only for debugging 167 safeString(seen map[typeId]bool) string 168 } 169 170 var types = make(map[reflect.Type]gobType) 171 var idToType = make(map[typeId]gobType) 172 var builtinIdToType map[typeId]gobType // set in init() after builtins are established 173 174 func setTypeId(typ gobType) { 175 nextId++ 176 typ.setId(nextId) 177 idToType[nextId] = typ 178 } 179 180 func (t typeId) gobType() gobType { 181 if t == 0 { 182 return nil 183 } 184 return idToType[t] 185 } 186 187 // string returns the string representation of the type associated with the typeId. 188 func (t typeId) string() string { 189 if t.gobType() == nil { 190 return "<nil>" 191 } 192 return t.gobType().string() 193 } 194 195 // Name returns the name of the type associated with the typeId. 196 func (t typeId) name() string { 197 if t.gobType() == nil { 198 return "<nil>" 199 } 200 return t.gobType().name() 201 } 202 203 // Common elements of all types. 204 type CommonType struct { 205 Name string 206 Id typeId 207 } 208 209 func (t *CommonType) id() typeId { return t.Id } 210 211 func (t *CommonType) setId(id typeId) { t.Id = id } 212 213 func (t *CommonType) string() string { return t.Name } 214 215 func (t *CommonType) safeString(seen map[typeId]bool) string { 216 return t.Name 217 } 218 219 func (t *CommonType) name() string { return t.Name } 220 221 // Create and check predefined types 222 // The string for tBytes is "bytes" not "[]byte" to signify its specialness. 223 224 var ( 225 // Primordial types, needed during initialization. 226 // Always passed as pointers so the interface{} type 227 // goes through without losing its interfaceness. 228 tBool = bootstrapType("bool", (*bool)(nil), 1) 229 tInt = bootstrapType("int", (*int)(nil), 2) 230 tUint = bootstrapType("uint", (*uint)(nil), 3) 231 tFloat = bootstrapType("float", (*float64)(nil), 4) 232 tBytes = bootstrapType("bytes", (*[]byte)(nil), 5) 233 tString = bootstrapType("string", (*string)(nil), 6) 234 tComplex = bootstrapType("complex", (*complex128)(nil), 7) 235 tInterface = bootstrapType("interface", (*interface{})(nil), 8) 236 // Reserve some Ids for compatible expansion 237 tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil), 9) 238 tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil), 10) 239 tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil), 11) 240 tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil), 12) 241 tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil), 13) 242 tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil), 14) 243 tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil), 15) 244 ) 245 246 // Predefined because it's needed by the Decoder 247 var tWireType = mustGetTypeInfo(reflect.TypeOf(wireType{})).id 248 var wireTypeUserInfo *userTypeInfo // userTypeInfo of (*wireType) 249 250 func init() { 251 // Some magic numbers to make sure there are no surprises. 252 checkId(16, tWireType) 253 checkId(17, mustGetTypeInfo(reflect.TypeOf(arrayType{})).id) 254 checkId(18, mustGetTypeInfo(reflect.TypeOf(CommonType{})).id) 255 checkId(19, mustGetTypeInfo(reflect.TypeOf(sliceType{})).id) 256 checkId(20, mustGetTypeInfo(reflect.TypeOf(structType{})).id) 257 checkId(21, mustGetTypeInfo(reflect.TypeOf(fieldType{})).id) 258 checkId(23, mustGetTypeInfo(reflect.TypeOf(mapType{})).id) 259 260 builtinIdToType = make(map[typeId]gobType) 261 for k, v := range idToType { 262 builtinIdToType[k] = v 263 } 264 265 // Move the id space upwards to allow for growth in the predefined world 266 // without breaking existing files. 267 if nextId > firstUserId { 268 panic(fmt.Sprintln("nextId too large:", nextId)) 269 } 270 nextId = firstUserId 271 registerBasics() 272 wireTypeUserInfo = userType(reflect.TypeOf((*wireType)(nil))) 273 } 274 275 // Array type 276 type arrayType struct { 277 CommonType 278 Elem typeId 279 Len int 280 } 281 282 func newArrayType(name string) *arrayType { 283 a := &arrayType{CommonType{Name: name}, 0, 0} 284 return a 285 } 286 287 func (a *arrayType) init(elem gobType, len int) { 288 // Set our type id before evaluating the element's, in case it's our own. 289 setTypeId(a) 290 a.Elem = elem.id() 291 a.Len = len 292 } 293 294 func (a *arrayType) safeString(seen map[typeId]bool) string { 295 if seen[a.Id] { 296 return a.Name 297 } 298 seen[a.Id] = true 299 return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen)) 300 } 301 302 func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) } 303 304 // GobEncoder type (something that implements the GobEncoder interface) 305 type gobEncoderType struct { 306 CommonType 307 } 308 309 func newGobEncoderType(name string) *gobEncoderType { 310 g := &gobEncoderType{CommonType{Name: name}} 311 setTypeId(g) 312 return g 313 } 314 315 func (g *gobEncoderType) safeString(seen map[typeId]bool) string { 316 return g.Name 317 } 318 319 func (g *gobEncoderType) string() string { return g.Name } 320 321 // Map type 322 type mapType struct { 323 CommonType 324 Key typeId 325 Elem typeId 326 } 327 328 func newMapType(name string) *mapType { 329 m := &mapType{CommonType{Name: name}, 0, 0} 330 return m 331 } 332 333 func (m *mapType) init(key, elem gobType) { 334 // Set our type id before evaluating the element's, in case it's our own. 335 setTypeId(m) 336 m.Key = key.id() 337 m.Elem = elem.id() 338 } 339 340 func (m *mapType) safeString(seen map[typeId]bool) string { 341 if seen[m.Id] { 342 return m.Name 343 } 344 seen[m.Id] = true 345 key := m.Key.gobType().safeString(seen) 346 elem := m.Elem.gobType().safeString(seen) 347 return fmt.Sprintf("map[%s]%s", key, elem) 348 } 349 350 func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) } 351 352 // Slice type 353 type sliceType struct { 354 CommonType 355 Elem typeId 356 } 357 358 func newSliceType(name string) *sliceType { 359 s := &sliceType{CommonType{Name: name}, 0} 360 return s 361 } 362 363 func (s *sliceType) init(elem gobType) { 364 // Set our type id before evaluating the element's, in case it's our own. 365 setTypeId(s) 366 s.Elem = elem.id() 367 } 368 369 func (s *sliceType) safeString(seen map[typeId]bool) string { 370 if seen[s.Id] { 371 return s.Name 372 } 373 seen[s.Id] = true 374 return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen)) 375 } 376 377 func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) } 378 379 // Struct type 380 type fieldType struct { 381 Name string 382 Id typeId 383 } 384 385 type structType struct { 386 CommonType 387 Field []*fieldType 388 } 389 390 func (s *structType) safeString(seen map[typeId]bool) string { 391 if s == nil { 392 return "<nil>" 393 } 394 if _, ok := seen[s.Id]; ok { 395 return s.Name 396 } 397 seen[s.Id] = true 398 str := s.Name + " = struct { " 399 for _, f := range s.Field { 400 str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen)) 401 } 402 str += "}" 403 return str 404 } 405 406 func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) } 407 408 func newStructType(name string) *structType { 409 s := &structType{CommonType{Name: name}, nil} 410 // For historical reasons we set the id here rather than init. 411 // See the comment in newTypeObject for details. 412 setTypeId(s) 413 return s 414 } 415 416 // newTypeObject allocates a gobType for the reflection type rt. 417 // Unless ut represents a GobEncoder, rt should be the base type 418 // of ut. 419 // This is only called from the encoding side. The decoding side 420 // works through typeIds and userTypeInfos alone. 421 func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, os.Error) { 422 // Does this type implement GobEncoder? 423 if ut.isGobEncoder { 424 return newGobEncoderType(name), nil 425 } 426 var err os.Error 427 var type0, type1 gobType 428 defer func() { 429 if err != nil { 430 types[rt] = nil, false 431 } 432 }() 433 // Install the top-level type before the subtypes (e.g. struct before 434 // fields) so recursive types can be constructed safely. 435 switch t := rt; t.Kind() { 436 // All basic types are easy: they are predefined. 437 case reflect.Bool: 438 return tBool.gobType(), nil 439 440 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 441 return tInt.gobType(), nil 442 443 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 444 return tUint.gobType(), nil 445 446 case reflect.Float32, reflect.Float64: 447 return tFloat.gobType(), nil 448 449 case reflect.Complex64, reflect.Complex128: 450 return tComplex.gobType(), nil 451 452 case reflect.String: 453 return tString.gobType(), nil 454 455 case reflect.Interface: 456 return tInterface.gobType(), nil 457 458 case reflect.Array: 459 at := newArrayType(name) 460 types[rt] = at 461 type0, err = getBaseType("", t.Elem()) 462 if err != nil { 463 return nil, err 464 } 465 // Historical aside: 466 // For arrays, maps, and slices, we set the type id after the elements 467 // are constructed. This is to retain the order of type id allocation after 468 // a fix made to handle recursive types, which changed the order in 469 // which types are built. Delaying the setting in this way preserves 470 // type ids while allowing recursive types to be described. Structs, 471 // done below, were already handling recursion correctly so they 472 // assign the top-level id before those of the field. 473 at.init(type0, t.Len()) 474 return at, nil 475 476 case reflect.Map: 477 mt := newMapType(name) 478 types[rt] = mt 479 type0, err = getBaseType("", t.Key()) 480 if err != nil { 481 return nil, err 482 } 483 type1, err = getBaseType("", t.Elem()) 484 if err != nil { 485 return nil, err 486 } 487 mt.init(type0, type1) 488 return mt, nil 489 490 case reflect.Slice: 491 // []byte == []uint8 is a special case 492 if t.Elem().Kind() == reflect.Uint8 { 493 return tBytes.gobType(), nil 494 } 495 st := newSliceType(name) 496 types[rt] = st 497 type0, err = getBaseType(t.Elem().Name(), t.Elem()) 498 if err != nil { 499 return nil, err 500 } 501 st.init(type0) 502 return st, nil 503 504 case reflect.Struct: 505 st := newStructType(name) 506 types[rt] = st 507 idToType[st.id()] = st 508 for i := 0; i < t.NumField(); i++ { 509 f := t.Field(i) 510 if !isExported(f.Name) { 511 continue 512 } 513 typ := userType(f.Type).base 514 tname := typ.Name() 515 if tname == "" { 516 t := userType(f.Type).base 517 tname = t.String() 518 } 519 gt, err := getBaseType(tname, f.Type) 520 if err != nil { 521 return nil, err 522 } 523 st.Field = append(st.Field, &fieldType{f.Name, gt.id()}) 524 } 525 return st, nil 526 527 default: 528 return nil, os.NewError("gob NewTypeObject can't handle type: " + rt.String()) 529 } 530 return nil, nil 531 } 532 533 // isExported reports whether this is an exported - upper case - name. 534 func isExported(name string) bool { 535 rune, _ := utf8.DecodeRuneInString(name) 536 return unicode.IsUpper(rune) 537 } 538 539 // getBaseType returns the Gob type describing the given reflect.Type's base type. 540 // typeLock must be held. 541 func getBaseType(name string, rt reflect.Type) (gobType, os.Error) { 542 ut := userType(rt) 543 return getType(name, ut, ut.base) 544 } 545 546 // getType returns the Gob type describing the given reflect.Type. 547 // Should be called only when handling GobEncoders/Decoders, 548 // which may be pointers. All other types are handled through the 549 // base type, never a pointer. 550 // typeLock must be held. 551 func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, os.Error) { 552 typ, present := types[rt] 553 if present { 554 return typ, nil 555 } 556 typ, err := newTypeObject(name, ut, rt) 557 if err == nil { 558 types[rt] = typ 559 } 560 return typ, err 561 } 562 563 func checkId(want, got typeId) { 564 if want != got { 565 fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want)) 566 panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string()) 567 } 568 } 569 570 // used for building the basic types; called only from init(). the incoming 571 // interface always refers to a pointer. 572 func bootstrapType(name string, e interface{}, expect typeId) typeId { 573 rt := reflect.TypeOf(e).Elem() 574 _, present := types[rt] 575 if present { 576 panic("bootstrap type already present: " + name + ", " + rt.String()) 577 } 578 typ := &CommonType{Name: name} 579 types[rt] = typ 580 setTypeId(typ) 581 checkId(expect, nextId) 582 userType(rt) // might as well cache it now 583 return nextId 584 } 585 586 // Representation of the information we send and receive about this type. 587 // Each value we send is preceded by its type definition: an encoded int. 588 // However, the very first time we send the value, we first send the pair 589 // (-id, wireType). 590 // For bootstrapping purposes, we assume that the recipient knows how 591 // to decode a wireType; it is exactly the wireType struct here, interpreted 592 // using the gob rules for sending a structure, except that we assume the 593 // ids for wireType and structType etc. are known. The relevant pieces 594 // are built in encode.go's init() function. 595 // To maintain binary compatibility, if you extend this type, always put 596 // the new fields last. 597 type wireType struct { 598 ArrayT *arrayType 599 SliceT *sliceType 600 StructT *structType 601 MapT *mapType 602 GobEncoderT *gobEncoderType 603 } 604 605 func (w *wireType) string() string { 606 const unknown = "unknown type" 607 if w == nil { 608 return unknown 609 } 610 switch { 611 case w.ArrayT != nil: 612 return w.ArrayT.Name 613 case w.SliceT != nil: 614 return w.SliceT.Name 615 case w.StructT != nil: 616 return w.StructT.Name 617 case w.MapT != nil: 618 return w.MapT.Name 619 case w.GobEncoderT != nil: 620 return w.GobEncoderT.Name 621 } 622 return unknown 623 } 624 625 type typeInfo struct { 626 id typeId 627 encoder *encEngine 628 wire *wireType 629 } 630 631 var typeInfoMap = make(map[reflect.Type]*typeInfo) // protected by typeLock 632 633 // typeLock must be held. 634 func getTypeInfo(ut *userTypeInfo) (*typeInfo, os.Error) { 635 rt := ut.base 636 if ut.isGobEncoder { 637 // We want the user type, not the base type. 638 rt = ut.user 639 } 640 info, ok := typeInfoMap[rt] 641 if ok { 642 return info, nil 643 } 644 info = new(typeInfo) 645 gt, err := getBaseType(rt.Name(), rt) 646 if err != nil { 647 return nil, err 648 } 649 info.id = gt.id() 650 651 if ut.isGobEncoder { 652 userType, err := getType(rt.Name(), ut, rt) 653 if err != nil { 654 return nil, err 655 } 656 info.wire = &wireType{GobEncoderT: userType.id().gobType().(*gobEncoderType)} 657 typeInfoMap[ut.user] = info 658 return info, nil 659 } 660 661 t := info.id.gobType() 662 switch typ := rt; typ.Kind() { 663 case reflect.Array: 664 info.wire = &wireType{ArrayT: t.(*arrayType)} 665 case reflect.Map: 666 info.wire = &wireType{MapT: t.(*mapType)} 667 case reflect.Slice: 668 // []byte == []uint8 is a special case handled separately 669 if typ.Elem().Kind() != reflect.Uint8 { 670 info.wire = &wireType{SliceT: t.(*sliceType)} 671 } 672 case reflect.Struct: 673 info.wire = &wireType{StructT: t.(*structType)} 674 } 675 typeInfoMap[rt] = info 676 return info, nil 677 } 678 679 // Called only when a panic is acceptable and unexpected. 680 func mustGetTypeInfo(rt reflect.Type) *typeInfo { 681 t, err := getTypeInfo(userType(rt)) 682 if err != nil { 683 panic("getTypeInfo: " + err.String()) 684 } 685 return t 686 } 687 688 // GobEncoder is the interface describing data that provides its own 689 // representation for encoding values for transmission to a GobDecoder. 690 // A type that implements GobEncoder and GobDecoder has complete 691 // control over the representation of its data and may therefore 692 // contain things such as private fields, channels, and functions, 693 // which are not usually transmissable in gob streams. 694 // 695 // Note: Since gobs can be stored permanently, It is good design 696 // to guarantee the encoding used by a GobEncoder is stable as the 697 // software evolves. For instance, it might make sense for GobEncode 698 // to include a version number in the encoding. 699 type GobEncoder interface { 700 // GobEncode returns a byte slice representing the encoding of the 701 // receiver for transmission to a GobDecoder, usually of the same 702 // concrete type. 703 GobEncode() ([]byte, os.Error) 704 } 705 706 // GobDecoder is the interface describing data that provides its own 707 // routine for decoding transmitted values sent by a GobEncoder. 708 type GobDecoder interface { 709 // GobDecode overwrites the receiver, which must be a pointer, 710 // with the value represented by the byte slice, which was written 711 // by GobEncode, usually for the same concrete type. 712 GobDecode([]byte) os.Error 713 } 714 715 var ( 716 nameToConcreteType = make(map[string]reflect.Type) 717 concreteTypeToName = make(map[reflect.Type]string) 718 ) 719 720 // RegisterName is like Register but uses the provided name rather than the 721 // type's default. 722 func RegisterName(name string, value interface{}) { 723 if name == "" { 724 // reserved for nil 725 panic("attempt to register empty name") 726 } 727 base := userType(reflect.TypeOf(value)).base 728 // Check for incompatible duplicates. 729 if t, ok := nameToConcreteType[name]; ok && t != base { 730 panic("gob: registering duplicate types for " + name) 731 } 732 if n, ok := concreteTypeToName[base]; ok && n != name { 733 panic("gob: registering duplicate names for " + base.String()) 734 } 735 // Store the name and type provided by the user.... 736 nameToConcreteType[name] = reflect.TypeOf(value) 737 // but the flattened type in the type table, since that's what decode needs. 738 concreteTypeToName[base] = name 739 } 740 741 // Register records a type, identified by a value for that type, under its 742 // internal type name. That name will identify the concrete type of a value 743 // sent or received as an interface variable. Only types that will be 744 // transferred as implementations of interface values need to be registered. 745 // Expecting to be used only during initialization, it panics if the mapping 746 // between types and names is not a bijection. 747 func Register(value interface{}) { 748 // Default to printed representation for unnamed types 749 rt := reflect.TypeOf(value) 750 name := rt.String() 751 752 // But for named types (or pointers to them), qualify with import path. 753 // Dereference one pointer looking for a named type. 754 star := "" 755 if rt.Name() == "" { 756 if pt := rt; pt.Kind() == reflect.Ptr { 757 star = "*" 758 rt = pt 759 } 760 } 761 if rt.Name() != "" { 762 if rt.PkgPath() == "" { 763 name = star + rt.Name() 764 } else { 765 name = star + rt.PkgPath() + "." + rt.Name() 766 } 767 } 768 769 RegisterName(name, value) 770 } 771 772 func registerBasics() { 773 Register(int(0)) 774 Register(int8(0)) 775 Register(int16(0)) 776 Register(int32(0)) 777 Register(int64(0)) 778 Register(uint(0)) 779 Register(uint8(0)) 780 Register(uint16(0)) 781 Register(uint32(0)) 782 Register(uint64(0)) 783 Register(float32(0)) 784 Register(float64(0)) 785 Register(complex64(0i)) 786 Register(complex128(0i)) 787 Register(false) 788 Register("") 789 Register([]byte(nil)) 790 }