legacy_test.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. // Copyright 2018 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. package impl_test
  5. import (
  6. "bytes"
  7. "math"
  8. "reflect"
  9. "testing"
  10. cmp "github.com/google/go-cmp/cmp"
  11. cmpopts "github.com/google/go-cmp/cmp/cmpopts"
  12. pack "google.golang.org/protobuf/internal/encoding/pack"
  13. pimpl "google.golang.org/protobuf/internal/impl"
  14. plegacy "google.golang.org/protobuf/internal/legacy"
  15. pragma "google.golang.org/protobuf/internal/pragma"
  16. ptype "google.golang.org/protobuf/internal/prototype"
  17. scalar "google.golang.org/protobuf/internal/scalar"
  18. pref "google.golang.org/protobuf/reflect/protoreflect"
  19. preg "google.golang.org/protobuf/reflect/protoregistry"
  20. piface "google.golang.org/protobuf/runtime/protoiface"
  21. proto2_20180125 "google.golang.org/protobuf/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152"
  22. )
  23. type legacyTestMessage struct {
  24. XXX_unrecognized []byte
  25. XXX_InternalExtensions map[int32]pimpl.ExtensionFieldV1
  26. }
  27. func (*legacyTestMessage) Reset() {}
  28. func (*legacyTestMessage) String() string { return "" }
  29. func (*legacyTestMessage) ProtoMessage() {}
  30. func (*legacyTestMessage) ExtensionRangeArray() []piface.ExtensionRangeV1 {
  31. return []piface.ExtensionRangeV1{{Start: 10, End: 20}, {Start: 40, End: 80}, {Start: 10000, End: 20000}}
  32. }
  33. func init() {
  34. mt := pimpl.Export{}.MessageTypeOf(&legacyTestMessage{})
  35. preg.GlobalTypes.Register(mt)
  36. }
  37. func TestLegacyUnknown(t *testing.T) {
  38. rawOf := func(toks ...pack.Token) pref.RawFields {
  39. return pref.RawFields(pack.Message(toks).Marshal())
  40. }
  41. raw1 := rawOf(pack.Tag{1, pack.BytesType}, pack.Bytes("1")) // 0a0131
  42. raw1a := rawOf(pack.Tag{1, pack.VarintType}, pack.Svarint(-4321)) // 08c143
  43. raw1b := rawOf(pack.Tag{1, pack.Fixed32Type}, pack.Uint32(0xdeadbeef)) // 0defbeadde
  44. raw1c := rawOf(pack.Tag{1, pack.Fixed64Type}, pack.Float64(math.Pi)) // 09182d4454fb210940
  45. raw2a := rawOf(pack.Tag{2, pack.BytesType}, pack.String("hello, world!")) // 120d68656c6c6f2c20776f726c6421
  46. raw2b := rawOf(pack.Tag{2, pack.VarintType}, pack.Uvarint(1234)) // 10d209
  47. raw3a := rawOf(pack.Tag{3, pack.StartGroupType}, pack.Tag{3, pack.EndGroupType}) // 1b1c
  48. raw3b := rawOf(pack.Tag{3, pack.BytesType}, pack.Bytes("\xde\xad\xbe\xef")) // 1a04deadbeef
  49. joinRaw := func(bs ...pref.RawFields) (out []byte) {
  50. for _, b := range bs {
  51. out = append(out, b...)
  52. }
  53. return out
  54. }
  55. m := new(legacyTestMessage)
  56. fs := pimpl.Export{}.MessageOf(m).UnknownFields()
  57. if got, want := fs.Len(), 0; got != want {
  58. t.Errorf("Len() = %d, want %d", got, want)
  59. }
  60. if got, want := m.XXX_unrecognized, joinRaw(); !bytes.Equal(got, want) {
  61. t.Errorf("data mismatch:\ngot: %x\nwant: %x", got, want)
  62. }
  63. fs.Set(1, raw1a)
  64. fs.Set(1, append(fs.Get(1), raw1b...))
  65. fs.Set(1, append(fs.Get(1), raw1c...))
  66. if got, want := fs.Len(), 1; got != want {
  67. t.Errorf("Len() = %d, want %d", got, want)
  68. }
  69. if got, want := m.XXX_unrecognized, joinRaw(raw1a, raw1b, raw1c); !bytes.Equal(got, want) {
  70. t.Errorf("data mismatch:\ngot: %x\nwant: %x", got, want)
  71. }
  72. fs.Set(2, raw2a)
  73. if got, want := fs.Len(), 2; got != want {
  74. t.Errorf("Len() = %d, want %d", got, want)
  75. }
  76. if got, want := m.XXX_unrecognized, joinRaw(raw1a, raw1b, raw1c, raw2a); !bytes.Equal(got, want) {
  77. t.Errorf("data mismatch:\ngot: %x\nwant: %x", got, want)
  78. }
  79. if got, want := fs.Get(1), joinRaw(raw1a, raw1b, raw1c); !bytes.Equal(got, want) {
  80. t.Errorf("Get(%d) = %x, want %x", 1, got, want)
  81. }
  82. if got, want := fs.Get(2), joinRaw(raw2a); !bytes.Equal(got, want) {
  83. t.Errorf("Get(%d) = %x, want %x", 2, got, want)
  84. }
  85. if got, want := fs.Get(3), joinRaw(); !bytes.Equal(got, want) {
  86. t.Errorf("Get(%d) = %x, want %x", 3, got, want)
  87. }
  88. fs.Set(1, nil) // remove field 1
  89. if got, want := fs.Len(), 1; got != want {
  90. t.Errorf("Len() = %d, want %d", got, want)
  91. }
  92. if got, want := m.XXX_unrecognized, joinRaw(raw2a); !bytes.Equal(got, want) {
  93. t.Errorf("data mismatch:\ngot: %x\nwant: %x", got, want)
  94. }
  95. // Simulate manual appending of raw field data.
  96. m.XXX_unrecognized = append(m.XXX_unrecognized, joinRaw(raw3a, raw1a, raw1b, raw2b, raw3b, raw1c)...)
  97. if got, want := fs.Len(), 3; got != want {
  98. t.Errorf("Len() = %d, want %d", got, want)
  99. }
  100. // Verify range iteration order.
  101. var i int
  102. want := []struct {
  103. num pref.FieldNumber
  104. raw pref.RawFields
  105. }{
  106. {2, joinRaw(raw2a, raw2b)},
  107. {3, joinRaw(raw3a, raw3b)},
  108. {1, joinRaw(raw1a, raw1b, raw1c)},
  109. }
  110. fs.Range(func(num pref.FieldNumber, raw pref.RawFields) bool {
  111. if i < len(want) {
  112. if num != want[i].num || !bytes.Equal(raw, want[i].raw) {
  113. t.Errorf("Range(%d) = (%d, %x), want (%d, %x)", i, num, raw, want[i].num, want[i].raw)
  114. }
  115. } else {
  116. t.Errorf("unexpected Range iteration: %d", i)
  117. }
  118. i++
  119. return true
  120. })
  121. fs.Set(2, fs.Get(2)) // moves field 2 to the end
  122. if got, want := fs.Len(), 3; got != want {
  123. t.Errorf("Len() = %d, want %d", got, want)
  124. }
  125. if got, want := m.XXX_unrecognized, joinRaw(raw3a, raw1a, raw1b, raw3b, raw1c, raw2a, raw2b); !bytes.Equal(got, want) {
  126. t.Errorf("data mismatch:\ngot: %x\nwant: %x", got, want)
  127. }
  128. fs.Set(1, nil) // remove field 1
  129. if got, want := fs.Len(), 2; got != want {
  130. t.Errorf("Len() = %d, want %d", got, want)
  131. }
  132. if got, want := m.XXX_unrecognized, joinRaw(raw3a, raw3b, raw2a, raw2b); !bytes.Equal(got, want) {
  133. t.Errorf("data mismatch:\ngot: %x\nwant: %x", got, want)
  134. }
  135. // Remove all fields.
  136. fs.Range(func(n pref.FieldNumber, b pref.RawFields) bool {
  137. fs.Set(n, nil)
  138. return true
  139. })
  140. if got, want := fs.Len(), 0; got != want {
  141. t.Errorf("Len() = %d, want %d", got, want)
  142. }
  143. if got, want := m.XXX_unrecognized, joinRaw(); !bytes.Equal(got, want) {
  144. t.Errorf("data mismatch:\ngot: %x\nwant: %x", got, want)
  145. }
  146. fs.Set(1, raw1)
  147. if got, want := fs.Len(), 1; got != want {
  148. t.Errorf("Len() = %d, want %d", got, want)
  149. }
  150. if got, want := m.XXX_unrecognized, joinRaw(raw1); !bytes.Equal(got, want) {
  151. t.Errorf("data mismatch:\ngot: %x\nwant: %x", got, want)
  152. }
  153. }
  154. func mustMakeExtensionType(x *ptype.StandaloneExtension, v interface{}) pref.ExtensionType {
  155. xd, err := ptype.NewExtension(x)
  156. if err != nil {
  157. panic(xd)
  158. }
  159. return plegacy.ExtensionTypeOf(xd, reflect.TypeOf(v))
  160. }
  161. var (
  162. parentDesc = pimpl.Export{}.MessageDescriptorOf((*legacyTestMessage)(nil))
  163. enumV1Desc = pimpl.Export{}.EnumDescriptorOf(proto2_20180125.Message_ChildEnum(0))
  164. messageV1Desc = pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message_ChildMessage)(nil))
  165. enumV2Desc = enumProto2Type.Descriptor()
  166. messageV2Desc = enumMessagesType.PBType.Descriptor()
  167. extensionTypes = []pref.ExtensionType{
  168. mustMakeExtensionType(&ptype.StandaloneExtension{
  169. FullName: "fizz.buzz.optional_bool",
  170. Number: 10000,
  171. Cardinality: pref.Optional,
  172. Kind: pref.BoolKind,
  173. Default: pref.ValueOf(true),
  174. ExtendedType: parentDesc,
  175. }, nil),
  176. mustMakeExtensionType(&ptype.StandaloneExtension{
  177. FullName: "fizz.buzz.optional_int32",
  178. Number: 10001,
  179. Cardinality: pref.Optional,
  180. Kind: pref.Int32Kind,
  181. Default: pref.ValueOf(int32(-12345)),
  182. ExtendedType: parentDesc,
  183. }, nil),
  184. mustMakeExtensionType(&ptype.StandaloneExtension{
  185. FullName: "fizz.buzz.optional_uint32",
  186. Number: 10002,
  187. Cardinality: pref.Optional,
  188. Kind: pref.Uint32Kind,
  189. Default: pref.ValueOf(uint32(3200)),
  190. ExtendedType: parentDesc,
  191. }, nil),
  192. mustMakeExtensionType(&ptype.StandaloneExtension{
  193. FullName: "fizz.buzz.optional_float",
  194. Number: 10003,
  195. Cardinality: pref.Optional,
  196. Kind: pref.FloatKind,
  197. Default: pref.ValueOf(float32(3.14159)),
  198. ExtendedType: parentDesc,
  199. }, nil),
  200. mustMakeExtensionType(&ptype.StandaloneExtension{
  201. FullName: "fizz.buzz.optional_string",
  202. Number: 10004,
  203. Cardinality: pref.Optional,
  204. Kind: pref.StringKind,
  205. Default: pref.ValueOf(string("hello, \"world!\"\n")),
  206. ExtendedType: parentDesc,
  207. }, nil),
  208. mustMakeExtensionType(&ptype.StandaloneExtension{
  209. FullName: "fizz.buzz.optional_bytes",
  210. Number: 10005,
  211. Cardinality: pref.Optional,
  212. Kind: pref.BytesKind,
  213. Default: pref.ValueOf([]byte("dead\xde\xad\xbe\xefbeef")),
  214. ExtendedType: parentDesc,
  215. }, nil),
  216. mustMakeExtensionType(&ptype.StandaloneExtension{
  217. FullName: "fizz.buzz.optional_enum_v1",
  218. Number: 10006,
  219. Cardinality: pref.Optional,
  220. Kind: pref.EnumKind,
  221. Default: pref.ValueOf(pref.EnumNumber(0)),
  222. EnumType: enumV1Desc,
  223. ExtendedType: parentDesc,
  224. }, proto2_20180125.Message_ChildEnum(0)),
  225. mustMakeExtensionType(&ptype.StandaloneExtension{
  226. FullName: "fizz.buzz.optional_message_v1",
  227. Number: 10007,
  228. Cardinality: pref.Optional,
  229. Kind: pref.MessageKind,
  230. MessageType: messageV1Desc,
  231. ExtendedType: parentDesc,
  232. }, (*proto2_20180125.Message_ChildMessage)(nil)),
  233. mustMakeExtensionType(&ptype.StandaloneExtension{
  234. FullName: "fizz.buzz.optional_enum_v2",
  235. Number: 10008,
  236. Cardinality: pref.Optional,
  237. Kind: pref.EnumKind,
  238. Default: pref.ValueOf(pref.EnumNumber(57005)),
  239. EnumType: enumV2Desc,
  240. ExtendedType: parentDesc,
  241. }, EnumProto2(0)),
  242. mustMakeExtensionType(&ptype.StandaloneExtension{
  243. FullName: "fizz.buzz.optional_message_v2",
  244. Number: 10009,
  245. Cardinality: pref.Optional,
  246. Kind: pref.MessageKind,
  247. MessageType: messageV2Desc,
  248. ExtendedType: parentDesc,
  249. }, (*EnumMessages)(nil)),
  250. mustMakeExtensionType(&ptype.StandaloneExtension{
  251. FullName: "fizz.buzz.repeated_bool",
  252. Number: 10010,
  253. Cardinality: pref.Repeated,
  254. Kind: pref.BoolKind,
  255. ExtendedType: parentDesc,
  256. }, nil),
  257. mustMakeExtensionType(&ptype.StandaloneExtension{
  258. FullName: "fizz.buzz.repeated_int32",
  259. Number: 10011,
  260. Cardinality: pref.Repeated,
  261. Kind: pref.Int32Kind,
  262. ExtendedType: parentDesc,
  263. }, nil),
  264. mustMakeExtensionType(&ptype.StandaloneExtension{
  265. FullName: "fizz.buzz.repeated_uint32",
  266. Number: 10012,
  267. Cardinality: pref.Repeated,
  268. Kind: pref.Uint32Kind,
  269. ExtendedType: parentDesc,
  270. }, nil),
  271. mustMakeExtensionType(&ptype.StandaloneExtension{
  272. FullName: "fizz.buzz.repeated_float",
  273. Number: 10013,
  274. Cardinality: pref.Repeated,
  275. Kind: pref.FloatKind,
  276. ExtendedType: parentDesc,
  277. }, nil),
  278. mustMakeExtensionType(&ptype.StandaloneExtension{
  279. FullName: "fizz.buzz.repeated_string",
  280. Number: 10014,
  281. Cardinality: pref.Repeated,
  282. Kind: pref.StringKind,
  283. ExtendedType: parentDesc,
  284. }, nil),
  285. mustMakeExtensionType(&ptype.StandaloneExtension{
  286. FullName: "fizz.buzz.repeated_bytes",
  287. Number: 10015,
  288. Cardinality: pref.Repeated,
  289. Kind: pref.BytesKind,
  290. ExtendedType: parentDesc,
  291. }, nil),
  292. mustMakeExtensionType(&ptype.StandaloneExtension{
  293. FullName: "fizz.buzz.repeated_enum_v1",
  294. Number: 10016,
  295. Cardinality: pref.Repeated,
  296. Kind: pref.EnumKind,
  297. EnumType: enumV1Desc,
  298. ExtendedType: parentDesc,
  299. }, proto2_20180125.Message_ChildEnum(0)),
  300. mustMakeExtensionType(&ptype.StandaloneExtension{
  301. FullName: "fizz.buzz.repeated_message_v1",
  302. Number: 10017,
  303. Cardinality: pref.Repeated,
  304. Kind: pref.MessageKind,
  305. MessageType: messageV1Desc,
  306. ExtendedType: parentDesc,
  307. }, (*proto2_20180125.Message_ChildMessage)(nil)),
  308. mustMakeExtensionType(&ptype.StandaloneExtension{
  309. FullName: "fizz.buzz.repeated_enum_v2",
  310. Number: 10018,
  311. Cardinality: pref.Repeated,
  312. Kind: pref.EnumKind,
  313. EnumType: enumV2Desc,
  314. ExtendedType: parentDesc,
  315. }, EnumProto2(0)),
  316. mustMakeExtensionType(&ptype.StandaloneExtension{
  317. FullName: "fizz.buzz.repeated_message_v2",
  318. Number: 10019,
  319. Cardinality: pref.Repeated,
  320. Kind: pref.MessageKind,
  321. MessageType: messageV2Desc,
  322. ExtendedType: parentDesc,
  323. }, (*EnumMessages)(nil)),
  324. }
  325. extensionDescs = []*piface.ExtensionDescV1{{
  326. ExtendedType: (*legacyTestMessage)(nil),
  327. ExtensionType: (*bool)(nil),
  328. Field: 10000,
  329. Name: "fizz.buzz.optional_bool",
  330. Tag: "varint,10000,opt,name=optional_bool,def=1",
  331. }, {
  332. ExtendedType: (*legacyTestMessage)(nil),
  333. ExtensionType: (*int32)(nil),
  334. Field: 10001,
  335. Name: "fizz.buzz.optional_int32",
  336. Tag: "varint,10001,opt,name=optional_int32,def=-12345",
  337. }, {
  338. ExtendedType: (*legacyTestMessage)(nil),
  339. ExtensionType: (*uint32)(nil),
  340. Field: 10002,
  341. Name: "fizz.buzz.optional_uint32",
  342. Tag: "varint,10002,opt,name=optional_uint32,def=3200",
  343. }, {
  344. ExtendedType: (*legacyTestMessage)(nil),
  345. ExtensionType: (*float32)(nil),
  346. Field: 10003,
  347. Name: "fizz.buzz.optional_float",
  348. Tag: "fixed32,10003,opt,name=optional_float,def=3.14159",
  349. }, {
  350. ExtendedType: (*legacyTestMessage)(nil),
  351. ExtensionType: (*string)(nil),
  352. Field: 10004,
  353. Name: "fizz.buzz.optional_string",
  354. Tag: "bytes,10004,opt,name=optional_string,def=hello, \"world!\"\n",
  355. }, {
  356. ExtendedType: (*legacyTestMessage)(nil),
  357. ExtensionType: ([]byte)(nil),
  358. Field: 10005,
  359. Name: "fizz.buzz.optional_bytes",
  360. Tag: "bytes,10005,opt,name=optional_bytes,def=dead\\336\\255\\276\\357beef",
  361. }, {
  362. ExtendedType: (*legacyTestMessage)(nil),
  363. ExtensionType: (*proto2_20180125.Message_ChildEnum)(nil),
  364. Field: 10006,
  365. Name: "fizz.buzz.optional_enum_v1",
  366. Tag: "varint,10006,opt,name=optional_enum_v1,enum=google.golang.org.proto2_20180125.Message_ChildEnum,def=0",
  367. }, {
  368. ExtendedType: (*legacyTestMessage)(nil),
  369. ExtensionType: (*proto2_20180125.Message_ChildMessage)(nil),
  370. Field: 10007,
  371. Name: "fizz.buzz.optional_message_v1",
  372. Tag: "bytes,10007,opt,name=optional_message_v1",
  373. }, {
  374. ExtendedType: (*legacyTestMessage)(nil),
  375. ExtensionType: (*EnumProto2)(nil),
  376. Field: 10008,
  377. Name: "fizz.buzz.optional_enum_v2",
  378. Tag: "varint,10008,opt,name=optional_enum_v2,enum=EnumProto2,def=57005",
  379. }, {
  380. ExtendedType: (*legacyTestMessage)(nil),
  381. ExtensionType: (*EnumMessages)(nil),
  382. Field: 10009,
  383. Name: "fizz.buzz.optional_message_v2",
  384. Tag: "bytes,10009,opt,name=optional_message_v2",
  385. }, {
  386. ExtendedType: (*legacyTestMessage)(nil),
  387. ExtensionType: ([]bool)(nil),
  388. Field: 10010,
  389. Name: "fizz.buzz.repeated_bool",
  390. Tag: "varint,10010,rep,name=repeated_bool",
  391. }, {
  392. ExtendedType: (*legacyTestMessage)(nil),
  393. ExtensionType: ([]int32)(nil),
  394. Field: 10011,
  395. Name: "fizz.buzz.repeated_int32",
  396. Tag: "varint,10011,rep,name=repeated_int32",
  397. }, {
  398. ExtendedType: (*legacyTestMessage)(nil),
  399. ExtensionType: ([]uint32)(nil),
  400. Field: 10012,
  401. Name: "fizz.buzz.repeated_uint32",
  402. Tag: "varint,10012,rep,name=repeated_uint32",
  403. }, {
  404. ExtendedType: (*legacyTestMessage)(nil),
  405. ExtensionType: ([]float32)(nil),
  406. Field: 10013,
  407. Name: "fizz.buzz.repeated_float",
  408. Tag: "fixed32,10013,rep,name=repeated_float",
  409. }, {
  410. ExtendedType: (*legacyTestMessage)(nil),
  411. ExtensionType: ([]string)(nil),
  412. Field: 10014,
  413. Name: "fizz.buzz.repeated_string",
  414. Tag: "bytes,10014,rep,name=repeated_string",
  415. }, {
  416. ExtendedType: (*legacyTestMessage)(nil),
  417. ExtensionType: ([][]byte)(nil),
  418. Field: 10015,
  419. Name: "fizz.buzz.repeated_bytes",
  420. Tag: "bytes,10015,rep,name=repeated_bytes",
  421. }, {
  422. ExtendedType: (*legacyTestMessage)(nil),
  423. ExtensionType: ([]proto2_20180125.Message_ChildEnum)(nil),
  424. Field: 10016,
  425. Name: "fizz.buzz.repeated_enum_v1",
  426. Tag: "varint,10016,rep,name=repeated_enum_v1,enum=google.golang.org.proto2_20180125.Message_ChildEnum",
  427. }, {
  428. ExtendedType: (*legacyTestMessage)(nil),
  429. ExtensionType: ([]*proto2_20180125.Message_ChildMessage)(nil),
  430. Field: 10017,
  431. Name: "fizz.buzz.repeated_message_v1",
  432. Tag: "bytes,10017,rep,name=repeated_message_v1",
  433. }, {
  434. ExtendedType: (*legacyTestMessage)(nil),
  435. ExtensionType: ([]EnumProto2)(nil),
  436. Field: 10018,
  437. Name: "fizz.buzz.repeated_enum_v2",
  438. Tag: "varint,10018,rep,name=repeated_enum_v2,enum=EnumProto2",
  439. }, {
  440. ExtendedType: (*legacyTestMessage)(nil),
  441. ExtensionType: ([]*EnumMessages)(nil),
  442. Field: 10019,
  443. Name: "fizz.buzz.repeated_message_v2",
  444. Tag: "bytes,10019,rep,name=repeated_message_v2",
  445. }}
  446. )
  447. func TestLegacyExtensions(t *testing.T) {
  448. opts := cmp.Options{cmp.Comparer(func(x, y *proto2_20180125.Message_ChildMessage) bool {
  449. return x == y // pointer compare messages for object identity
  450. })}
  451. m := new(legacyTestMessage)
  452. fs := pimpl.Export{}.MessageOf(m).KnownFields()
  453. ts := fs.ExtensionTypes()
  454. if n := fs.Len(); n != 0 {
  455. t.Errorf("KnownFields.Len() = %v, want 0", n)
  456. }
  457. if n := ts.Len(); n != 0 {
  458. t.Errorf("ExtensionFieldTypes.Len() = %v, want 0", n)
  459. }
  460. // Register all the extension types.
  461. for _, xt := range extensionTypes {
  462. ts.Register(xt)
  463. }
  464. // Check that getting the zero value returns the default value for scalars,
  465. // nil for singular messages, and an empty list for repeated fields.
  466. defaultValues := []interface{}{
  467. bool(true),
  468. int32(-12345),
  469. uint32(3200),
  470. float32(3.14159),
  471. string("hello, \"world!\"\n"),
  472. []byte("dead\xde\xad\xbe\xefbeef"),
  473. proto2_20180125.Message_ALPHA,
  474. nil,
  475. EnumProto2(0xdead),
  476. nil,
  477. new([]bool),
  478. new([]int32),
  479. new([]uint32),
  480. new([]float32),
  481. new([]string),
  482. new([][]byte),
  483. new([]proto2_20180125.Message_ChildEnum),
  484. new([]*proto2_20180125.Message_ChildMessage),
  485. new([]EnumProto2),
  486. new([]*EnumMessages),
  487. }
  488. for i, xt := range extensionTypes {
  489. var got interface{}
  490. num := xt.Descriptor().Number()
  491. if v := fs.Get(num); v.IsValid() {
  492. got = xt.InterfaceOf(v)
  493. }
  494. want := defaultValues[i]
  495. if diff := cmp.Diff(want, got, opts); diff != "" {
  496. t.Errorf("KnownFields.Get(%d) mismatch (-want +got):\n%v", num, diff)
  497. }
  498. }
  499. // All fields should be unpopulated.
  500. for _, xt := range extensionTypes {
  501. num := xt.Descriptor().Number()
  502. if fs.Has(num) {
  503. t.Errorf("KnownFields.Has(%d) = true, want false", num)
  504. }
  505. }
  506. // Set some values and append to values to the lists.
  507. m1a := &proto2_20180125.Message_ChildMessage{F1: scalar.String("m1a")}
  508. m1b := &proto2_20180125.Message_ChildMessage{F1: scalar.String("m2b")}
  509. m2a := &EnumMessages{EnumP2: EnumProto2(0x1b).Enum()}
  510. m2b := &EnumMessages{EnumP2: EnumProto2(0x2b).Enum()}
  511. setValues := []interface{}{
  512. bool(false),
  513. int32(-54321),
  514. uint32(6400),
  515. float32(2.71828),
  516. string("goodbye, \"world!\"\n"),
  517. []byte("live\xde\xad\xbe\xefchicken"),
  518. proto2_20180125.Message_CHARLIE,
  519. m1a,
  520. EnumProto2(0xbeef),
  521. m2a,
  522. &[]bool{true},
  523. &[]int32{-1000},
  524. &[]uint32{1280},
  525. &[]float32{1.6180},
  526. &[]string{"zero"},
  527. &[][]byte{[]byte("zero")},
  528. &[]proto2_20180125.Message_ChildEnum{proto2_20180125.Message_BRAVO},
  529. &[]*proto2_20180125.Message_ChildMessage{m1b},
  530. &[]EnumProto2{0xdead},
  531. &[]*EnumMessages{m2b},
  532. }
  533. for i, xt := range extensionTypes {
  534. fs.Set(xt.Descriptor().Number(), xt.ValueOf(setValues[i]))
  535. }
  536. for i, xt := range extensionTypes[len(extensionTypes)/2:] {
  537. v := extensionTypes[i].ValueOf(setValues[i])
  538. fs.Get(xt.Descriptor().Number()).List().Append(v)
  539. }
  540. // Get the values and check for equality.
  541. getValues := []interface{}{
  542. bool(false),
  543. int32(-54321),
  544. uint32(6400),
  545. float32(2.71828),
  546. string("goodbye, \"world!\"\n"),
  547. []byte("live\xde\xad\xbe\xefchicken"),
  548. proto2_20180125.Message_ChildEnum(proto2_20180125.Message_CHARLIE),
  549. m1a,
  550. EnumProto2(0xbeef),
  551. m2a,
  552. &[]bool{true, false},
  553. &[]int32{-1000, -54321},
  554. &[]uint32{1280, 6400},
  555. &[]float32{1.6180, 2.71828},
  556. &[]string{"zero", "goodbye, \"world!\"\n"},
  557. &[][]byte{[]byte("zero"), []byte("live\xde\xad\xbe\xefchicken")},
  558. &[]proto2_20180125.Message_ChildEnum{proto2_20180125.Message_BRAVO, proto2_20180125.Message_CHARLIE},
  559. &[]*proto2_20180125.Message_ChildMessage{m1b, m1a},
  560. &[]EnumProto2{0xdead, 0xbeef},
  561. &[]*EnumMessages{m2b, m2a},
  562. }
  563. for i, xt := range extensionTypes {
  564. num := xt.Descriptor().Number()
  565. got := xt.InterfaceOf(fs.Get(num))
  566. want := getValues[i]
  567. if diff := cmp.Diff(want, got, opts); diff != "" {
  568. t.Errorf("KnownFields.Get(%d) mismatch (-want +got):\n%v", num, diff)
  569. }
  570. }
  571. if n := fs.Len(); n != 20 {
  572. t.Errorf("KnownFields.Len() = %v, want 0", n)
  573. }
  574. if n := ts.Len(); n != 20 {
  575. t.Errorf("ExtensionFieldTypes.Len() = %v, want 20", n)
  576. }
  577. // Clear the field for all extension types.
  578. for _, xt := range extensionTypes[:len(extensionTypes)/2] {
  579. fs.Clear(xt.Descriptor().Number())
  580. }
  581. for i, xt := range extensionTypes[len(extensionTypes)/2:] {
  582. if i%2 == 0 {
  583. fs.Clear(xt.Descriptor().Number())
  584. } else {
  585. fs.Get(xt.Descriptor().Number()).List().Truncate(0)
  586. }
  587. }
  588. if n := fs.Len(); n != 0 {
  589. t.Errorf("KnownFields.Len() = %v, want 0", n)
  590. }
  591. if n := ts.Len(); n != 20 {
  592. t.Errorf("ExtensionFieldTypes.Len() = %v, want 20", n)
  593. }
  594. // De-register all extension types.
  595. for _, xt := range extensionTypes {
  596. ts.Remove(xt)
  597. }
  598. if n := fs.Len(); n != 0 {
  599. t.Errorf("KnownFields.Len() = %v, want 0", n)
  600. }
  601. if n := ts.Len(); n != 0 {
  602. t.Errorf("ExtensionFieldTypes.Len() = %v, want 0", n)
  603. }
  604. }
  605. func TestExtensionConvert(t *testing.T) {
  606. for i := range extensionTypes {
  607. i := i
  608. t.Run("", func(t *testing.T) {
  609. t.Parallel()
  610. wantType := extensionTypes[i]
  611. wantDesc := extensionDescs[i]
  612. gotType := plegacy.Export{}.ExtensionTypeFromDesc(wantDesc)
  613. gotDesc := plegacy.Export{}.ExtensionDescFromType(wantType)
  614. // TODO: We need a test package to compare descriptors.
  615. type list interface {
  616. Len() int
  617. pragma.DoNotImplement
  618. }
  619. opts := cmp.Options{
  620. cmp.Comparer(func(x, y reflect.Type) bool {
  621. return x == y
  622. }),
  623. cmp.Transformer("", func(x list) []interface{} {
  624. out := make([]interface{}, x.Len())
  625. v := reflect.ValueOf(x)
  626. for i := 0; i < x.Len(); i++ {
  627. m := v.MethodByName("Get")
  628. out[i] = m.Call([]reflect.Value{reflect.ValueOf(i)})[0].Interface()
  629. }
  630. return out
  631. }),
  632. // TODO: Add this when ExtensionType no longer implements
  633. // ExtensionDescriptor.
  634. /*
  635. cmp.Transformer("", func(x pref.ExtensionType) pref.ExtensionDescriptor {
  636. return x.Descriptor()
  637. }),
  638. */
  639. cmp.Transformer("", func(x pref.Descriptor) map[string]interface{} {
  640. out := make(map[string]interface{})
  641. v := reflect.ValueOf(x)
  642. for i := 0; i < v.NumMethod(); i++ {
  643. name := v.Type().Method(i).Name
  644. if m := v.Method(i); m.Type().NumIn() == 0 && m.Type().NumOut() == 1 {
  645. switch name {
  646. case "New":
  647. // Ignore New since it a constructor.
  648. case "Options":
  649. // Ignore descriptor options since protos are not cmperable.
  650. case "ContainingOneof", "ContainingMessage", "Enum", "Message":
  651. // Avoid descending into a dependency to avoid a cycle.
  652. // Just record the full name if available.
  653. //
  654. // TODO: Cycle support in cmp would be useful here.
  655. v := m.Call(nil)[0]
  656. if !v.IsNil() {
  657. out[name] = v.Interface().(pref.Descriptor).FullName()
  658. }
  659. case "Oneof", "Extendee":
  660. // TODO: Remove this.
  661. default:
  662. out[name] = m.Call(nil)[0].Interface()
  663. }
  664. }
  665. }
  666. return out
  667. }),
  668. cmp.Transformer("", func(v pref.Value) interface{} {
  669. return v.Interface()
  670. }),
  671. }
  672. if diff := cmp.Diff(&wantType, &gotType, opts); diff != "" {
  673. t.Errorf("ExtensionType mismatch (-want, +got):\n%v", diff)
  674. }
  675. opts = cmp.Options{
  676. cmpopts.IgnoreFields(piface.ExtensionDescV1{}, "Type"),
  677. }
  678. if diff := cmp.Diff(wantDesc, gotDesc, opts); diff != "" {
  679. t.Errorf("ExtensionDesc mismatch (-want, +got):\n%v", diff)
  680. }
  681. })
  682. }
  683. }