1
2
3
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
20
21
22 type userTypeInfo struct {
23 user reflect.Type
24 base reflect.Type
25 indir int
26 externalEnc int
27 externalDec int
28 encIndir int8
29 decIndir int8
30 }
31
32
33 const (
34 xGob = 1 + iota
35 xBinary
36 xText
37 )
38
39 var userTypeCache sync.Map
40
41
42
43
44 func validUserType(rt reflect.Type) (*userTypeInfo, error) {
45 if ui, ok := userTypeCache.Load(rt); ok {
46 return ui.(*userTypeInfo), nil
47 }
48
49
50
51
52
53 ut := new(userTypeInfo)
54 ut.base = rt
55 ut.user = rt
56
57
58
59
60
61 slowpoke := ut.base
62 for {
63 pt := ut.base
64 if pt.Kind() != reflect.Pointer {
65 break
66 }
67 ut.base = pt.Elem()
68 if ut.base == slowpoke {
69
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
85
86
87
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
97
98
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 wireTypeType = reflect.TypeOf((*wireType)(nil)).Elem()
114 )
115
116
117
118
119
120 func implementsInterface(typ, gobEncDecType reflect.Type) (success bool, indir int8) {
121 if typ == nil {
122 return
123 }
124 rt := typ
125
126
127 for {
128 if rt.Implements(gobEncDecType) {
129 return true, indir
130 }
131 if p := rt; p.Kind() == reflect.Pointer {
132 indir++
133 if indir > 100 {
134 return false, 0
135 }
136 rt = p.Elem()
137 continue
138 }
139 break
140 }
141
142 if typ.Kind() != reflect.Pointer {
143
144 if reflect.PointerTo(typ).Implements(gobEncDecType) {
145 return true, -1
146 }
147 }
148 return false, 0
149 }
150
151
152
153 func userType(rt reflect.Type) *userTypeInfo {
154 ut, err := validUserType(rt)
155 if err != nil {
156 error_(err)
157 }
158 return ut
159 }
160
161
162
163 type typeId int32
164
165 var typeLock sync.Mutex
166 const firstUserId = 64
167
168 type gobType interface {
169 id() typeId
170 setId(id typeId)
171 name() string
172 string() string
173 safeString(seen map[typeId]bool) string
174 }
175
176 var (
177 types = make(map[reflect.Type]gobType, 32)
178 idToTypeSlice = make([]gobType, 1, firstUserId)
179 builtinIdToTypeSlice [firstUserId]gobType
180 )
181
182 func idToType(id typeId) gobType {
183 if id < 0 || int(id) >= len(idToTypeSlice) {
184 return nil
185 }
186 return idToTypeSlice[id]
187 }
188
189 func builtinIdToType(id typeId) gobType {
190 if id < 0 || int(id) >= len(builtinIdToTypeSlice) {
191 return nil
192 }
193 return builtinIdToTypeSlice[id]
194 }
195
196 func setTypeId(typ gobType) {
197
198 if typ.id() != 0 {
199 return
200 }
201 nextId := typeId(len(idToTypeSlice))
202 typ.setId(nextId)
203 idToTypeSlice = append(idToTypeSlice, typ)
204 }
205
206 func (t typeId) gobType() gobType {
207 if t == 0 {
208 return nil
209 }
210 return idToType(t)
211 }
212
213
214 func (t typeId) string() string {
215 if t.gobType() == nil {
216 return "<nil>"
217 }
218 return t.gobType().string()
219 }
220
221
222 func (t typeId) name() string {
223 if t.gobType() == nil {
224 return "<nil>"
225 }
226 return t.gobType().name()
227 }
228
229
230
231
232
233 type CommonType struct {
234 Name string
235 Id typeId
236 }
237
238 func (t *CommonType) id() typeId { return t.Id }
239
240 func (t *CommonType) setId(id typeId) { t.Id = id }
241
242 func (t *CommonType) string() string { return t.Name }
243
244 func (t *CommonType) safeString(seen map[typeId]bool) string {
245 return t.Name
246 }
247
248 func (t *CommonType) name() string { return t.Name }
249
250
251
252
253 var (
254
255
256
257 tBool = bootstrapType("bool", (*bool)(nil))
258 tInt = bootstrapType("int", (*int)(nil))
259 tUint = bootstrapType("uint", (*uint)(nil))
260 tFloat = bootstrapType("float", (*float64)(nil))
261 tBytes = bootstrapType("bytes", (*[]byte)(nil))
262 tString = bootstrapType("string", (*string)(nil))
263 tComplex = bootstrapType("complex", (*complex128)(nil))
264 tInterface = bootstrapType("interface", (*any)(nil))
265
266 tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil))
267 tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil))
268 tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil))
269 tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil))
270 tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil))
271 tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil))
272 tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil))
273 )
274
275
276 var tWireType = mustGetTypeInfo(wireTypeType).id
277 var wireTypeUserInfo *userTypeInfo
278
279 func init() {
280
281 checkId(16, tWireType)
282 checkId(17, mustGetTypeInfo(reflect.TypeOf((*arrayType)(nil)).Elem()).id)
283 checkId(18, mustGetTypeInfo(reflect.TypeOf((*CommonType)(nil)).Elem()).id)
284 checkId(19, mustGetTypeInfo(reflect.TypeOf((*sliceType)(nil)).Elem()).id)
285 checkId(20, mustGetTypeInfo(reflect.TypeOf((*structType)(nil)).Elem()).id)
286 checkId(21, mustGetTypeInfo(reflect.TypeOf((*fieldType)(nil)).Elem()).id)
287 checkId(23, mustGetTypeInfo(reflect.TypeOf((*mapType)(nil)).Elem()).id)
288
289 copy(builtinIdToTypeSlice[:], idToTypeSlice)
290
291
292
293 if nextId := len(idToTypeSlice); nextId > firstUserId {
294 panic(fmt.Sprintln("nextId too large:", nextId))
295 }
296 idToTypeSlice = idToTypeSlice[:firstUserId]
297 registerBasics()
298 wireTypeUserInfo = userType(wireTypeType)
299 }
300
301
302 type arrayType struct {
303 CommonType
304 Elem typeId
305 Len int
306 }
307
308 func newArrayType(name string) *arrayType {
309 a := &arrayType{CommonType{Name: name}, 0, 0}
310 return a
311 }
312
313 func (a *arrayType) init(elem gobType, len int) {
314
315 setTypeId(a)
316 a.Elem = elem.id()
317 a.Len = len
318 }
319
320 func (a *arrayType) safeString(seen map[typeId]bool) string {
321 if seen[a.Id] {
322 return a.Name
323 }
324 seen[a.Id] = true
325 return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen))
326 }
327
328 func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) }
329
330
331 type gobEncoderType struct {
332 CommonType
333 }
334
335 func newGobEncoderType(name string) *gobEncoderType {
336 g := &gobEncoderType{CommonType{Name: name}}
337 setTypeId(g)
338 return g
339 }
340
341 func (g *gobEncoderType) safeString(seen map[typeId]bool) string {
342 return g.Name
343 }
344
345 func (g *gobEncoderType) string() string { return g.Name }
346
347
348 type mapType struct {
349 CommonType
350 Key typeId
351 Elem typeId
352 }
353
354 func newMapType(name string) *mapType {
355 m := &mapType{CommonType{Name: name}, 0, 0}
356 return m
357 }
358
359 func (m *mapType) init(key, elem gobType) {
360
361 setTypeId(m)
362 m.Key = key.id()
363 m.Elem = elem.id()
364 }
365
366 func (m *mapType) safeString(seen map[typeId]bool) string {
367 if seen[m.Id] {
368 return m.Name
369 }
370 seen[m.Id] = true
371 key := m.Key.gobType().safeString(seen)
372 elem := m.Elem.gobType().safeString(seen)
373 return fmt.Sprintf("map[%s]%s", key, elem)
374 }
375
376 func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) }
377
378
379 type sliceType struct {
380 CommonType
381 Elem typeId
382 }
383
384 func newSliceType(name string) *sliceType {
385 s := &sliceType{CommonType{Name: name}, 0}
386 return s
387 }
388
389 func (s *sliceType) init(elem gobType) {
390
391 setTypeId(s)
392
393
394 if elem.id() == 0 {
395 setTypeId(elem)
396 }
397 s.Elem = elem.id()
398 }
399
400 func (s *sliceType) safeString(seen map[typeId]bool) string {
401 if seen[s.Id] {
402 return s.Name
403 }
404 seen[s.Id] = true
405 return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen))
406 }
407
408 func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) }
409
410
411 type fieldType struct {
412 Name string
413 Id typeId
414 }
415
416 type structType struct {
417 CommonType
418 Field []fieldType
419 }
420
421 func (s *structType) safeString(seen map[typeId]bool) string {
422 if s == nil {
423 return "<nil>"
424 }
425 if _, ok := seen[s.Id]; ok {
426 return s.Name
427 }
428 seen[s.Id] = true
429 str := s.Name + " = struct { "
430 for _, f := range s.Field {
431 str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen))
432 }
433 str += "}"
434 return str
435 }
436
437 func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) }
438
439 func newStructType(name string) *structType {
440 s := &structType{CommonType{Name: name}, nil}
441
442
443 setTypeId(s)
444 return s
445 }
446
447
448
449
450
451
452 func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
453
454 if ut.externalEnc != 0 {
455 return newGobEncoderType(name), nil
456 }
457 var err error
458 var type0, type1 gobType
459 defer func() {
460 if err != nil {
461 delete(types, rt)
462 }
463 }()
464
465
466 switch t := rt; t.Kind() {
467
468 case reflect.Bool:
469 return tBool.gobType(), nil
470
471 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
472 return tInt.gobType(), nil
473
474 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
475 return tUint.gobType(), nil
476
477 case reflect.Float32, reflect.Float64:
478 return tFloat.gobType(), nil
479
480 case reflect.Complex64, reflect.Complex128:
481 return tComplex.gobType(), nil
482
483 case reflect.String:
484 return tString.gobType(), nil
485
486 case reflect.Interface:
487 return tInterface.gobType(), nil
488
489 case reflect.Array:
490 at := newArrayType(name)
491 types[rt] = at
492 type0, err = getBaseType("", t.Elem())
493 if err != nil {
494 return nil, err
495 }
496
497
498
499
500
501
502
503
504 at.init(type0, t.Len())
505 return at, nil
506
507 case reflect.Map:
508 mt := newMapType(name)
509 types[rt] = mt
510 type0, err = getBaseType("", t.Key())
511 if err != nil {
512 return nil, err
513 }
514 type1, err = getBaseType("", t.Elem())
515 if err != nil {
516 return nil, err
517 }
518 mt.init(type0, type1)
519 return mt, nil
520
521 case reflect.Slice:
522
523 if t.Elem().Kind() == reflect.Uint8 {
524 return tBytes.gobType(), nil
525 }
526 st := newSliceType(name)
527 types[rt] = st
528 type0, err = getBaseType(t.Elem().Name(), t.Elem())
529 if err != nil {
530 return nil, err
531 }
532 st.init(type0)
533 return st, nil
534
535 case reflect.Struct:
536 st := newStructType(name)
537 types[rt] = st
538 idToTypeSlice[st.id()] = st
539 for i := 0; i < t.NumField(); i++ {
540 f := t.Field(i)
541 if !isSent(&f) {
542 continue
543 }
544 typ := userType(f.Type).base
545 tname := typ.Name()
546 if tname == "" {
547 t := userType(f.Type).base
548 tname = t.String()
549 }
550 gt, err := getBaseType(tname, f.Type)
551 if err != nil {
552 return nil, err
553 }
554
555
556
557
558 if gt.id() == 0 {
559 setTypeId(gt)
560 }
561 st.Field = append(st.Field, fieldType{f.Name, gt.id()})
562 }
563 return st, nil
564
565 default:
566 return nil, errors.New("gob NewTypeObject can't handle type: " + rt.String())
567 }
568 }
569
570
571 func isExported(name string) bool {
572 rune, _ := utf8.DecodeRuneInString(name)
573 return unicode.IsUpper(rune)
574 }
575
576
577
578
579 func isSent(field *reflect.StructField) bool {
580 if !isExported(field.Name) {
581 return false
582 }
583
584
585 typ := field.Type
586 for typ.Kind() == reflect.Pointer {
587 typ = typ.Elem()
588 }
589 if typ.Kind() == reflect.Chan || typ.Kind() == reflect.Func {
590 return false
591 }
592 return true
593 }
594
595
596
597 func getBaseType(name string, rt reflect.Type) (gobType, error) {
598 ut := userType(rt)
599 return getType(name, ut, ut.base)
600 }
601
602
603
604
605
606
607 func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
608 typ, present := types[rt]
609 if present {
610 return typ, nil
611 }
612 typ, err := newTypeObject(name, ut, rt)
613 if err == nil {
614 types[rt] = typ
615 }
616 return typ, err
617 }
618
619 func checkId(want, got typeId) {
620 if want != got {
621 fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
622 panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
623 }
624 }
625
626
627
628 func bootstrapType(name string, e any) typeId {
629 rt := reflect.TypeOf(e).Elem()
630 _, present := types[rt]
631 if present {
632 panic("bootstrap type already present: " + name + ", " + rt.String())
633 }
634 typ := &CommonType{Name: name}
635 types[rt] = typ
636 setTypeId(typ)
637 return typ.id()
638 }
639
640
641
642
643
644
645
646
647
648
649
650
651 type wireType struct {
652 ArrayT *arrayType
653 SliceT *sliceType
654 StructT *structType
655 MapT *mapType
656 GobEncoderT *gobEncoderType
657 BinaryMarshalerT *gobEncoderType
658 TextMarshalerT *gobEncoderType
659 }
660
661 func (w *wireType) string() string {
662 const unknown = "unknown type"
663 if w == nil {
664 return unknown
665 }
666 switch {
667 case w.ArrayT != nil:
668 return w.ArrayT.Name
669 case w.SliceT != nil:
670 return w.SliceT.Name
671 case w.StructT != nil:
672 return w.StructT.Name
673 case w.MapT != nil:
674 return w.MapT.Name
675 case w.GobEncoderT != nil:
676 return w.GobEncoderT.Name
677 case w.BinaryMarshalerT != nil:
678 return w.BinaryMarshalerT.Name
679 case w.TextMarshalerT != nil:
680 return w.TextMarshalerT.Name
681 }
682 return unknown
683 }
684
685 type typeInfo struct {
686 id typeId
687 encInit sync.Mutex
688 encoder atomic.Pointer[encEngine]
689 wire wireType
690 }
691
692
693
694
695
696
697
698 var typeInfoMap atomic.Value
699
700
701
702
703
704 var typeInfoMapInit = make(map[reflect.Type]*typeInfo, 16)
705
706 func lookupTypeInfo(rt reflect.Type) *typeInfo {
707 if m := typeInfoMapInit; m != nil {
708 return m[rt]
709 }
710 m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
711 return m[rt]
712 }
713
714 func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
715 rt := ut.base
716 if ut.externalEnc != 0 {
717
718 rt = ut.user
719 }
720 if info := lookupTypeInfo(rt); info != nil {
721 return info, nil
722 }
723 return buildTypeInfo(ut, rt)
724 }
725
726
727
728 func buildTypeInfo(ut *userTypeInfo, rt reflect.Type) (*typeInfo, error) {
729 typeLock.Lock()
730 defer typeLock.Unlock()
731
732 if info := lookupTypeInfo(rt); info != nil {
733 return info, nil
734 }
735
736 gt, err := getBaseType(rt.Name(), rt)
737 if err != nil {
738 return nil, err
739 }
740 info := &typeInfo{id: gt.id()}
741
742 if ut.externalEnc != 0 {
743 userType, err := getType(rt.Name(), ut, rt)
744 if err != nil {
745 return nil, err
746 }
747 gt := userType.id().gobType().(*gobEncoderType)
748 switch ut.externalEnc {
749 case xGob:
750 info.wire.GobEncoderT = gt
751 case xBinary:
752 info.wire.BinaryMarshalerT = gt
753 case xText:
754 info.wire.TextMarshalerT = gt
755 }
756 rt = ut.user
757 } else {
758 t := info.id.gobType()
759 switch typ := rt; typ.Kind() {
760 case reflect.Array:
761 info.wire.ArrayT = t.(*arrayType)
762 case reflect.Map:
763 info.wire.MapT = t.(*mapType)
764 case reflect.Slice:
765
766 if typ.Elem().Kind() != reflect.Uint8 {
767 info.wire.SliceT = t.(*sliceType)
768 }
769 case reflect.Struct:
770 info.wire.StructT = t.(*structType)
771 }
772 }
773
774 if m := typeInfoMapInit; m != nil {
775 m[rt] = info
776 return info, nil
777 }
778
779
780 m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
781 newm := make(map[reflect.Type]*typeInfo, len(m))
782 for k, v := range m {
783 newm[k] = v
784 }
785 newm[rt] = info
786 typeInfoMap.Store(newm)
787 return info, nil
788 }
789
790
791 func mustGetTypeInfo(rt reflect.Type) *typeInfo {
792 t, err := getTypeInfo(userType(rt))
793 if err != nil {
794 panic("getTypeInfo: " + err.Error())
795 }
796 return t
797 }
798
799
800
801
802
803
804
805
806
807
808
809
810 type GobEncoder interface {
811
812
813
814 GobEncode() ([]byte, error)
815 }
816
817
818
819 type GobDecoder interface {
820
821
822
823 GobDecode([]byte) error
824 }
825
826 var (
827 nameToConcreteType sync.Map
828 concreteTypeToName sync.Map
829 )
830
831
832
833 func RegisterName(name string, value any) {
834 if name == "" {
835
836 panic("attempt to register empty name")
837 }
838
839 ut := userType(reflect.TypeOf(value))
840
841
842
843
844
845 if t, dup := nameToConcreteType.LoadOrStore(name, reflect.TypeOf(value)); dup && t != ut.user {
846 panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
847 }
848
849
850 if n, dup := concreteTypeToName.LoadOrStore(ut.base, name); dup && n != name {
851 nameToConcreteType.Delete(name)
852 panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
853 }
854 }
855
856
857
858
859
860
861
862 func Register(value any) {
863
864 rt := reflect.TypeOf(value)
865 name := rt.String()
866
867
868
869 star := ""
870 if rt.Name() == "" {
871 if pt := rt; pt.Kind() == reflect.Pointer {
872 star = "*"
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889 rt = pt
890 }
891 }
892 if rt.Name() != "" {
893 if rt.PkgPath() == "" {
894 name = star + rt.Name()
895 } else {
896 name = star + rt.PkgPath() + "." + rt.Name()
897 }
898 }
899
900 RegisterName(name, value)
901 }
902
903 func registerBasics() {
904 Register(int(0))
905 Register(int8(0))
906 Register(int16(0))
907 Register(int32(0))
908 Register(int64(0))
909 Register(uint(0))
910 Register(uint8(0))
911 Register(uint16(0))
912 Register(uint32(0))
913 Register(uint64(0))
914 Register(float32(0))
915 Register(float64(0))
916 Register(complex64(0i))
917 Register(complex128(0i))
918 Register(uintptr(0))
919 Register(false)
920 Register("")
921 Register([]byte(nil))
922 Register([]int(nil))
923 Register([]int8(nil))
924 Register([]int16(nil))
925 Register([]int32(nil))
926 Register([]int64(nil))
927 Register([]uint(nil))
928 Register([]uint8(nil))
929 Register([]uint16(nil))
930 Register([]uint32(nil))
931 Register([]uint64(nil))
932 Register([]float32(nil))
933 Register([]float64(nil))
934 Register([]complex64(nil))
935 Register([]complex128(nil))
936 Register([]uintptr(nil))
937 Register([]bool(nil))
938 Register([]string(nil))
939 }
940
941 func init() {
942 typeInfoMap.Store(typeInfoMapInit)
943 typeInfoMapInit = nil
944 }
945
View as plain text