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.TypeFor[GobEncoder]()
107 gobDecoderInterfaceType = reflect.TypeFor[GobDecoder]()
108 binaryMarshalerInterfaceType = reflect.TypeFor[encoding.BinaryMarshaler]()
109 binaryUnmarshalerInterfaceType = reflect.TypeFor[encoding.BinaryUnmarshaler]()
110 textMarshalerInterfaceType = reflect.TypeFor[encoding.TextMarshaler]()
111 textUnmarshalerInterfaceType = reflect.TypeFor[encoding.TextUnmarshaler]()
112
113 wireTypeType = reflect.TypeFor[wireType]()
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.TypeFor[arrayType]()).id)
283 checkId(18, mustGetTypeInfo(reflect.TypeFor[CommonType]()).id)
284 checkId(19, mustGetTypeInfo(reflect.TypeFor[sliceType]()).id)
285 checkId(20, mustGetTypeInfo(reflect.TypeFor[structType]()).id)
286 checkId(21, mustGetTypeInfo(reflect.TypeFor[fieldType]()).id)
287 checkId(23, mustGetTypeInfo(reflect.TypeFor[mapType]()).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
593 return true
594 }
595
596
597
598 func getBaseType(name string, rt reflect.Type) (gobType, error) {
599 ut := userType(rt)
600 return getType(name, ut, ut.base)
601 }
602
603
604
605
606
607
608 func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
609 typ, present := types[rt]
610 if present {
611 return typ, nil
612 }
613 typ, err := newTypeObject(name, ut, rt)
614 if err == nil {
615 types[rt] = typ
616 }
617 return typ, err
618 }
619
620 func checkId(want, got typeId) {
621 if want != got {
622 fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
623 panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
624 }
625 }
626
627
628
629 func bootstrapType(name string, e any) typeId {
630 rt := reflect.TypeOf(e).Elem()
631 _, present := types[rt]
632 if present {
633 panic("bootstrap type already present: " + name + ", " + rt.String())
634 }
635 typ := &CommonType{Name: name}
636 types[rt] = typ
637 setTypeId(typ)
638 return typ.id()
639 }
640
641
642
643
644
645
646
647
648
649
650
651
652 type wireType struct {
653 ArrayT *arrayType
654 SliceT *sliceType
655 StructT *structType
656 MapT *mapType
657 GobEncoderT *gobEncoderType
658 BinaryMarshalerT *gobEncoderType
659 TextMarshalerT *gobEncoderType
660 }
661
662 func (w *wireType) string() string {
663 const unknown = "unknown type"
664 if w == nil {
665 return unknown
666 }
667 switch {
668 case w.ArrayT != nil:
669 return w.ArrayT.Name
670 case w.SliceT != nil:
671 return w.SliceT.Name
672 case w.StructT != nil:
673 return w.StructT.Name
674 case w.MapT != nil:
675 return w.MapT.Name
676 case w.GobEncoderT != nil:
677 return w.GobEncoderT.Name
678 case w.BinaryMarshalerT != nil:
679 return w.BinaryMarshalerT.Name
680 case w.TextMarshalerT != nil:
681 return w.TextMarshalerT.Name
682 }
683 return unknown
684 }
685
686 type typeInfo struct {
687 id typeId
688 encInit sync.Mutex
689 encoder atomic.Pointer[encEngine]
690 wire wireType
691 }
692
693
694
695
696
697
698
699 var typeInfoMap atomic.Value
700
701
702
703
704
705 var typeInfoMapInit = make(map[reflect.Type]*typeInfo, 16)
706
707 func lookupTypeInfo(rt reflect.Type) *typeInfo {
708 if m := typeInfoMapInit; m != nil {
709 return m[rt]
710 }
711 m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
712 return m[rt]
713 }
714
715 func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
716 rt := ut.base
717 if ut.externalEnc != 0 {
718
719 rt = ut.user
720 }
721 if info := lookupTypeInfo(rt); info != nil {
722 return info, nil
723 }
724 return buildTypeInfo(ut, rt)
725 }
726
727
728
729 func buildTypeInfo(ut *userTypeInfo, rt reflect.Type) (*typeInfo, error) {
730 typeLock.Lock()
731 defer typeLock.Unlock()
732
733 if info := lookupTypeInfo(rt); info != nil {
734 return info, nil
735 }
736
737 gt, err := getBaseType(rt.Name(), rt)
738 if err != nil {
739 return nil, err
740 }
741 info := &typeInfo{id: gt.id()}
742
743 if ut.externalEnc != 0 {
744 userType, err := getType(rt.Name(), ut, rt)
745 if err != nil {
746 return nil, err
747 }
748 gt := userType.id().gobType().(*gobEncoderType)
749 switch ut.externalEnc {
750 case xGob:
751 info.wire.GobEncoderT = gt
752 case xBinary:
753 info.wire.BinaryMarshalerT = gt
754 case xText:
755 info.wire.TextMarshalerT = gt
756 }
757 rt = ut.user
758 } else {
759 t := info.id.gobType()
760 switch typ := rt; typ.Kind() {
761 case reflect.Array:
762 info.wire.ArrayT = t.(*arrayType)
763 case reflect.Map:
764 info.wire.MapT = t.(*mapType)
765 case reflect.Slice:
766
767 if typ.Elem().Kind() != reflect.Uint8 {
768 info.wire.SliceT = t.(*sliceType)
769 }
770 case reflect.Struct:
771 info.wire.StructT = t.(*structType)
772 }
773 }
774
775 if m := typeInfoMapInit; m != nil {
776 m[rt] = info
777 return info, nil
778 }
779
780
781 m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
782 newm := make(map[reflect.Type]*typeInfo, len(m))
783 for k, v := range m {
784 newm[k] = v
785 }
786 newm[rt] = info
787 typeInfoMap.Store(newm)
788 return info, nil
789 }
790
791
792 func mustGetTypeInfo(rt reflect.Type) *typeInfo {
793 t, err := getTypeInfo(userType(rt))
794 if err != nil {
795 panic("getTypeInfo: " + err.Error())
796 }
797 return t
798 }
799
800
801
802
803
804
805
806
807
808
809
810
811 type GobEncoder interface {
812
813
814
815 GobEncode() ([]byte, error)
816 }
817
818
819
820 type GobDecoder interface {
821
822
823
824 GobDecode([]byte) error
825 }
826
827 var (
828 nameToConcreteType sync.Map
829 concreteTypeToName sync.Map
830 )
831
832
833
834 func RegisterName(name string, value any) {
835 if name == "" {
836
837 panic("attempt to register empty name")
838 }
839
840 ut := userType(reflect.TypeOf(value))
841
842
843
844
845
846 if t, dup := nameToConcreteType.LoadOrStore(name, reflect.TypeOf(value)); dup && t != ut.user {
847 panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
848 }
849
850
851 if n, dup := concreteTypeToName.LoadOrStore(ut.base, name); dup && n != name {
852 nameToConcreteType.Delete(name)
853 panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
854 }
855 }
856
857
858
859
860
861
862
863 func Register(value any) {
864
865 rt := reflect.TypeOf(value)
866 name := rt.String()
867
868
869
870 star := ""
871 if rt.Name() == "" {
872 if pt := rt; pt.Kind() == reflect.Pointer {
873 star = "*"
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890 rt = pt
891 }
892 }
893 if rt.Name() != "" {
894 if rt.PkgPath() == "" {
895 name = star + rt.Name()
896 } else {
897 name = star + rt.PkgPath() + "." + rt.Name()
898 }
899 }
900
901 RegisterName(name, value)
902 }
903
904 func registerBasics() {
905 Register(int(0))
906 Register(int8(0))
907 Register(int16(0))
908 Register(int32(0))
909 Register(int64(0))
910 Register(uint(0))
911 Register(uint8(0))
912 Register(uint16(0))
913 Register(uint32(0))
914 Register(uint64(0))
915 Register(float32(0))
916 Register(float64(0))
917 Register(complex64(0i))
918 Register(complex128(0i))
919 Register(uintptr(0))
920 Register(false)
921 Register("")
922 Register([]byte(nil))
923 Register([]int(nil))
924 Register([]int8(nil))
925 Register([]int16(nil))
926 Register([]int32(nil))
927 Register([]int64(nil))
928 Register([]uint(nil))
929 Register([]uint8(nil))
930 Register([]uint16(nil))
931 Register([]uint32(nil))
932 Register([]uint64(nil))
933 Register([]float32(nil))
934 Register([]float64(nil))
935 Register([]complex64(nil))
936 Register([]complex128(nil))
937 Register([]uintptr(nil))
938 Register([]bool(nil))
939 Register([]string(nil))
940 }
941
942 func init() {
943 typeInfoMap.Store(typeInfoMapInit)
944 typeInfoMapInit = nil
945 }
946
View as plain text