...
1
2
3
4
5 package impl
6
7 import (
8 "reflect"
9 "sync"
10 "sync/atomic"
11
12 "google.golang.org/protobuf/reflect/protoreflect"
13 "google.golang.org/protobuf/runtime/protoiface"
14 )
15
16
17
18
19
20
21 type ExtensionInfo struct {
22
23
24
25
26
27
28
29
30
31
32
33
34
35 init uint32
36 mu sync.Mutex
37
38 goType reflect.Type
39 desc extensionTypeDescriptor
40 conv Converter
41 info *extensionFieldInfo
42
43
44
45
46
47
48 ExtendedType protoiface.MessageV1
49
50
51
52
53
54
55
56 ExtensionType interface{}
57
58
59
60
61 Field int32
62
63
64
65
66 Name string
67
68
69
70
71 Tag string
72
73
74
75
76 Filename string
77 }
78
79
80 const (
81 extensionInfoUninitialized = 0
82 extensionInfoDescInit = 1
83 extensionInfoFullInit = 2
84 )
85
86 func InitExtensionInfo(xi *ExtensionInfo, xd protoreflect.ExtensionDescriptor, goType reflect.Type) {
87 xi.goType = goType
88 xi.desc = extensionTypeDescriptor{xd, xi}
89 xi.init = extensionInfoDescInit
90 }
91
92 func (xi *ExtensionInfo) New() protoreflect.Value {
93 return xi.lazyInit().New()
94 }
95 func (xi *ExtensionInfo) Zero() protoreflect.Value {
96 return xi.lazyInit().Zero()
97 }
98 func (xi *ExtensionInfo) ValueOf(v interface{}) protoreflect.Value {
99 return xi.lazyInit().PBValueOf(reflect.ValueOf(v))
100 }
101 func (xi *ExtensionInfo) InterfaceOf(v protoreflect.Value) interface{} {
102 return xi.lazyInit().GoValueOf(v).Interface()
103 }
104 func (xi *ExtensionInfo) IsValidValue(v protoreflect.Value) bool {
105 return xi.lazyInit().IsValidPB(v)
106 }
107 func (xi *ExtensionInfo) IsValidInterface(v interface{}) bool {
108 return xi.lazyInit().IsValidGo(reflect.ValueOf(v))
109 }
110 func (xi *ExtensionInfo) TypeDescriptor() protoreflect.ExtensionTypeDescriptor {
111 if atomic.LoadUint32(&xi.init) < extensionInfoDescInit {
112 xi.lazyInitSlow()
113 }
114 return &xi.desc
115 }
116
117 func (xi *ExtensionInfo) lazyInit() Converter {
118 if atomic.LoadUint32(&xi.init) < extensionInfoFullInit {
119 xi.lazyInitSlow()
120 }
121 return xi.conv
122 }
123
124 func (xi *ExtensionInfo) lazyInitSlow() {
125 xi.mu.Lock()
126 defer xi.mu.Unlock()
127
128 if xi.init == extensionInfoFullInit {
129 return
130 }
131 defer atomic.StoreUint32(&xi.init, extensionInfoFullInit)
132
133 if xi.desc.ExtensionDescriptor == nil {
134 xi.initFromLegacy()
135 }
136 if !xi.desc.ExtensionDescriptor.IsPlaceholder() {
137 if xi.ExtensionType == nil {
138 xi.initToLegacy()
139 }
140 xi.conv = NewConverter(xi.goType, xi.desc.ExtensionDescriptor)
141 xi.info = makeExtensionFieldInfo(xi.desc.ExtensionDescriptor)
142 xi.info.validation = newValidationInfo(xi.desc.ExtensionDescriptor, xi.goType)
143 }
144 }
145
146 type extensionTypeDescriptor struct {
147 protoreflect.ExtensionDescriptor
148 xi *ExtensionInfo
149 }
150
151 func (xtd *extensionTypeDescriptor) Type() protoreflect.ExtensionType {
152 return xtd.xi
153 }
154 func (xtd *extensionTypeDescriptor) Descriptor() protoreflect.ExtensionDescriptor {
155 return xtd.ExtensionDescriptor
156 }
157
View as plain text