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