9 "math" |
9 "math" |
10 "reflect" |
10 "reflect" |
11 "sync" |
11 "sync" |
12 |
12 |
13 "google.golang.org/protobuf/internal/flags" |
13 "google.golang.org/protobuf/internal/flags" |
14 pref "google.golang.org/protobuf/reflect/protoreflect" |
14 "google.golang.org/protobuf/reflect/protoreflect" |
15 preg "google.golang.org/protobuf/reflect/protoregistry" |
15 "google.golang.org/protobuf/reflect/protoregistry" |
16 ) |
16 ) |
17 |
17 |
18 type fieldInfo struct { |
18 type fieldInfo struct { |
19 fieldDesc pref.FieldDescriptor |
19 fieldDesc protoreflect.FieldDescriptor |
20 |
20 |
21 // These fields are used for protobuf reflection support. |
21 // These fields are used for protobuf reflection support. |
22 has func(pointer) bool |
22 has func(pointer) bool |
23 clear func(pointer) |
23 clear func(pointer) |
24 get func(pointer) pref.Value |
24 get func(pointer) protoreflect.Value |
25 set func(pointer, pref.Value) |
25 set func(pointer, protoreflect.Value) |
26 mutable func(pointer) pref.Value |
26 mutable func(pointer) protoreflect.Value |
27 newMessage func() pref.Message |
27 newMessage func() protoreflect.Message |
28 newField func() pref.Value |
28 newField func() protoreflect.Value |
29 } |
29 } |
30 |
30 |
31 func fieldInfoForMissing(fd pref.FieldDescriptor) fieldInfo { |
31 func fieldInfoForMissing(fd protoreflect.FieldDescriptor) fieldInfo { |
32 // This never occurs for generated message types. |
32 // This never occurs for generated message types. |
33 // It implies that a hand-crafted type has missing Go fields |
33 // It implies that a hand-crafted type has missing Go fields |
34 // for specific protobuf message fields. |
34 // for specific protobuf message fields. |
35 return fieldInfo{ |
35 return fieldInfo{ |
36 fieldDesc: fd, |
36 fieldDesc: fd, |
38 return false |
38 return false |
39 }, |
39 }, |
40 clear: func(p pointer) { |
40 clear: func(p pointer) { |
41 panic("missing Go struct field for " + string(fd.FullName())) |
41 panic("missing Go struct field for " + string(fd.FullName())) |
42 }, |
42 }, |
43 get: func(p pointer) pref.Value { |
43 get: func(p pointer) protoreflect.Value { |
44 return fd.Default() |
44 return fd.Default() |
45 }, |
45 }, |
46 set: func(p pointer, v pref.Value) { |
46 set: func(p pointer, v protoreflect.Value) { |
47 panic("missing Go struct field for " + string(fd.FullName())) |
47 panic("missing Go struct field for " + string(fd.FullName())) |
48 }, |
48 }, |
49 mutable: func(p pointer) pref.Value { |
49 mutable: func(p pointer) protoreflect.Value { |
50 panic("missing Go struct field for " + string(fd.FullName())) |
50 panic("missing Go struct field for " + string(fd.FullName())) |
51 }, |
51 }, |
52 newMessage: func() pref.Message { |
52 newMessage: func() protoreflect.Message { |
53 panic("missing Go struct field for " + string(fd.FullName())) |
53 panic("missing Go struct field for " + string(fd.FullName())) |
54 }, |
54 }, |
55 newField: func() pref.Value { |
55 newField: func() protoreflect.Value { |
56 if v := fd.Default(); v.IsValid() { |
56 if v := fd.Default(); v.IsValid() { |
57 return v |
57 return v |
58 } |
58 } |
59 panic("missing Go struct field for " + string(fd.FullName())) |
59 panic("missing Go struct field for " + string(fd.FullName())) |
60 }, |
60 }, |
61 } |
61 } |
62 } |
62 } |
63 |
63 |
64 func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo { |
64 func fieldInfoForOneof(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo { |
65 ft := fs.Type |
65 ft := fs.Type |
66 if ft.Kind() != reflect.Interface { |
66 if ft.Kind() != reflect.Interface { |
67 panic(fmt.Sprintf("field %v has invalid type: got %v, want interface kind", fd.FullName(), ft)) |
67 panic(fmt.Sprintf("field %v has invalid type: got %v, want interface kind", fd.FullName(), ft)) |
68 } |
68 } |
69 if ot.Kind() != reflect.Struct { |
69 if ot.Kind() != reflect.Struct { |
100 // so that (*OneofWrapperType)(nil) gets cleared to nil. |
100 // so that (*OneofWrapperType)(nil) gets cleared to nil. |
101 return |
101 return |
102 } |
102 } |
103 rv.Set(reflect.Zero(rv.Type())) |
103 rv.Set(reflect.Zero(rv.Type())) |
104 }, |
104 }, |
105 get: func(p pointer) pref.Value { |
105 get: func(p pointer) protoreflect.Value { |
106 if p.IsNil() { |
106 if p.IsNil() { |
107 return conv.Zero() |
107 return conv.Zero() |
108 } |
108 } |
109 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
109 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
110 if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() { |
110 if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() { |
111 return conv.Zero() |
111 return conv.Zero() |
112 } |
112 } |
113 rv = rv.Elem().Elem().Field(0) |
113 rv = rv.Elem().Elem().Field(0) |
114 return conv.PBValueOf(rv) |
114 return conv.PBValueOf(rv) |
115 }, |
115 }, |
116 set: func(p pointer, v pref.Value) { |
116 set: func(p pointer, v protoreflect.Value) { |
117 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
117 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
118 if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() { |
118 if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() { |
119 rv.Set(reflect.New(ot)) |
119 rv.Set(reflect.New(ot)) |
120 } |
120 } |
121 rv = rv.Elem().Elem().Field(0) |
121 rv = rv.Elem().Elem().Field(0) |
122 rv.Set(conv.GoValueOf(v)) |
122 rv.Set(conv.GoValueOf(v)) |
123 }, |
123 }, |
124 mutable: func(p pointer) pref.Value { |
124 mutable: func(p pointer) protoreflect.Value { |
125 if !isMessage { |
125 if !isMessage { |
126 panic(fmt.Sprintf("field %v with invalid Mutable call on field with non-composite type", fd.FullName())) |
126 panic(fmt.Sprintf("field %v with invalid Mutable call on field with non-composite type", fd.FullName())) |
127 } |
127 } |
128 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
128 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
129 if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() { |
129 if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() { |
130 rv.Set(reflect.New(ot)) |
130 rv.Set(reflect.New(ot)) |
131 } |
131 } |
132 rv = rv.Elem().Elem().Field(0) |
132 rv = rv.Elem().Elem().Field(0) |
133 if rv.Kind() == reflect.Ptr && rv.IsNil() { |
133 if rv.Kind() == reflect.Ptr && rv.IsNil() { |
134 rv.Set(conv.GoValueOf(pref.ValueOfMessage(conv.New().Message()))) |
134 rv.Set(conv.GoValueOf(protoreflect.ValueOfMessage(conv.New().Message()))) |
135 } |
135 } |
136 return conv.PBValueOf(rv) |
136 return conv.PBValueOf(rv) |
137 }, |
137 }, |
138 newMessage: func() pref.Message { |
138 newMessage: func() protoreflect.Message { |
139 return conv.New().Message() |
139 return conv.New().Message() |
140 }, |
140 }, |
141 newField: func() pref.Value { |
141 newField: func() protoreflect.Value { |
142 return conv.New() |
142 return conv.New() |
143 }, |
143 }, |
144 } |
144 } |
145 } |
145 } |
146 |
146 |
147 func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { |
147 func fieldInfoForMap(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { |
148 ft := fs.Type |
148 ft := fs.Type |
149 if ft.Kind() != reflect.Map { |
149 if ft.Kind() != reflect.Map { |
150 panic(fmt.Sprintf("field %v has invalid type: got %v, want map kind", fd.FullName(), ft)) |
150 panic(fmt.Sprintf("field %v has invalid type: got %v, want map kind", fd.FullName(), ft)) |
151 } |
151 } |
152 conv := NewConverter(ft, fd) |
152 conv := NewConverter(ft, fd) |
164 }, |
164 }, |
165 clear: func(p pointer) { |
165 clear: func(p pointer) { |
166 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
166 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
167 rv.Set(reflect.Zero(rv.Type())) |
167 rv.Set(reflect.Zero(rv.Type())) |
168 }, |
168 }, |
169 get: func(p pointer) pref.Value { |
169 get: func(p pointer) protoreflect.Value { |
170 if p.IsNil() { |
170 if p.IsNil() { |
171 return conv.Zero() |
171 return conv.Zero() |
172 } |
172 } |
173 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
173 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
174 if rv.Len() == 0 { |
174 if rv.Len() == 0 { |
175 return conv.Zero() |
175 return conv.Zero() |
176 } |
176 } |
177 return conv.PBValueOf(rv) |
177 return conv.PBValueOf(rv) |
178 }, |
178 }, |
179 set: func(p pointer, v pref.Value) { |
179 set: func(p pointer, v protoreflect.Value) { |
180 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
180 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
181 pv := conv.GoValueOf(v) |
181 pv := conv.GoValueOf(v) |
182 if pv.IsNil() { |
182 if pv.IsNil() { |
183 panic(fmt.Sprintf("map field %v cannot be set with read-only value", fd.FullName())) |
183 panic(fmt.Sprintf("map field %v cannot be set with read-only value", fd.FullName())) |
184 } |
184 } |
185 rv.Set(pv) |
185 rv.Set(pv) |
186 }, |
186 }, |
187 mutable: func(p pointer) pref.Value { |
187 mutable: func(p pointer) protoreflect.Value { |
188 v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
188 v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
189 if v.IsNil() { |
189 if v.IsNil() { |
190 v.Set(reflect.MakeMap(fs.Type)) |
190 v.Set(reflect.MakeMap(fs.Type)) |
191 } |
191 } |
192 return conv.PBValueOf(v) |
192 return conv.PBValueOf(v) |
193 }, |
193 }, |
194 newField: func() pref.Value { |
194 newField: func() protoreflect.Value { |
195 return conv.New() |
195 return conv.New() |
196 }, |
196 }, |
197 } |
197 } |
198 } |
198 } |
199 |
199 |
200 func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { |
200 func fieldInfoForList(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { |
201 ft := fs.Type |
201 ft := fs.Type |
202 if ft.Kind() != reflect.Slice { |
202 if ft.Kind() != reflect.Slice { |
203 panic(fmt.Sprintf("field %v has invalid type: got %v, want slice kind", fd.FullName(), ft)) |
203 panic(fmt.Sprintf("field %v has invalid type: got %v, want slice kind", fd.FullName(), ft)) |
204 } |
204 } |
205 conv := NewConverter(reflect.PtrTo(ft), fd) |
205 conv := NewConverter(reflect.PtrTo(ft), fd) |
217 }, |
217 }, |
218 clear: func(p pointer) { |
218 clear: func(p pointer) { |
219 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
219 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
220 rv.Set(reflect.Zero(rv.Type())) |
220 rv.Set(reflect.Zero(rv.Type())) |
221 }, |
221 }, |
222 get: func(p pointer) pref.Value { |
222 get: func(p pointer) protoreflect.Value { |
223 if p.IsNil() { |
223 if p.IsNil() { |
224 return conv.Zero() |
224 return conv.Zero() |
225 } |
225 } |
226 rv := p.Apply(fieldOffset).AsValueOf(fs.Type) |
226 rv := p.Apply(fieldOffset).AsValueOf(fs.Type) |
227 if rv.Elem().Len() == 0 { |
227 if rv.Elem().Len() == 0 { |
228 return conv.Zero() |
228 return conv.Zero() |
229 } |
229 } |
230 return conv.PBValueOf(rv) |
230 return conv.PBValueOf(rv) |
231 }, |
231 }, |
232 set: func(p pointer, v pref.Value) { |
232 set: func(p pointer, v protoreflect.Value) { |
233 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
233 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
234 pv := conv.GoValueOf(v) |
234 pv := conv.GoValueOf(v) |
235 if pv.IsNil() { |
235 if pv.IsNil() { |
236 panic(fmt.Sprintf("list field %v cannot be set with read-only value", fd.FullName())) |
236 panic(fmt.Sprintf("list field %v cannot be set with read-only value", fd.FullName())) |
237 } |
237 } |
238 rv.Set(pv.Elem()) |
238 rv.Set(pv.Elem()) |
239 }, |
239 }, |
240 mutable: func(p pointer) pref.Value { |
240 mutable: func(p pointer) protoreflect.Value { |
241 v := p.Apply(fieldOffset).AsValueOf(fs.Type) |
241 v := p.Apply(fieldOffset).AsValueOf(fs.Type) |
242 return conv.PBValueOf(v) |
242 return conv.PBValueOf(v) |
243 }, |
243 }, |
244 newField: func() pref.Value { |
244 newField: func() protoreflect.Value { |
245 return conv.New() |
245 return conv.New() |
246 }, |
246 }, |
247 } |
247 } |
248 } |
248 } |
249 |
249 |
250 var ( |
250 var ( |
251 nilBytes = reflect.ValueOf([]byte(nil)) |
251 nilBytes = reflect.ValueOf([]byte(nil)) |
252 emptyBytes = reflect.ValueOf([]byte{}) |
252 emptyBytes = reflect.ValueOf([]byte{}) |
253 ) |
253 ) |
254 |
254 |
255 func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { |
255 func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { |
256 ft := fs.Type |
256 ft := fs.Type |
257 nullable := fd.HasPresence() |
257 nullable := fd.HasPresence() |
258 isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 |
258 isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 |
259 if nullable { |
259 if nullable { |
260 if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice { |
260 if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice { |
330 } else { |
330 } else { |
331 rv.Set(nilBytes) // do not preserve presence |
331 rv.Set(nilBytes) // do not preserve presence |
332 } |
332 } |
333 } |
333 } |
334 }, |
334 }, |
335 newField: func() pref.Value { |
335 newField: func() protoreflect.Value { |
336 return conv.New() |
336 return conv.New() |
337 }, |
337 }, |
338 } |
338 } |
339 } |
339 } |
340 |
340 |
341 func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldInfo { |
341 func fieldInfoForWeakMessage(fd protoreflect.FieldDescriptor, weakOffset offset) fieldInfo { |
342 if !flags.ProtoLegacy { |
342 if !flags.ProtoLegacy { |
343 panic("no support for proto1 weak fields") |
343 panic("no support for proto1 weak fields") |
344 } |
344 } |
345 |
345 |
346 var once sync.Once |
346 var once sync.Once |
347 var messageType pref.MessageType |
347 var messageType protoreflect.MessageType |
348 lazyInit := func() { |
348 lazyInit := func() { |
349 once.Do(func() { |
349 once.Do(func() { |
350 messageName := fd.Message().FullName() |
350 messageName := fd.Message().FullName() |
351 messageType, _ = preg.GlobalTypes.FindMessageByName(messageName) |
351 messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName) |
352 if messageType == nil { |
352 if messageType == nil { |
353 panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName())) |
353 panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName())) |
354 } |
354 } |
355 }) |
355 }) |
356 } |
356 } |
366 return ok |
366 return ok |
367 }, |
367 }, |
368 clear: func(p pointer) { |
368 clear: func(p pointer) { |
369 p.Apply(weakOffset).WeakFields().clear(num) |
369 p.Apply(weakOffset).WeakFields().clear(num) |
370 }, |
370 }, |
371 get: func(p pointer) pref.Value { |
371 get: func(p pointer) protoreflect.Value { |
372 lazyInit() |
372 lazyInit() |
373 if p.IsNil() { |
373 if p.IsNil() { |
374 return pref.ValueOfMessage(messageType.Zero()) |
374 return protoreflect.ValueOfMessage(messageType.Zero()) |
375 } |
375 } |
376 m, ok := p.Apply(weakOffset).WeakFields().get(num) |
376 m, ok := p.Apply(weakOffset).WeakFields().get(num) |
377 if !ok { |
377 if !ok { |
378 return pref.ValueOfMessage(messageType.Zero()) |
378 return protoreflect.ValueOfMessage(messageType.Zero()) |
379 } |
379 } |
380 return pref.ValueOfMessage(m.ProtoReflect()) |
380 return protoreflect.ValueOfMessage(m.ProtoReflect()) |
381 }, |
381 }, |
382 set: func(p pointer, v pref.Value) { |
382 set: func(p pointer, v protoreflect.Value) { |
383 lazyInit() |
383 lazyInit() |
384 m := v.Message() |
384 m := v.Message() |
385 if m.Descriptor() != messageType.Descriptor() { |
385 if m.Descriptor() != messageType.Descriptor() { |
386 if got, want := m.Descriptor().FullName(), messageType.Descriptor().FullName(); got != want { |
386 if got, want := m.Descriptor().FullName(), messageType.Descriptor().FullName(); got != want { |
387 panic(fmt.Sprintf("field %v has mismatching message descriptor: got %v, want %v", fd.FullName(), got, want)) |
387 panic(fmt.Sprintf("field %v has mismatching message descriptor: got %v, want %v", fd.FullName(), got, want)) |
388 } |
388 } |
389 panic(fmt.Sprintf("field %v has mismatching message descriptor: %v", fd.FullName(), m.Descriptor().FullName())) |
389 panic(fmt.Sprintf("field %v has mismatching message descriptor: %v", fd.FullName(), m.Descriptor().FullName())) |
390 } |
390 } |
391 p.Apply(weakOffset).WeakFields().set(num, m.Interface()) |
391 p.Apply(weakOffset).WeakFields().set(num, m.Interface()) |
392 }, |
392 }, |
393 mutable: func(p pointer) pref.Value { |
393 mutable: func(p pointer) protoreflect.Value { |
394 lazyInit() |
394 lazyInit() |
395 fs := p.Apply(weakOffset).WeakFields() |
395 fs := p.Apply(weakOffset).WeakFields() |
396 m, ok := fs.get(num) |
396 m, ok := fs.get(num) |
397 if !ok { |
397 if !ok { |
398 m = messageType.New().Interface() |
398 m = messageType.New().Interface() |
399 fs.set(num, m) |
399 fs.set(num, m) |
400 } |
400 } |
401 return pref.ValueOfMessage(m.ProtoReflect()) |
401 return protoreflect.ValueOfMessage(m.ProtoReflect()) |
402 }, |
402 }, |
403 newMessage: func() pref.Message { |
403 newMessage: func() protoreflect.Message { |
404 lazyInit() |
404 lazyInit() |
405 return messageType.New() |
405 return messageType.New() |
406 }, |
406 }, |
407 newField: func() pref.Value { |
407 newField: func() protoreflect.Value { |
408 lazyInit() |
408 lazyInit() |
409 return pref.ValueOfMessage(messageType.New()) |
409 return protoreflect.ValueOfMessage(messageType.New()) |
410 }, |
410 }, |
411 } |
411 } |
412 } |
412 } |
413 |
413 |
414 func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { |
414 func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { |
415 ft := fs.Type |
415 ft := fs.Type |
416 conv := NewConverter(ft, fd) |
416 conv := NewConverter(ft, fd) |
417 |
417 |
418 // TODO: Implement unsafe fast path? |
418 // TODO: Implement unsafe fast path? |
419 fieldOffset := offsetOf(fs, x) |
419 fieldOffset := offsetOf(fs, x) |
431 }, |
431 }, |
432 clear: func(p pointer) { |
432 clear: func(p pointer) { |
433 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
433 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
434 rv.Set(reflect.Zero(rv.Type())) |
434 rv.Set(reflect.Zero(rv.Type())) |
435 }, |
435 }, |
436 get: func(p pointer) pref.Value { |
436 get: func(p pointer) protoreflect.Value { |
437 if p.IsNil() { |
437 if p.IsNil() { |
438 return conv.Zero() |
438 return conv.Zero() |
439 } |
439 } |
440 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
440 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
441 return conv.PBValueOf(rv) |
441 return conv.PBValueOf(rv) |
442 }, |
442 }, |
443 set: func(p pointer, v pref.Value) { |
443 set: func(p pointer, v protoreflect.Value) { |
444 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
444 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
445 rv.Set(conv.GoValueOf(v)) |
445 rv.Set(conv.GoValueOf(v)) |
446 if fs.Type.Kind() == reflect.Ptr && rv.IsNil() { |
446 if fs.Type.Kind() == reflect.Ptr && rv.IsNil() { |
447 panic(fmt.Sprintf("field %v has invalid nil pointer", fd.FullName())) |
447 panic(fmt.Sprintf("field %v has invalid nil pointer", fd.FullName())) |
448 } |
448 } |
449 }, |
449 }, |
450 mutable: func(p pointer) pref.Value { |
450 mutable: func(p pointer) protoreflect.Value { |
451 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
451 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
452 if fs.Type.Kind() == reflect.Ptr && rv.IsNil() { |
452 if fs.Type.Kind() == reflect.Ptr && rv.IsNil() { |
453 rv.Set(conv.GoValueOf(conv.New())) |
453 rv.Set(conv.GoValueOf(conv.New())) |
454 } |
454 } |
455 return conv.PBValueOf(rv) |
455 return conv.PBValueOf(rv) |
456 }, |
456 }, |
457 newMessage: func() pref.Message { |
457 newMessage: func() protoreflect.Message { |
458 return conv.New().Message() |
458 return conv.New().Message() |
459 }, |
459 }, |
460 newField: func() pref.Value { |
460 newField: func() protoreflect.Value { |
461 return conv.New() |
461 return conv.New() |
462 }, |
462 }, |
463 } |
463 } |
464 } |
464 } |
465 |
465 |
466 type oneofInfo struct { |
466 type oneofInfo struct { |
467 oneofDesc pref.OneofDescriptor |
467 oneofDesc protoreflect.OneofDescriptor |
468 which func(pointer) pref.FieldNumber |
468 which func(pointer) protoreflect.FieldNumber |
469 } |
469 } |
470 |
470 |
471 func makeOneofInfo(od pref.OneofDescriptor, si structInfo, x exporter) *oneofInfo { |
471 func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) *oneofInfo { |
472 oi := &oneofInfo{oneofDesc: od} |
472 oi := &oneofInfo{oneofDesc: od} |
473 if od.IsSynthetic() { |
473 if od.IsSynthetic() { |
474 fs := si.fieldsByNumber[od.Fields().Get(0).Number()] |
474 fs := si.fieldsByNumber[od.Fields().Get(0).Number()] |
475 fieldOffset := offsetOf(fs, x) |
475 fieldOffset := offsetOf(fs, x) |
476 oi.which = func(p pointer) pref.FieldNumber { |
476 oi.which = func(p pointer) protoreflect.FieldNumber { |
477 if p.IsNil() { |
477 if p.IsNil() { |
478 return 0 |
478 return 0 |
479 } |
479 } |
480 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
480 rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() |
481 if rv.IsNil() { // valid on either *T or []byte |
481 if rv.IsNil() { // valid on either *T or []byte |