legacy_test.go 23 KB

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