methods_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright 2019 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // The protoreflect tag disables fast-path methods, including legacy ones.
  5. //go:build !protoreflect
  6. // +build !protoreflect
  7. package proto_test
  8. import (
  9. "bytes"
  10. "errors"
  11. "fmt"
  12. "testing"
  13. "google.golang.org/protobuf/internal/impl"
  14. "google.golang.org/protobuf/proto"
  15. "google.golang.org/protobuf/runtime/protoiface"
  16. legacypb "google.golang.org/protobuf/internal/testprotos/legacy"
  17. )
  18. type selfMarshaler struct {
  19. bytes []byte
  20. err error
  21. }
  22. func (m selfMarshaler) Reset() {}
  23. func (m selfMarshaler) ProtoMessage() {}
  24. func (m selfMarshaler) String() string {
  25. return fmt.Sprintf("selfMarshaler{bytes:%v, err:%v}", m.bytes, m.err)
  26. }
  27. func (m selfMarshaler) Marshal() ([]byte, error) {
  28. return m.bytes, m.err
  29. }
  30. func (m *selfMarshaler) Unmarshal(b []byte) error {
  31. m.bytes = b
  32. return m.err
  33. }
  34. func TestLegacyMarshalMethod(t *testing.T) {
  35. for _, test := range []selfMarshaler{
  36. {bytes: []byte("marshal")},
  37. {bytes: []byte("marshal"), err: errors.New("some error")},
  38. } {
  39. m := impl.Export{}.MessageOf(test).Interface()
  40. b, err := proto.Marshal(m)
  41. if err != test.err || !bytes.Equal(b, test.bytes) {
  42. t.Errorf("proto.Marshal(%v) = %v, %v; want %v, %v", test, b, err, test.bytes, test.err)
  43. }
  44. if gotSize, wantSize := proto.Size(m), len(test.bytes); gotSize != wantSize {
  45. t.Fatalf("proto.Size(%v) = %v, want %v", test, gotSize, wantSize)
  46. }
  47. prefix := []byte("prefix")
  48. want := append(prefix, test.bytes...)
  49. b, err = proto.MarshalOptions{}.MarshalAppend(prefix, m)
  50. if err != test.err || !bytes.Equal(b, want) {
  51. t.Errorf("MarshalAppend(%v, %v) = %v, %v; want %v, %v", prefix, test, b, err, test.bytes, test.err)
  52. }
  53. b, err = proto.MarshalOptions{
  54. Deterministic: true,
  55. }.MarshalAppend(nil, m)
  56. if err != test.err || !bytes.Equal(b, test.bytes) {
  57. t.Errorf("MarshalOptions{Deterministic:true}.MarshalAppend(nil, %v) = %v, %v; want %v, %v", test, b, err, test.bytes, test.err)
  58. }
  59. }
  60. }
  61. func TestLegacyUnmarshalMethod(t *testing.T) {
  62. sm := &selfMarshaler{}
  63. m := impl.Export{}.MessageOf(sm).Interface()
  64. want := []byte("unmarshal")
  65. if err := proto.Unmarshal(want, m); err != nil {
  66. t.Fatalf("proto.Unmarshal(selfMarshaler{}) = %v, want nil", err)
  67. }
  68. if !bytes.Equal(sm.bytes, want) {
  69. t.Fatalf("proto.Unmarshal(selfMarshaler{}): Marshal method not called")
  70. }
  71. }
  72. type descPanicSelfMarshaler struct{}
  73. const descPanicSelfMarshalerBytes = "bytes"
  74. func (m *descPanicSelfMarshaler) Reset() {}
  75. func (m *descPanicSelfMarshaler) ProtoMessage() {}
  76. func (m *descPanicSelfMarshaler) Descriptor() ([]byte, []int) { panic("Descriptor method panics") }
  77. func (m *descPanicSelfMarshaler) String() string { return "descPanicSelfMarshaler{}" }
  78. func (m *descPanicSelfMarshaler) Marshal() ([]byte, error) {
  79. return []byte(descPanicSelfMarshalerBytes), nil
  80. }
  81. func TestSelfMarshalerDescriptorPanics(t *testing.T) {
  82. m := &descPanicSelfMarshaler{}
  83. got, err := proto.Marshal(impl.Export{}.MessageOf(m).Interface())
  84. want := []byte(descPanicSelfMarshalerBytes)
  85. if err != nil || !bytes.Equal(got, want) {
  86. t.Fatalf("proto.Marshal(%v) = %v, %v; want %v, nil", m, got, err, want)
  87. }
  88. }
  89. type descSelfMarshaler struct {
  90. someField int // some non-generated field
  91. }
  92. const descSelfMarshalerBytes = "bytes"
  93. func (m *descSelfMarshaler) Reset() {}
  94. func (m *descSelfMarshaler) ProtoMessage() {}
  95. func (m *descSelfMarshaler) Descriptor() ([]byte, []int) {
  96. return ((*legacypb.Legacy)(nil)).GetF1().Descriptor()
  97. }
  98. func (m *descSelfMarshaler) String() string {
  99. return "descSelfMarshaler{}"
  100. }
  101. func (m *descSelfMarshaler) Marshal() ([]byte, error) {
  102. return []byte(descSelfMarshalerBytes), nil
  103. }
  104. func TestSelfMarshalerWithDescriptor(t *testing.T) {
  105. m := &descSelfMarshaler{}
  106. got, err := proto.Marshal(impl.Export{}.MessageOf(m).Interface())
  107. want := []byte(descSelfMarshalerBytes)
  108. if err != nil || !bytes.Equal(got, want) {
  109. t.Fatalf("proto.Marshal(%v) = %v, %v; want %v, nil", m, got, err, want)
  110. }
  111. }
  112. func TestDecodeFastCheckInitialized(t *testing.T) {
  113. for _, test := range testValidMessages {
  114. if !test.checkFastInit {
  115. continue
  116. }
  117. for _, message := range test.decodeTo {
  118. t.Run(fmt.Sprintf("%s (%T)", test.desc, message), func(t *testing.T) {
  119. m := message.ProtoReflect().New()
  120. opts := proto.UnmarshalOptions{
  121. AllowPartial: true,
  122. }
  123. out, err := opts.UnmarshalState(protoiface.UnmarshalInput{
  124. Buf: test.wire,
  125. Message: m,
  126. })
  127. if err != nil {
  128. t.Fatalf("Unmarshal error: %v", err)
  129. }
  130. if got, want := (out.Flags&protoiface.UnmarshalInitialized != 0), !test.partial; got != want {
  131. t.Errorf("out.Initialized = %v, want %v", got, want)
  132. }
  133. })
  134. }
  135. }
  136. }
  137. type selfMerger struct {
  138. src protoiface.MessageV1
  139. }
  140. func (*selfMerger) Reset() {}
  141. func (*selfMerger) ProtoMessage() {}
  142. func (*selfMerger) String() string { return "selfMerger{}" }
  143. func (m *selfMerger) Merge(src protoiface.MessageV1) {
  144. m.src = src
  145. }
  146. func TestLegacyMergeMethod(t *testing.T) {
  147. src := &selfMerger{}
  148. dst := &selfMerger{}
  149. proto.Merge(
  150. impl.Export{}.MessageOf(dst).Interface(),
  151. impl.Export{}.MessageOf(src).Interface(),
  152. )
  153. if got, want := dst.src, src; got != want {
  154. t.Errorf("Merge(dst, src): want dst.src = src, got %v", got)
  155. }
  156. if got := src.src; got != nil {
  157. t.Errorf("Merge(dst, src): want src.src = nil, got %v", got)
  158. }
  159. }