14 ptag "google.golang.org/protobuf/internal/encoding/tag" |
14 ptag "google.golang.org/protobuf/internal/encoding/tag" |
15 "google.golang.org/protobuf/internal/errors" |
15 "google.golang.org/protobuf/internal/errors" |
16 "google.golang.org/protobuf/internal/filedesc" |
16 "google.golang.org/protobuf/internal/filedesc" |
17 "google.golang.org/protobuf/internal/strs" |
17 "google.golang.org/protobuf/internal/strs" |
18 "google.golang.org/protobuf/reflect/protoreflect" |
18 "google.golang.org/protobuf/reflect/protoreflect" |
19 pref "google.golang.org/protobuf/reflect/protoreflect" |
|
20 "google.golang.org/protobuf/runtime/protoiface" |
19 "google.golang.org/protobuf/runtime/protoiface" |
21 piface "google.golang.org/protobuf/runtime/protoiface" |
|
22 ) |
20 ) |
23 |
21 |
24 // legacyWrapMessage wraps v as a protoreflect.Message, |
22 // legacyWrapMessage wraps v as a protoreflect.Message, |
25 // where v must be a *struct kind and not implement the v2 API already. |
23 // where v must be a *struct kind and not implement the v2 API already. |
26 func legacyWrapMessage(v reflect.Value) pref.Message { |
24 func legacyWrapMessage(v reflect.Value) protoreflect.Message { |
27 t := v.Type() |
25 t := v.Type() |
28 if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct { |
26 if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct { |
29 return aberrantMessage{v: v} |
27 return aberrantMessage{v: v} |
30 } |
28 } |
31 mt := legacyLoadMessageInfo(t, "") |
29 mt := legacyLoadMessageInfo(t, "") |
87 |
85 |
88 // LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type, |
86 // LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type, |
89 // which should be a *struct kind and must not implement the v2 API already. |
87 // which should be a *struct kind and must not implement the v2 API already. |
90 // |
88 // |
91 // This is exported for testing purposes. |
89 // This is exported for testing purposes. |
92 func LegacyLoadMessageDesc(t reflect.Type) pref.MessageDescriptor { |
90 func LegacyLoadMessageDesc(t reflect.Type) protoreflect.MessageDescriptor { |
93 return legacyLoadMessageDesc(t, "") |
91 return legacyLoadMessageDesc(t, "") |
94 } |
92 } |
95 func legacyLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor { |
93 func legacyLoadMessageDesc(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor { |
96 // Fast-path: check if a MessageDescriptor is cached for this concrete type. |
94 // Fast-path: check if a MessageDescriptor is cached for this concrete type. |
97 if mi, ok := legacyMessageDescCache.Load(t); ok { |
95 if mi, ok := legacyMessageDescCache.Load(t); ok { |
98 return mi.(pref.MessageDescriptor) |
96 return mi.(protoreflect.MessageDescriptor) |
99 } |
97 } |
100 |
98 |
101 // Slow-path: initialize MessageDescriptor from the raw descriptor. |
99 // Slow-path: initialize MessageDescriptor from the raw descriptor. |
102 mv := reflect.Zero(t).Interface() |
100 mv := reflect.Zero(t).Interface() |
103 if _, ok := mv.(pref.ProtoMessage); ok { |
101 if _, ok := mv.(protoreflect.ProtoMessage); ok { |
104 panic(fmt.Sprintf("%v already implements proto.Message", t)) |
102 panic(fmt.Sprintf("%v already implements proto.Message", t)) |
105 } |
103 } |
106 mdV1, ok := mv.(messageV1) |
104 mdV1, ok := mv.(messageV1) |
107 if !ok { |
105 if !ok { |
108 return aberrantLoadMessageDesc(t, name) |
106 return aberrantLoadMessageDesc(t, name) |
162 // aberrantLoadMessageDesc returns an MessageDescriptor derived from the Go type, |
160 // aberrantLoadMessageDesc returns an MessageDescriptor derived from the Go type, |
163 // which must not implement protoreflect.ProtoMessage or messageV1. |
161 // which must not implement protoreflect.ProtoMessage or messageV1. |
164 // |
162 // |
165 // This is a best-effort derivation of the message descriptor using the protobuf |
163 // This is a best-effort derivation of the message descriptor using the protobuf |
166 // tags on the struct fields. |
164 // tags on the struct fields. |
167 func aberrantLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor { |
165 func aberrantLoadMessageDesc(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor { |
168 aberrantMessageDescLock.Lock() |
166 aberrantMessageDescLock.Lock() |
169 defer aberrantMessageDescLock.Unlock() |
167 defer aberrantMessageDescLock.Unlock() |
170 if aberrantMessageDescCache == nil { |
168 if aberrantMessageDescCache == nil { |
171 aberrantMessageDescCache = make(map[reflect.Type]protoreflect.MessageDescriptor) |
169 aberrantMessageDescCache = make(map[reflect.Type]protoreflect.MessageDescriptor) |
172 } |
170 } |
173 return aberrantLoadMessageDescReentrant(t, name) |
171 return aberrantLoadMessageDescReentrant(t, name) |
174 } |
172 } |
175 func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.MessageDescriptor { |
173 func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor { |
176 // Fast-path: check if an MessageDescriptor is cached for this concrete type. |
174 // Fast-path: check if an MessageDescriptor is cached for this concrete type. |
177 if md, ok := aberrantMessageDescCache[t]; ok { |
175 if md, ok := aberrantMessageDescCache[t]; ok { |
178 return md |
176 return md |
179 } |
177 } |
180 |
178 |
316 return opts.Interface() |
314 return opts.Interface() |
317 } |
315 } |
318 } |
316 } |
319 |
317 |
320 // Populate Enum and Message. |
318 // Populate Enum and Message. |
321 if fd.Enum() == nil && fd.Kind() == pref.EnumKind { |
319 if fd.Enum() == nil && fd.Kind() == protoreflect.EnumKind { |
322 switch v := reflect.Zero(t).Interface().(type) { |
320 switch v := reflect.Zero(t).Interface().(type) { |
323 case pref.Enum: |
321 case protoreflect.Enum: |
324 fd.L1.Enum = v.Descriptor() |
322 fd.L1.Enum = v.Descriptor() |
325 default: |
323 default: |
326 fd.L1.Enum = LegacyLoadEnumDesc(t) |
324 fd.L1.Enum = LegacyLoadEnumDesc(t) |
327 } |
325 } |
328 } |
326 } |
329 if fd.Message() == nil && (fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind) { |
327 if fd.Message() == nil && (fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind) { |
330 switch v := reflect.Zero(t).Interface().(type) { |
328 switch v := reflect.Zero(t).Interface().(type) { |
331 case pref.ProtoMessage: |
329 case protoreflect.ProtoMessage: |
332 fd.L1.Message = v.ProtoReflect().Descriptor() |
330 fd.L1.Message = v.ProtoReflect().Descriptor() |
333 case messageV1: |
331 case messageV1: |
334 fd.L1.Message = LegacyLoadMessageDesc(t) |
332 fd.L1.Message = LegacyLoadMessageDesc(t) |
335 default: |
333 default: |
336 if t.Kind() == reflect.Map { |
334 if t.Kind() == reflect.Map { |
337 n := len(md.L1.Messages.List) |
335 n := len(md.L1.Messages.List) |
338 md.L1.Messages.List = append(md.L1.Messages.List, filedesc.Message{L2: new(filedesc.MessageL2)}) |
336 md.L1.Messages.List = append(md.L1.Messages.List, filedesc.Message{L2: new(filedesc.MessageL2)}) |
339 md2 := &md.L1.Messages.List[n] |
337 md2 := &md.L1.Messages.List[n] |
340 md2.L0.FullName = md.FullName().Append(pref.Name(strs.MapEntryName(string(fd.Name())))) |
338 md2.L0.FullName = md.FullName().Append(protoreflect.Name(strs.MapEntryName(string(fd.Name())))) |
341 md2.L0.ParentFile = md.L0.ParentFile |
339 md2.L0.ParentFile = md.L0.ParentFile |
342 md2.L0.Parent = md |
340 md2.L0.Parent = md |
343 md2.L0.Index = n |
341 md2.L0.Index = n |
344 |
342 |
345 md2.L1.IsMapEntry = true |
343 md2.L1.IsMapEntry = true |
346 md2.L2.Options = func() pref.ProtoMessage { |
344 md2.L2.Options = func() protoreflect.ProtoMessage { |
347 opts := descopts.Message.ProtoReflect().New() |
345 opts := descopts.Message.ProtoReflect().New() |
348 opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true)) |
346 opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true)) |
349 return opts.Interface() |
347 return opts.Interface() |
350 } |
348 } |
351 |
349 |
381 // legacyMerger is the proto.Merger interface superseded by protoiface.Methoder. |
379 // legacyMerger is the proto.Merger interface superseded by protoiface.Methoder. |
382 type legacyMerger interface { |
380 type legacyMerger interface { |
383 Merge(protoiface.MessageV1) |
381 Merge(protoiface.MessageV1) |
384 } |
382 } |
385 |
383 |
386 var aberrantProtoMethods = &piface.Methods{ |
384 var aberrantProtoMethods = &protoiface.Methods{ |
387 Marshal: legacyMarshal, |
385 Marshal: legacyMarshal, |
388 Unmarshal: legacyUnmarshal, |
386 Unmarshal: legacyUnmarshal, |
389 Merge: legacyMerge, |
387 Merge: legacyMerge, |
390 |
388 |
391 // We have no way to tell whether the type's Marshal method |
389 // We have no way to tell whether the type's Marshal method |
392 // supports deterministic serialization or not, but this |
390 // supports deterministic serialization or not, but this |
393 // preserves the v1 implementation's behavior of always |
391 // preserves the v1 implementation's behavior of always |
394 // calling Marshal methods when present. |
392 // calling Marshal methods when present. |
395 Flags: piface.SupportMarshalDeterministic, |
393 Flags: protoiface.SupportMarshalDeterministic, |
396 } |
394 } |
397 |
395 |
398 func legacyMarshal(in piface.MarshalInput) (piface.MarshalOutput, error) { |
396 func legacyMarshal(in protoiface.MarshalInput) (protoiface.MarshalOutput, error) { |
399 v := in.Message.(unwrapper).protoUnwrap() |
397 v := in.Message.(unwrapper).protoUnwrap() |
400 marshaler, ok := v.(legacyMarshaler) |
398 marshaler, ok := v.(legacyMarshaler) |
401 if !ok { |
399 if !ok { |
402 return piface.MarshalOutput{}, errors.New("%T does not implement Marshal", v) |
400 return protoiface.MarshalOutput{}, errors.New("%T does not implement Marshal", v) |
403 } |
401 } |
404 out, err := marshaler.Marshal() |
402 out, err := marshaler.Marshal() |
405 if in.Buf != nil { |
403 if in.Buf != nil { |
406 out = append(in.Buf, out...) |
404 out = append(in.Buf, out...) |
407 } |
405 } |
408 return piface.MarshalOutput{ |
406 return protoiface.MarshalOutput{ |
409 Buf: out, |
407 Buf: out, |
410 }, err |
408 }, err |
411 } |
409 } |
412 |
410 |
413 func legacyUnmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutput, error) { |
411 func legacyUnmarshal(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { |
414 v := in.Message.(unwrapper).protoUnwrap() |
412 v := in.Message.(unwrapper).protoUnwrap() |
415 unmarshaler, ok := v.(legacyUnmarshaler) |
413 unmarshaler, ok := v.(legacyUnmarshaler) |
416 if !ok { |
414 if !ok { |
417 return piface.UnmarshalOutput{}, errors.New("%T does not implement Unmarshal", v) |
415 return protoiface.UnmarshalOutput{}, errors.New("%T does not implement Unmarshal", v) |
418 } |
416 } |
419 return piface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf) |
417 return protoiface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf) |
420 } |
418 } |
421 |
419 |
422 func legacyMerge(in piface.MergeInput) piface.MergeOutput { |
420 func legacyMerge(in protoiface.MergeInput) protoiface.MergeOutput { |
423 // Check whether this supports the legacy merger. |
421 // Check whether this supports the legacy merger. |
424 dstv := in.Destination.(unwrapper).protoUnwrap() |
422 dstv := in.Destination.(unwrapper).protoUnwrap() |
425 merger, ok := dstv.(legacyMerger) |
423 merger, ok := dstv.(legacyMerger) |
426 if ok { |
424 if ok { |
427 merger.Merge(Export{}.ProtoMessageV1Of(in.Source)) |
425 merger.Merge(Export{}.ProtoMessageV1Of(in.Source)) |
428 return piface.MergeOutput{Flags: piface.MergeComplete} |
426 return protoiface.MergeOutput{Flags: protoiface.MergeComplete} |
429 } |
427 } |
430 |
428 |
431 // If legacy merger is unavailable, implement merge in terms of |
429 // If legacy merger is unavailable, implement merge in terms of |
432 // a marshal and unmarshal operation. |
430 // a marshal and unmarshal operation. |
433 srcv := in.Source.(unwrapper).protoUnwrap() |
431 srcv := in.Source.(unwrapper).protoUnwrap() |
434 marshaler, ok := srcv.(legacyMarshaler) |
432 marshaler, ok := srcv.(legacyMarshaler) |
435 if !ok { |
433 if !ok { |
436 return piface.MergeOutput{} |
434 return protoiface.MergeOutput{} |
437 } |
435 } |
438 dstv = in.Destination.(unwrapper).protoUnwrap() |
436 dstv = in.Destination.(unwrapper).protoUnwrap() |
439 unmarshaler, ok := dstv.(legacyUnmarshaler) |
437 unmarshaler, ok := dstv.(legacyUnmarshaler) |
440 if !ok { |
438 if !ok { |
441 return piface.MergeOutput{} |
439 return protoiface.MergeOutput{} |
442 } |
440 } |
443 if !in.Source.IsValid() { |
441 if !in.Source.IsValid() { |
444 // Legacy Marshal methods may not function on nil messages. |
442 // Legacy Marshal methods may not function on nil messages. |
445 // Check for a typed nil source only after we confirm that |
443 // Check for a typed nil source only after we confirm that |
446 // legacy Marshal/Unmarshal methods are present, for |
444 // legacy Marshal/Unmarshal methods are present, for |
447 // consistency. |
445 // consistency. |
448 return piface.MergeOutput{Flags: piface.MergeComplete} |
446 return protoiface.MergeOutput{Flags: protoiface.MergeComplete} |
449 } |
447 } |
450 b, err := marshaler.Marshal() |
448 b, err := marshaler.Marshal() |
451 if err != nil { |
449 if err != nil { |
452 return piface.MergeOutput{} |
450 return protoiface.MergeOutput{} |
453 } |
451 } |
454 err = unmarshaler.Unmarshal(b) |
452 err = unmarshaler.Unmarshal(b) |
455 if err != nil { |
453 if err != nil { |
456 return piface.MergeOutput{} |
454 return protoiface.MergeOutput{} |
457 } |
455 } |
458 return piface.MergeOutput{Flags: piface.MergeComplete} |
456 return protoiface.MergeOutput{Flags: protoiface.MergeComplete} |
459 } |
457 } |
460 |
458 |
461 // aberrantMessageType implements MessageType for all types other than pointer-to-struct. |
459 // aberrantMessageType implements MessageType for all types other than pointer-to-struct. |
462 type aberrantMessageType struct { |
460 type aberrantMessageType struct { |
463 t reflect.Type |
461 t reflect.Type |
464 } |
462 } |
465 |
463 |
466 func (mt aberrantMessageType) New() pref.Message { |
464 func (mt aberrantMessageType) New() protoreflect.Message { |
467 if mt.t.Kind() == reflect.Ptr { |
465 if mt.t.Kind() == reflect.Ptr { |
468 return aberrantMessage{reflect.New(mt.t.Elem())} |
466 return aberrantMessage{reflect.New(mt.t.Elem())} |
469 } |
467 } |
470 return aberrantMessage{reflect.Zero(mt.t)} |
468 return aberrantMessage{reflect.Zero(mt.t)} |
471 } |
469 } |
472 func (mt aberrantMessageType) Zero() pref.Message { |
470 func (mt aberrantMessageType) Zero() protoreflect.Message { |
473 return aberrantMessage{reflect.Zero(mt.t)} |
471 return aberrantMessage{reflect.Zero(mt.t)} |
474 } |
472 } |
475 func (mt aberrantMessageType) GoType() reflect.Type { |
473 func (mt aberrantMessageType) GoType() reflect.Type { |
476 return mt.t |
474 return mt.t |
477 } |
475 } |
478 func (mt aberrantMessageType) Descriptor() pref.MessageDescriptor { |
476 func (mt aberrantMessageType) Descriptor() protoreflect.MessageDescriptor { |
479 return LegacyLoadMessageDesc(mt.t) |
477 return LegacyLoadMessageDesc(mt.t) |
480 } |
478 } |
481 |
479 |
482 // aberrantMessage implements Message for all types other than pointer-to-struct. |
480 // aberrantMessage implements Message for all types other than pointer-to-struct. |
483 // |
481 // |
497 if m.v.Kind() == reflect.Ptr && !m.v.IsNil() { |
495 if m.v.Kind() == reflect.Ptr && !m.v.IsNil() { |
498 m.v.Elem().Set(reflect.Zero(m.v.Type().Elem())) |
496 m.v.Elem().Set(reflect.Zero(m.v.Type().Elem())) |
499 } |
497 } |
500 } |
498 } |
501 |
499 |
502 func (m aberrantMessage) ProtoReflect() pref.Message { |
500 func (m aberrantMessage) ProtoReflect() protoreflect.Message { |
503 return m |
501 return m |
504 } |
502 } |
505 |
503 |
506 func (m aberrantMessage) Descriptor() pref.MessageDescriptor { |
504 func (m aberrantMessage) Descriptor() protoreflect.MessageDescriptor { |
507 return LegacyLoadMessageDesc(m.v.Type()) |
505 return LegacyLoadMessageDesc(m.v.Type()) |
508 } |
506 } |
509 func (m aberrantMessage) Type() pref.MessageType { |
507 func (m aberrantMessage) Type() protoreflect.MessageType { |
510 return aberrantMessageType{m.v.Type()} |
508 return aberrantMessageType{m.v.Type()} |
511 } |
509 } |
512 func (m aberrantMessage) New() pref.Message { |
510 func (m aberrantMessage) New() protoreflect.Message { |
513 if m.v.Type().Kind() == reflect.Ptr { |
511 if m.v.Type().Kind() == reflect.Ptr { |
514 return aberrantMessage{reflect.New(m.v.Type().Elem())} |
512 return aberrantMessage{reflect.New(m.v.Type().Elem())} |
515 } |
513 } |
516 return aberrantMessage{reflect.Zero(m.v.Type())} |
514 return aberrantMessage{reflect.Zero(m.v.Type())} |
517 } |
515 } |
518 func (m aberrantMessage) Interface() pref.ProtoMessage { |
516 func (m aberrantMessage) Interface() protoreflect.ProtoMessage { |
519 return m |
517 return m |
520 } |
518 } |
521 func (m aberrantMessage) Range(f func(pref.FieldDescriptor, pref.Value) bool) { |
519 func (m aberrantMessage) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { |
522 return |
520 return |
523 } |
521 } |
524 func (m aberrantMessage) Has(pref.FieldDescriptor) bool { |
522 func (m aberrantMessage) Has(protoreflect.FieldDescriptor) bool { |
525 return false |
523 return false |
526 } |
524 } |
527 func (m aberrantMessage) Clear(pref.FieldDescriptor) { |
525 func (m aberrantMessage) Clear(protoreflect.FieldDescriptor) { |
528 panic("invalid Message.Clear on " + string(m.Descriptor().FullName())) |
526 panic("invalid Message.Clear on " + string(m.Descriptor().FullName())) |
529 } |
527 } |
530 func (m aberrantMessage) Get(fd pref.FieldDescriptor) pref.Value { |
528 func (m aberrantMessage) Get(fd protoreflect.FieldDescriptor) protoreflect.Value { |
531 if fd.Default().IsValid() { |
529 if fd.Default().IsValid() { |
532 return fd.Default() |
530 return fd.Default() |
533 } |
531 } |
534 panic("invalid Message.Get on " + string(m.Descriptor().FullName())) |
532 panic("invalid Message.Get on " + string(m.Descriptor().FullName())) |
535 } |
533 } |
536 func (m aberrantMessage) Set(pref.FieldDescriptor, pref.Value) { |
534 func (m aberrantMessage) Set(protoreflect.FieldDescriptor, protoreflect.Value) { |
537 panic("invalid Message.Set on " + string(m.Descriptor().FullName())) |
535 panic("invalid Message.Set on " + string(m.Descriptor().FullName())) |
538 } |
536 } |
539 func (m aberrantMessage) Mutable(pref.FieldDescriptor) pref.Value { |
537 func (m aberrantMessage) Mutable(protoreflect.FieldDescriptor) protoreflect.Value { |
540 panic("invalid Message.Mutable on " + string(m.Descriptor().FullName())) |
538 panic("invalid Message.Mutable on " + string(m.Descriptor().FullName())) |
541 } |
539 } |
542 func (m aberrantMessage) NewField(pref.FieldDescriptor) pref.Value { |
540 func (m aberrantMessage) NewField(protoreflect.FieldDescriptor) protoreflect.Value { |
543 panic("invalid Message.NewField on " + string(m.Descriptor().FullName())) |
541 panic("invalid Message.NewField on " + string(m.Descriptor().FullName())) |
544 } |
542 } |
545 func (m aberrantMessage) WhichOneof(pref.OneofDescriptor) pref.FieldDescriptor { |
543 func (m aberrantMessage) WhichOneof(protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { |
546 panic("invalid Message.WhichOneof descriptor on " + string(m.Descriptor().FullName())) |
544 panic("invalid Message.WhichOneof descriptor on " + string(m.Descriptor().FullName())) |
547 } |
545 } |
548 func (m aberrantMessage) GetUnknown() pref.RawFields { |
546 func (m aberrantMessage) GetUnknown() protoreflect.RawFields { |
549 return nil |
547 return nil |
550 } |
548 } |
551 func (m aberrantMessage) SetUnknown(pref.RawFields) { |
549 func (m aberrantMessage) SetUnknown(protoreflect.RawFields) { |
552 // SetUnknown discards its input on messages which don't support unknown field storage. |
550 // SetUnknown discards its input on messages which don't support unknown field storage. |
553 } |
551 } |
554 func (m aberrantMessage) IsValid() bool { |
552 func (m aberrantMessage) IsValid() bool { |
555 if m.v.Kind() == reflect.Ptr { |
553 if m.v.Kind() == reflect.Ptr { |
556 return !m.v.IsNil() |
554 return !m.v.IsNil() |
557 } |
555 } |
558 return false |
556 return false |
559 } |
557 } |
560 func (m aberrantMessage) ProtoMethods() *piface.Methods { |
558 func (m aberrantMessage) ProtoMethods() *protoiface.Methods { |
561 return aberrantProtoMethods |
559 return aberrantProtoMethods |
562 } |
560 } |
563 func (m aberrantMessage) protoUnwrap() interface{} { |
561 func (m aberrantMessage) protoUnwrap() interface{} { |
564 return m.v.Interface() |
562 return m.v.Interface() |
565 } |
563 } |