8 "fmt" |
8 "fmt" |
9 "reflect" |
9 "reflect" |
10 |
10 |
11 "google.golang.org/protobuf/internal/detrand" |
11 "google.golang.org/protobuf/internal/detrand" |
12 "google.golang.org/protobuf/internal/pragma" |
12 "google.golang.org/protobuf/internal/pragma" |
13 pref "google.golang.org/protobuf/reflect/protoreflect" |
13 "google.golang.org/protobuf/reflect/protoreflect" |
14 ) |
14 ) |
15 |
15 |
16 type reflectMessageInfo struct { |
16 type reflectMessageInfo struct { |
17 fields map[pref.FieldNumber]*fieldInfo |
17 fields map[protoreflect.FieldNumber]*fieldInfo |
18 oneofs map[pref.Name]*oneofInfo |
18 oneofs map[protoreflect.Name]*oneofInfo |
19 |
19 |
20 // fieldTypes contains the zero value of an enum or message field. |
20 // fieldTypes contains the zero value of an enum or message field. |
21 // For lists, it contains the element type. |
21 // For lists, it contains the element type. |
22 // For maps, it contains the entry value type. |
22 // For maps, it contains the entry value type. |
23 fieldTypes map[pref.FieldNumber]interface{} |
23 fieldTypes map[protoreflect.FieldNumber]interface{} |
24 |
24 |
25 // denseFields is a subset of fields where: |
25 // denseFields is a subset of fields where: |
26 // 0 < fieldDesc.Number() < len(denseFields) |
26 // 0 < fieldDesc.Number() < len(denseFields) |
27 // It provides faster access to the fieldInfo, but may be incomplete. |
27 // It provides faster access to the fieldInfo, but may be incomplete. |
28 denseFields []*fieldInfo |
28 denseFields []*fieldInfo |
29 |
29 |
30 // rangeInfos is a list of all fields (not belonging to a oneof) and oneofs. |
30 // rangeInfos is a list of all fields (not belonging to a oneof) and oneofs. |
31 rangeInfos []interface{} // either *fieldInfo or *oneofInfo |
31 rangeInfos []interface{} // either *fieldInfo or *oneofInfo |
32 |
32 |
33 getUnknown func(pointer) pref.RawFields |
33 getUnknown func(pointer) protoreflect.RawFields |
34 setUnknown func(pointer, pref.RawFields) |
34 setUnknown func(pointer, protoreflect.RawFields) |
35 extensionMap func(pointer) *extensionMap |
35 extensionMap func(pointer) *extensionMap |
36 |
36 |
37 nilMessage atomicNilMessage |
37 nilMessage atomicNilMessage |
38 } |
38 } |
39 |
39 |
50 // Go struct and matches message fields with struct fields. |
50 // Go struct and matches message fields with struct fields. |
51 // |
51 // |
52 // This code assumes that the struct is well-formed and panics if there are |
52 // This code assumes that the struct is well-formed and panics if there are |
53 // any discrepancies. |
53 // any discrepancies. |
54 func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) { |
54 func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) { |
55 mi.fields = map[pref.FieldNumber]*fieldInfo{} |
55 mi.fields = map[protoreflect.FieldNumber]*fieldInfo{} |
56 md := mi.Desc |
56 md := mi.Desc |
57 fds := md.Fields() |
57 fds := md.Fields() |
58 for i := 0; i < fds.Len(); i++ { |
58 for i := 0; i < fds.Len(); i++ { |
59 fd := fds.Get(i) |
59 fd := fds.Get(i) |
60 fs := si.fieldsByNumber[fd.Number()] |
60 fs := si.fieldsByNumber[fd.Number()] |
80 fi = fieldInfoForScalar(fd, fs, mi.Exporter) |
80 fi = fieldInfoForScalar(fd, fs, mi.Exporter) |
81 } |
81 } |
82 mi.fields[fd.Number()] = &fi |
82 mi.fields[fd.Number()] = &fi |
83 } |
83 } |
84 |
84 |
85 mi.oneofs = map[pref.Name]*oneofInfo{} |
85 mi.oneofs = map[protoreflect.Name]*oneofInfo{} |
86 for i := 0; i < md.Oneofs().Len(); i++ { |
86 for i := 0; i < md.Oneofs().Len(); i++ { |
87 od := md.Oneofs().Get(i) |
87 od := md.Oneofs().Get(i) |
88 mi.oneofs[od.Name()] = makeOneofInfo(od, si, mi.Exporter) |
88 mi.oneofs[od.Name()] = makeOneofInfo(od, si, mi.Exporter) |
89 } |
89 } |
90 |
90 |
115 |
115 |
116 func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) { |
116 func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) { |
117 switch { |
117 switch { |
118 case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsAType: |
118 case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsAType: |
119 // Handle as []byte. |
119 // Handle as []byte. |
120 mi.getUnknown = func(p pointer) pref.RawFields { |
120 mi.getUnknown = func(p pointer) protoreflect.RawFields { |
121 if p.IsNil() { |
121 if p.IsNil() { |
122 return nil |
122 return nil |
123 } |
123 } |
124 return *p.Apply(mi.unknownOffset).Bytes() |
124 return *p.Apply(mi.unknownOffset).Bytes() |
125 } |
125 } |
126 mi.setUnknown = func(p pointer, b pref.RawFields) { |
126 mi.setUnknown = func(p pointer, b protoreflect.RawFields) { |
127 if p.IsNil() { |
127 if p.IsNil() { |
128 panic("invalid SetUnknown on nil Message") |
128 panic("invalid SetUnknown on nil Message") |
129 } |
129 } |
130 *p.Apply(mi.unknownOffset).Bytes() = b |
130 *p.Apply(mi.unknownOffset).Bytes() = b |
131 } |
131 } |
132 case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsBType: |
132 case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsBType: |
133 // Handle as *[]byte. |
133 // Handle as *[]byte. |
134 mi.getUnknown = func(p pointer) pref.RawFields { |
134 mi.getUnknown = func(p pointer) protoreflect.RawFields { |
135 if p.IsNil() { |
135 if p.IsNil() { |
136 return nil |
136 return nil |
137 } |
137 } |
138 bp := p.Apply(mi.unknownOffset).BytesPtr() |
138 bp := p.Apply(mi.unknownOffset).BytesPtr() |
139 if *bp == nil { |
139 if *bp == nil { |
140 return nil |
140 return nil |
141 } |
141 } |
142 return **bp |
142 return **bp |
143 } |
143 } |
144 mi.setUnknown = func(p pointer, b pref.RawFields) { |
144 mi.setUnknown = func(p pointer, b protoreflect.RawFields) { |
145 if p.IsNil() { |
145 if p.IsNil() { |
146 panic("invalid SetUnknown on nil Message") |
146 panic("invalid SetUnknown on nil Message") |
147 } |
147 } |
148 bp := p.Apply(mi.unknownOffset).BytesPtr() |
148 bp := p.Apply(mi.unknownOffset).BytesPtr() |
149 if *bp == nil { |
149 if *bp == nil { |
150 *bp = new([]byte) |
150 *bp = new([]byte) |
151 } |
151 } |
152 **bp = b |
152 **bp = b |
153 } |
153 } |
154 default: |
154 default: |
155 mi.getUnknown = func(pointer) pref.RawFields { |
155 mi.getUnknown = func(pointer) protoreflect.RawFields { |
156 return nil |
156 return nil |
157 } |
157 } |
158 mi.setUnknown = func(p pointer, _ pref.RawFields) { |
158 mi.setUnknown = func(p pointer, _ protoreflect.RawFields) { |
159 if p.IsNil() { |
159 if p.IsNil() { |
160 panic("invalid SetUnknown on nil Message") |
160 panic("invalid SetUnknown on nil Message") |
161 } |
161 } |
162 } |
162 } |
163 } |
163 } |
222 if isMessage && ft != nil && ft.Kind() != reflect.Ptr { |
222 if isMessage && ft != nil && ft.Kind() != reflect.Ptr { |
223 ft = reflect.PtrTo(ft) // never occurs for officially generated message types |
223 ft = reflect.PtrTo(ft) // never occurs for officially generated message types |
224 } |
224 } |
225 if ft != nil { |
225 if ft != nil { |
226 if mi.fieldTypes == nil { |
226 if mi.fieldTypes == nil { |
227 mi.fieldTypes = make(map[pref.FieldNumber]interface{}) |
227 mi.fieldTypes = make(map[protoreflect.FieldNumber]interface{}) |
228 } |
228 } |
229 mi.fieldTypes[fd.Number()] = reflect.Zero(ft).Interface() |
229 mi.fieldTypes[fd.Number()] = reflect.Zero(ft).Interface() |
230 } |
230 } |
231 } |
231 } |
232 } |
232 } |
233 |
233 |
234 type extensionMap map[int32]ExtensionField |
234 type extensionMap map[int32]ExtensionField |
235 |
235 |
236 func (m *extensionMap) Range(f func(pref.FieldDescriptor, pref.Value) bool) { |
236 func (m *extensionMap) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { |
237 if m != nil { |
237 if m != nil { |
238 for _, x := range *m { |
238 for _, x := range *m { |
239 xd := x.Type().TypeDescriptor() |
239 xd := x.Type().TypeDescriptor() |
240 v := x.Value() |
240 v := x.Value() |
241 if xd.IsList() && v.List().Len() == 0 { |
241 if xd.IsList() && v.List().Len() == 0 { |
264 case xd.Message() != nil: |
264 case xd.Message() != nil: |
265 return x.Value().Message().IsValid() |
265 return x.Value().Message().IsValid() |
266 } |
266 } |
267 return true |
267 return true |
268 } |
268 } |
269 func (m *extensionMap) Clear(xt pref.ExtensionType) { |
269 func (m *extensionMap) Clear(xt protoreflect.ExtensionType) { |
270 delete(*m, int32(xt.TypeDescriptor().Number())) |
270 delete(*m, int32(xt.TypeDescriptor().Number())) |
271 } |
271 } |
272 func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value { |
272 func (m *extensionMap) Get(xt protoreflect.ExtensionType) protoreflect.Value { |
273 xd := xt.TypeDescriptor() |
273 xd := xt.TypeDescriptor() |
274 if m != nil { |
274 if m != nil { |
275 if x, ok := (*m)[int32(xd.Number())]; ok { |
275 if x, ok := (*m)[int32(xd.Number())]; ok { |
276 return x.Value() |
276 return x.Value() |
277 } |
277 } |
278 } |
278 } |
279 return xt.Zero() |
279 return xt.Zero() |
280 } |
280 } |
281 func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) { |
281 func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value) { |
282 xd := xt.TypeDescriptor() |
282 xd := xt.TypeDescriptor() |
283 isValid := true |
283 isValid := true |
284 switch { |
284 switch { |
285 case !xt.IsValidValue(v): |
285 case !xt.IsValidValue(v): |
286 isValid = false |
286 isValid = false |
300 } |
300 } |
301 var x ExtensionField |
301 var x ExtensionField |
302 x.Set(xt, v) |
302 x.Set(xt, v) |
303 (*m)[int32(xd.Number())] = x |
303 (*m)[int32(xd.Number())] = x |
304 } |
304 } |
305 func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value { |
305 func (m *extensionMap) Mutable(xt protoreflect.ExtensionType) protoreflect.Value { |
306 xd := xt.TypeDescriptor() |
306 xd := xt.TypeDescriptor() |
307 if xd.Kind() != pref.MessageKind && xd.Kind() != pref.GroupKind && !xd.IsList() && !xd.IsMap() { |
307 if xd.Kind() != protoreflect.MessageKind && xd.Kind() != protoreflect.GroupKind && !xd.IsList() && !xd.IsMap() { |
308 panic("invalid Mutable on field with non-composite type") |
308 panic("invalid Mutable on field with non-composite type") |
309 } |
309 } |
310 if x, ok := (*m)[int32(xd.Number())]; ok { |
310 if x, ok := (*m)[int32(xd.Number())]; ok { |
311 return x.Value() |
311 return x.Value() |
312 } |
312 } |
317 |
317 |
318 // MessageState is a data structure that is nested as the first field in a |
318 // MessageState is a data structure that is nested as the first field in a |
319 // concrete message. It provides a way to implement the ProtoReflect method |
319 // concrete message. It provides a way to implement the ProtoReflect method |
320 // in an allocation-free way without needing to have a shadow Go type generated |
320 // in an allocation-free way without needing to have a shadow Go type generated |
321 // for every message type. This technique only works using unsafe. |
321 // for every message type. This technique only works using unsafe. |
322 // |
|
323 // |
322 // |
324 // Example generated code: |
323 // Example generated code: |
325 // |
324 // |
326 // type M struct { |
325 // type M struct { |
327 // state protoimpl.MessageState |
326 // state protoimpl.MessageState |
349 // By unsafely converting a *M into a *MessageState, the MessageState object |
348 // By unsafely converting a *M into a *MessageState, the MessageState object |
350 // has access to all the information needed to implement protobuf reflection. |
349 // has access to all the information needed to implement protobuf reflection. |
351 // It has access to the message info as its first field, and a pointer to the |
350 // It has access to the message info as its first field, and a pointer to the |
352 // MessageState is identical to a pointer to the concrete message value. |
351 // MessageState is identical to a pointer to the concrete message value. |
353 // |
352 // |
354 // |
|
355 // Requirements: |
353 // Requirements: |
356 // • The type M must implement protoreflect.ProtoMessage. |
354 // - The type M must implement protoreflect.ProtoMessage. |
357 // • The address of m must not be nil. |
355 // - The address of m must not be nil. |
358 // • The address of m and the address of m.state must be equal, |
356 // - The address of m and the address of m.state must be equal, |
359 // even though they are different Go types. |
357 // even though they are different Go types. |
360 type MessageState struct { |
358 type MessageState struct { |
361 pragma.NoUnkeyedLiterals |
359 pragma.NoUnkeyedLiterals |
362 pragma.DoNotCompare |
360 pragma.DoNotCompare |
363 pragma.DoNotCopy |
361 pragma.DoNotCopy |
364 |
362 |
366 } |
364 } |
367 |
365 |
368 type messageState MessageState |
366 type messageState MessageState |
369 |
367 |
370 var ( |
368 var ( |
371 _ pref.Message = (*messageState)(nil) |
369 _ protoreflect.Message = (*messageState)(nil) |
372 _ unwrapper = (*messageState)(nil) |
370 _ unwrapper = (*messageState)(nil) |
373 ) |
371 ) |
374 |
372 |
375 // messageDataType is a tuple of a pointer to the message data and |
373 // messageDataType is a tuple of a pointer to the message data and |
376 // a pointer to the message type. It is a generalized way of providing a |
374 // a pointer to the message type. It is a generalized way of providing a |
377 // reflective view over a message instance. The disadvantage of this approach |
375 // reflective view over a message instance. The disadvantage of this approach |
385 messageReflectWrapper messageDataType |
383 messageReflectWrapper messageDataType |
386 messageIfaceWrapper messageDataType |
384 messageIfaceWrapper messageDataType |
387 ) |
385 ) |
388 |
386 |
389 var ( |
387 var ( |
390 _ pref.Message = (*messageReflectWrapper)(nil) |
388 _ protoreflect.Message = (*messageReflectWrapper)(nil) |
391 _ unwrapper = (*messageReflectWrapper)(nil) |
389 _ unwrapper = (*messageReflectWrapper)(nil) |
392 _ pref.ProtoMessage = (*messageIfaceWrapper)(nil) |
390 _ protoreflect.ProtoMessage = (*messageIfaceWrapper)(nil) |
393 _ unwrapper = (*messageIfaceWrapper)(nil) |
391 _ unwrapper = (*messageIfaceWrapper)(nil) |
394 ) |
392 ) |
395 |
393 |
396 // MessageOf returns a reflective view over a message. The input must be a |
394 // MessageOf returns a reflective view over a message. The input must be a |
397 // pointer to a named Go struct. If the provided type has a ProtoReflect method, |
395 // pointer to a named Go struct. If the provided type has a ProtoReflect method, |
398 // it must be implemented by calling this method. |
396 // it must be implemented by calling this method. |
399 func (mi *MessageInfo) MessageOf(m interface{}) pref.Message { |
397 func (mi *MessageInfo) MessageOf(m interface{}) protoreflect.Message { |
400 if reflect.TypeOf(m) != mi.GoReflectType { |
398 if reflect.TypeOf(m) != mi.GoReflectType { |
401 panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType)) |
399 panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType)) |
402 } |
400 } |
403 p := pointerOfIface(m) |
401 p := pointerOfIface(m) |
404 if p.IsNil() { |
402 if p.IsNil() { |
419 rv := reflect.ValueOf(m.protoUnwrap()) |
417 rv := reflect.ValueOf(m.protoUnwrap()) |
420 if rv.Kind() == reflect.Ptr && !rv.IsNil() { |
418 if rv.Kind() == reflect.Ptr && !rv.IsNil() { |
421 rv.Elem().Set(reflect.Zero(rv.Type().Elem())) |
419 rv.Elem().Set(reflect.Zero(rv.Type().Elem())) |
422 } |
420 } |
423 } |
421 } |
424 func (m *messageIfaceWrapper) ProtoReflect() pref.Message { |
422 func (m *messageIfaceWrapper) ProtoReflect() protoreflect.Message { |
425 return (*messageReflectWrapper)(m) |
423 return (*messageReflectWrapper)(m) |
426 } |
424 } |
427 func (m *messageIfaceWrapper) protoUnwrap() interface{} { |
425 func (m *messageIfaceWrapper) protoUnwrap() interface{} { |
428 return m.p.AsIfaceOf(m.mi.GoReflectType.Elem()) |
426 return m.p.AsIfaceOf(m.mi.GoReflectType.Elem()) |
429 } |
427 } |
430 |
428 |
431 // checkField verifies that the provided field descriptor is valid. |
429 // checkField verifies that the provided field descriptor is valid. |
432 // Exactly one of the returned values is populated. |
430 // Exactly one of the returned values is populated. |
433 func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.ExtensionType) { |
431 func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionType) { |
434 var fi *fieldInfo |
432 var fi *fieldInfo |
435 if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) { |
433 if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) { |
436 fi = mi.denseFields[n] |
434 fi = mi.denseFields[n] |
437 } else { |
435 } else { |
438 fi = mi.fields[n] |
436 fi = mi.fields[n] |
453 panic(fmt.Sprintf("extension %v has mismatching containing message: got %v, want %v", fd.FullName(), got, want)) |
451 panic(fmt.Sprintf("extension %v has mismatching containing message: got %v, want %v", fd.FullName(), got, want)) |
454 } |
452 } |
455 if !mi.Desc.ExtensionRanges().Has(fd.Number()) { |
453 if !mi.Desc.ExtensionRanges().Has(fd.Number()) { |
456 panic(fmt.Sprintf("extension %v extends %v outside the extension range", fd.FullName(), mi.Desc.FullName())) |
454 panic(fmt.Sprintf("extension %v extends %v outside the extension range", fd.FullName(), mi.Desc.FullName())) |
457 } |
455 } |
458 xtd, ok := fd.(pref.ExtensionTypeDescriptor) |
456 xtd, ok := fd.(protoreflect.ExtensionTypeDescriptor) |
459 if !ok { |
457 if !ok { |
460 panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName())) |
458 panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName())) |
461 } |
459 } |
462 return nil, xtd.Type() |
460 return nil, xtd.Type() |
463 } |
461 } |