decode_test.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404
  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 textpb_test
  5. import (
  6. "math"
  7. "testing"
  8. protoV1 "github.com/golang/protobuf/proto"
  9. "github.com/golang/protobuf/protoapi"
  10. anypb "github.com/golang/protobuf/ptypes/any"
  11. "github.com/golang/protobuf/v2/encoding/textpb"
  12. "github.com/golang/protobuf/v2/internal/legacy"
  13. "github.com/golang/protobuf/v2/internal/scalar"
  14. "github.com/golang/protobuf/v2/proto"
  15. preg "github.com/golang/protobuf/v2/reflect/protoregistry"
  16. // The legacy package must be imported prior to use of any legacy messages.
  17. // TODO: Remove this when protoV1 registers these hooks for you.
  18. _ "github.com/golang/protobuf/v2/internal/legacy"
  19. "github.com/golang/protobuf/v2/encoding/textpb/testprotos/pb2"
  20. "github.com/golang/protobuf/v2/encoding/textpb/testprotos/pb3"
  21. )
  22. func init() {
  23. // TODO: remove this when generated code registers to V2 global registry.
  24. registerExtension(pb2.E_OptExtBool)
  25. registerExtension(pb2.E_OptExtString)
  26. registerExtension(pb2.E_OptExtEnum)
  27. registerExtension(pb2.E_OptExtNested)
  28. registerExtension(pb2.E_RptExtFixed32)
  29. registerExtension(pb2.E_RptExtEnum)
  30. registerExtension(pb2.E_RptExtNested)
  31. registerExtension(pb2.E_ExtensionsContainer_OptExtBool)
  32. registerExtension(pb2.E_ExtensionsContainer_OptExtString)
  33. registerExtension(pb2.E_ExtensionsContainer_OptExtEnum)
  34. registerExtension(pb2.E_ExtensionsContainer_OptExtNested)
  35. registerExtension(pb2.E_ExtensionsContainer_RptExtString)
  36. registerExtension(pb2.E_ExtensionsContainer_RptExtEnum)
  37. registerExtension(pb2.E_ExtensionsContainer_RptExtNested)
  38. registerExtension(pb2.E_MessageSetExtension)
  39. registerExtension(pb2.E_MessageSetExtension_MessageSetExtension)
  40. registerExtension(pb2.E_MessageSetExtension_NotMessageSetExtension)
  41. registerExtension(pb2.E_MessageSetExtension_ExtNested)
  42. registerExtension(pb2.E_FakeMessageSetExtension_MessageSetExtension)
  43. }
  44. func registerExtension(xd *protoapi.ExtensionDesc) {
  45. xt := legacy.Export{}.ExtensionTypeFromDesc(xd)
  46. preg.GlobalTypes.Register(xt)
  47. }
  48. func TestUnmarshal(t *testing.T) {
  49. tests := []struct {
  50. desc string
  51. umo textpb.UnmarshalOptions
  52. inputMessage proto.Message
  53. inputText string
  54. wantMessage proto.Message
  55. wantErr bool
  56. }{{
  57. desc: "proto2 empty message",
  58. inputMessage: &pb2.Scalars{},
  59. wantMessage: &pb2.Scalars{},
  60. }, {
  61. desc: "proto2 optional scalar fields set to zero values",
  62. inputMessage: &pb2.Scalars{},
  63. inputText: `opt_bool: false
  64. opt_int32: 0
  65. opt_int64: 0
  66. opt_uint32: 0
  67. opt_uint64: 0
  68. opt_sint32: 0
  69. opt_sint64: 0
  70. opt_fixed32: 0
  71. opt_fixed64: 0
  72. opt_sfixed32: 0
  73. opt_sfixed64: 0
  74. opt_float: 0
  75. opt_double: 0
  76. opt_bytes: ""
  77. opt_string: ""
  78. `,
  79. wantMessage: &pb2.Scalars{
  80. OptBool: scalar.Bool(false),
  81. OptInt32: scalar.Int32(0),
  82. OptInt64: scalar.Int64(0),
  83. OptUint32: scalar.Uint32(0),
  84. OptUint64: scalar.Uint64(0),
  85. OptSint32: scalar.Int32(0),
  86. OptSint64: scalar.Int64(0),
  87. OptFixed32: scalar.Uint32(0),
  88. OptFixed64: scalar.Uint64(0),
  89. OptSfixed32: scalar.Int32(0),
  90. OptSfixed64: scalar.Int64(0),
  91. OptFloat: scalar.Float32(0),
  92. OptDouble: scalar.Float64(0),
  93. OptBytes: []byte{},
  94. OptString: scalar.String(""),
  95. },
  96. }, {
  97. desc: "proto3 scalar fields set to zero values",
  98. inputMessage: &pb3.Scalars{},
  99. inputText: `s_bool: false
  100. s_int32: 0
  101. s_int64: 0
  102. s_uint32: 0
  103. s_uint64: 0
  104. s_sint32: 0
  105. s_sint64: 0
  106. s_fixed32: 0
  107. s_fixed64: 0
  108. s_sfixed32: 0
  109. s_sfixed64: 0
  110. s_float: 0
  111. s_double: 0
  112. s_bytes: ""
  113. s_string: ""
  114. `,
  115. wantMessage: &pb3.Scalars{},
  116. }, {
  117. desc: "proto2 optional scalar fields",
  118. inputMessage: &pb2.Scalars{},
  119. inputText: `opt_bool: true
  120. opt_int32: 255
  121. opt_int64: 3735928559
  122. opt_uint32: 0xff
  123. opt_uint64: 0xdeadbeef
  124. opt_sint32: -1001
  125. opt_sint64: -0xffff
  126. opt_fixed64: 64
  127. opt_sfixed32: -32
  128. opt_float: 1.234
  129. opt_double: 1.23e+100
  130. opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
  131. opt_string: "谷歌"
  132. `,
  133. wantMessage: &pb2.Scalars{
  134. OptBool: scalar.Bool(true),
  135. OptInt32: scalar.Int32(0xff),
  136. OptInt64: scalar.Int64(0xdeadbeef),
  137. OptUint32: scalar.Uint32(0xff),
  138. OptUint64: scalar.Uint64(0xdeadbeef),
  139. OptSint32: scalar.Int32(-1001),
  140. OptSint64: scalar.Int64(-0xffff),
  141. OptFixed64: scalar.Uint64(64),
  142. OptSfixed32: scalar.Int32(-32),
  143. OptFloat: scalar.Float32(1.234),
  144. OptDouble: scalar.Float64(1.23e100),
  145. OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
  146. OptString: scalar.String("谷歌"),
  147. },
  148. }, {
  149. desc: "proto3 scalar fields",
  150. inputMessage: &pb3.Scalars{},
  151. inputText: `s_bool: true
  152. s_int32: 255
  153. s_int64: 3735928559
  154. s_uint32: 0xff
  155. s_uint64: 0xdeadbeef
  156. s_sint32: -1001
  157. s_sint64: -0xffff
  158. s_fixed64: 64
  159. s_sfixed32: -32
  160. s_float: 1.234
  161. s_double: 1.23e+100
  162. s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
  163. s_string: "谷歌"
  164. `,
  165. wantMessage: &pb3.Scalars{
  166. SBool: true,
  167. SInt32: 0xff,
  168. SInt64: 0xdeadbeef,
  169. SUint32: 0xff,
  170. SUint64: 0xdeadbeef,
  171. SSint32: -1001,
  172. SSint64: -0xffff,
  173. SFixed64: 64,
  174. SSfixed32: -32,
  175. SFloat: 1.234,
  176. SDouble: 1.23e100,
  177. SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
  178. SString: "谷歌",
  179. },
  180. }, {
  181. desc: "proto2 message contains unknown field",
  182. inputMessage: &pb2.Scalars{},
  183. inputText: "unknown_field: 123",
  184. wantErr: true,
  185. }, {
  186. desc: "proto3 message contains unknown field",
  187. inputMessage: &pb3.Scalars{},
  188. inputText: "unknown_field: 456",
  189. wantErr: true,
  190. }, {
  191. desc: "proto2 numeric key field",
  192. inputMessage: &pb2.Scalars{},
  193. inputText: "1: true",
  194. wantErr: true,
  195. }, {
  196. desc: "proto3 numeric key field",
  197. inputMessage: &pb3.Scalars{},
  198. inputText: "1: true",
  199. wantErr: true,
  200. }, {
  201. desc: "invalid bool value",
  202. inputMessage: &pb3.Scalars{},
  203. inputText: "s_bool: 123",
  204. wantErr: true,
  205. }, {
  206. desc: "invalid int32 value",
  207. inputMessage: &pb3.Scalars{},
  208. inputText: "s_int32: not_a_num",
  209. wantErr: true,
  210. }, {
  211. desc: "invalid int64 value",
  212. inputMessage: &pb3.Scalars{},
  213. inputText: "s_int64: 'not a num either'",
  214. wantErr: true,
  215. }, {
  216. desc: "invalid uint32 value",
  217. inputMessage: &pb3.Scalars{},
  218. inputText: "s_fixed32: -42",
  219. wantErr: true,
  220. }, {
  221. desc: "invalid uint64 value",
  222. inputMessage: &pb3.Scalars{},
  223. inputText: "s_uint64: -47",
  224. wantErr: true,
  225. }, {
  226. desc: "invalid sint32 value",
  227. inputMessage: &pb3.Scalars{},
  228. inputText: "s_sint32: '42'",
  229. wantErr: true,
  230. }, {
  231. desc: "invalid sint64 value",
  232. inputMessage: &pb3.Scalars{},
  233. inputText: "s_sint64: '-47'",
  234. wantErr: true,
  235. }, {
  236. desc: "invalid fixed32 value",
  237. inputMessage: &pb3.Scalars{},
  238. inputText: "s_fixed32: -42",
  239. wantErr: true,
  240. }, {
  241. desc: "invalid fixed64 value",
  242. inputMessage: &pb3.Scalars{},
  243. inputText: "s_fixed64: -42",
  244. wantErr: true,
  245. }, {
  246. desc: "invalid sfixed32 value",
  247. inputMessage: &pb3.Scalars{},
  248. inputText: "s_sfixed32: 'not valid'",
  249. wantErr: true,
  250. }, {
  251. desc: "invalid sfixed64 value",
  252. inputMessage: &pb3.Scalars{},
  253. inputText: "s_sfixed64: bad",
  254. wantErr: true,
  255. }, {
  256. desc: "float32 positive infinity",
  257. inputMessage: &pb3.Scalars{},
  258. inputText: "s_float: inf",
  259. wantMessage: &pb3.Scalars{
  260. SFloat: float32(math.Inf(1)),
  261. },
  262. }, {
  263. desc: "float32 negative infinity",
  264. inputMessage: &pb3.Scalars{},
  265. inputText: "s_float: -inf",
  266. wantMessage: &pb3.Scalars{
  267. SFloat: float32(math.Inf(-1)),
  268. },
  269. }, {
  270. desc: "float64 positive infinity",
  271. inputMessage: &pb3.Scalars{},
  272. inputText: "s_double: inf",
  273. wantMessage: &pb3.Scalars{
  274. SDouble: math.Inf(1),
  275. },
  276. }, {
  277. desc: "float64 negative infinity",
  278. inputMessage: &pb3.Scalars{},
  279. inputText: "s_double: -inf",
  280. wantMessage: &pb3.Scalars{
  281. SDouble: math.Inf(-1),
  282. },
  283. }, {
  284. desc: "invalid string value",
  285. inputMessage: &pb3.Scalars{},
  286. inputText: "s_string: invalid_string",
  287. wantErr: true,
  288. }, {
  289. desc: "proto2 bytes set to empty string",
  290. inputMessage: &pb2.Scalars{},
  291. inputText: "opt_bytes: ''",
  292. wantMessage: &pb2.Scalars{
  293. OptBytes: []byte(""),
  294. },
  295. }, {
  296. desc: "proto3 bytes set to empty string",
  297. inputMessage: &pb3.Scalars{},
  298. inputText: "s_bytes: ''",
  299. wantMessage: &pb3.Scalars{},
  300. }, {
  301. desc: "proto2 duplicate singular field",
  302. inputMessage: &pb2.Scalars{},
  303. inputText: `
  304. opt_bool: true
  305. opt_bool: false
  306. `,
  307. wantErr: true,
  308. }, {
  309. desc: "proto2 invalid singular field",
  310. inputMessage: &pb2.Scalars{},
  311. inputText: `
  312. opt_bool: [true, false]
  313. `,
  314. wantErr: true,
  315. }, {
  316. desc: "proto2 more duplicate singular field",
  317. inputMessage: &pb2.Scalars{},
  318. inputText: `
  319. opt_bool: true
  320. opt_string: "hello"
  321. opt_bool: false
  322. `,
  323. wantErr: true,
  324. }, {
  325. desc: "proto3 duplicate singular field",
  326. inputMessage: &pb3.Scalars{},
  327. inputText: `
  328. s_bool: false
  329. s_bool: true
  330. `,
  331. wantErr: true,
  332. }, {
  333. desc: "proto3 more duplicate singular field",
  334. inputMessage: &pb3.Scalars{},
  335. inputText: `
  336. s_bool: false
  337. s_string: ""
  338. s_bool: true
  339. `,
  340. wantErr: true,
  341. }, {
  342. desc: "proto2 enum",
  343. inputMessage: &pb2.Enums{},
  344. inputText: `
  345. opt_enum: FIRST
  346. opt_nested_enum: UNO
  347. `,
  348. wantMessage: &pb2.Enums{
  349. OptEnum: pb2.Enum_FIRST.Enum(),
  350. OptNestedEnum: pb2.Enums_UNO.Enum(),
  351. },
  352. }, {
  353. desc: "proto2 enum set to numeric values",
  354. inputMessage: &pb2.Enums{},
  355. inputText: `
  356. opt_enum: 1
  357. opt_nested_enum: 2
  358. `,
  359. wantMessage: &pb2.Enums{
  360. OptEnum: pb2.Enum_FIRST.Enum(),
  361. OptNestedEnum: pb2.Enums_DOS.Enum(),
  362. },
  363. }, {
  364. desc: "proto2 enum set to unnamed numeric values",
  365. inputMessage: &pb2.Enums{},
  366. inputText: `
  367. opt_enum: 101
  368. opt_nested_enum: -101
  369. `,
  370. wantMessage: &pb2.Enums{
  371. OptEnum: pb2Enum(101),
  372. OptNestedEnum: pb2Enums_NestedEnum(-101),
  373. },
  374. }, {
  375. desc: "proto2 enum set to invalid named",
  376. inputMessage: &pb2.Enums{},
  377. inputText: `
  378. opt_enum: UNNAMED
  379. opt_nested_enum: UNNAMED_TOO
  380. `,
  381. wantErr: true,
  382. }, {
  383. desc: "proto3 enum name value",
  384. inputMessage: &pb3.Enums{},
  385. inputText: `
  386. s_enum: ONE
  387. s_nested_enum: DIEZ
  388. `,
  389. wantMessage: &pb3.Enums{
  390. SEnum: pb3.Enum_ONE,
  391. SNestedEnum: pb3.Enums_DIEZ,
  392. },
  393. }, {
  394. desc: "proto3 enum numeric value",
  395. inputMessage: &pb3.Enums{},
  396. inputText: `
  397. s_enum: 2
  398. s_nested_enum: 1
  399. `,
  400. wantMessage: &pb3.Enums{
  401. SEnum: pb3.Enum_TWO,
  402. SNestedEnum: pb3.Enums_UNO,
  403. },
  404. }, {
  405. desc: "proto3 enum unnamed numeric value",
  406. inputMessage: &pb3.Enums{},
  407. inputText: `
  408. s_enum: 0x7fffffff
  409. s_nested_enum: -0x80000000
  410. `,
  411. wantMessage: &pb3.Enums{
  412. SEnum: 0x7fffffff,
  413. SNestedEnum: -0x80000000,
  414. },
  415. }, {
  416. desc: "proto2 nested empty messages",
  417. inputMessage: &pb2.Nests{},
  418. inputText: `
  419. opt_nested: {}
  420. OptGroup: {}
  421. `,
  422. wantMessage: &pb2.Nests{
  423. OptNested: &pb2.Nested{},
  424. Optgroup: &pb2.Nests_OptGroup{},
  425. },
  426. }, {
  427. desc: "proto2 nested messages",
  428. inputMessage: &pb2.Nests{},
  429. inputText: `
  430. opt_nested: {
  431. opt_string: "nested message"
  432. opt_nested: {
  433. opt_string: "another nested message"
  434. }
  435. }
  436. `,
  437. wantMessage: &pb2.Nests{
  438. OptNested: &pb2.Nested{
  439. OptString: scalar.String("nested message"),
  440. OptNested: &pb2.Nested{
  441. OptString: scalar.String("another nested message"),
  442. },
  443. },
  444. },
  445. }, {
  446. desc: "proto3 nested empty message",
  447. inputMessage: &pb3.Nests{},
  448. inputText: "s_nested: {}",
  449. wantMessage: &pb3.Nests{
  450. SNested: &pb3.Nested{},
  451. },
  452. }, {
  453. desc: "proto3 nested message",
  454. inputMessage: &pb3.Nests{},
  455. inputText: `
  456. s_nested: {
  457. s_string: "nested message"
  458. s_nested: {
  459. s_string: "another nested message"
  460. }
  461. }
  462. `,
  463. wantMessage: &pb3.Nests{
  464. SNested: &pb3.Nested{
  465. SString: "nested message",
  466. SNested: &pb3.Nested{
  467. SString: "another nested message",
  468. },
  469. },
  470. },
  471. }, {
  472. desc: "oneof field set to empty string",
  473. inputMessage: &pb2.Oneofs{},
  474. inputText: "str: ''",
  475. wantMessage: &pb2.Oneofs{
  476. Union: &pb2.Oneofs_Str{},
  477. },
  478. }, {
  479. desc: "oneof field set to string",
  480. inputMessage: &pb2.Oneofs{},
  481. inputText: "str: 'hello'",
  482. wantMessage: &pb2.Oneofs{
  483. Union: &pb2.Oneofs_Str{
  484. Str: "hello",
  485. },
  486. },
  487. }, {
  488. desc: "oneof field set to empty message",
  489. inputMessage: &pb2.Oneofs{},
  490. inputText: "msg: {}",
  491. wantMessage: &pb2.Oneofs{
  492. Union: &pb2.Oneofs_Msg{
  493. Msg: &pb2.Nested{},
  494. },
  495. },
  496. }, {
  497. desc: "oneof field set to message",
  498. inputMessage: &pb2.Oneofs{},
  499. inputText: `
  500. msg: {
  501. opt_string: "nested message"
  502. }
  503. `,
  504. wantMessage: &pb2.Oneofs{
  505. Union: &pb2.Oneofs_Msg{
  506. Msg: &pb2.Nested{
  507. OptString: scalar.String("nested message"),
  508. },
  509. },
  510. },
  511. }, {
  512. desc: "oneof field set to last value",
  513. inputMessage: &pb2.Oneofs{},
  514. inputText: `
  515. msg: {
  516. opt_string: "nested message"
  517. }
  518. str: "wins"
  519. `,
  520. wantMessage: &pb2.Oneofs{
  521. Union: &pb2.Oneofs_Str{
  522. Str: "wins",
  523. },
  524. },
  525. }, {
  526. desc: "repeated scalar using same field name",
  527. inputMessage: &pb2.Repeats{},
  528. inputText: `
  529. rpt_string: "a"
  530. rpt_string: "b"
  531. rpt_int32: 0xff
  532. rpt_float: 1.23
  533. rpt_bytes: "bytes"
  534. `,
  535. wantMessage: &pb2.Repeats{
  536. RptString: []string{"a", "b"},
  537. RptInt32: []int32{0xff},
  538. RptFloat: []float32{1.23},
  539. RptBytes: [][]byte{[]byte("bytes")},
  540. },
  541. }, {
  542. desc: "repeated using mix of [] and repeated field name",
  543. inputMessage: &pb2.Repeats{},
  544. inputText: `
  545. rpt_string: "a"
  546. rpt_bool: true
  547. rpt_string: ["x", "y"]
  548. rpt_bool: [ false, true ]
  549. rpt_string: "b"
  550. `,
  551. wantMessage: &pb2.Repeats{
  552. RptString: []string{"a", "x", "y", "b"},
  553. RptBool: []bool{true, false, true},
  554. },
  555. }, {
  556. desc: "repeated enums",
  557. inputMessage: &pb2.Enums{},
  558. inputText: `
  559. rpt_enum: TENTH
  560. rpt_enum: 1
  561. rpt_nested_enum: [DOS, 2]
  562. rpt_enum: 42
  563. rpt_nested_enum: -47
  564. `,
  565. wantMessage: &pb2.Enums{
  566. RptEnum: []pb2.Enum{pb2.Enum_TENTH, pb2.Enum_FIRST, 42},
  567. RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
  568. },
  569. }, {
  570. desc: "repeated nested messages",
  571. inputMessage: &pb2.Nests{},
  572. inputText: `
  573. rpt_nested: {
  574. opt_string: "repeat nested one"
  575. }
  576. rpt_nested: {
  577. opt_string: "repeat nested two"
  578. opt_nested: {
  579. opt_string: "inside repeat nested two"
  580. }
  581. }
  582. rpt_nested: {}
  583. `,
  584. wantMessage: &pb2.Nests{
  585. RptNested: []*pb2.Nested{
  586. {
  587. OptString: scalar.String("repeat nested one"),
  588. },
  589. {
  590. OptString: scalar.String("repeat nested two"),
  591. OptNested: &pb2.Nested{
  592. OptString: scalar.String("inside repeat nested two"),
  593. },
  594. },
  595. {},
  596. },
  597. },
  598. }, {
  599. desc: "repeated group fields",
  600. inputMessage: &pb2.Nests{},
  601. inputText: `
  602. RptGroup: {
  603. rpt_bool: true
  604. rpt_bool: false
  605. }
  606. RptGroup: {}
  607. `,
  608. wantMessage: &pb2.Nests{
  609. Rptgroup: []*pb2.Nests_RptGroup{
  610. {
  611. RptBool: []bool{true, false},
  612. },
  613. {},
  614. },
  615. },
  616. }, {
  617. desc: "map fields 1",
  618. inputMessage: &pb2.Maps{},
  619. inputText: `
  620. int32_to_str: {
  621. key: -101
  622. value: "-101"
  623. }
  624. int32_to_str: {
  625. key: 0
  626. value: "zero"
  627. }
  628. sfixed64_to_bool: {
  629. key: 0
  630. value: false
  631. }
  632. int32_to_str: {
  633. key: 255
  634. value: "0xff"
  635. }
  636. bool_to_uint32: {
  637. key: false
  638. value: 101
  639. }
  640. sfixed64_to_bool: {
  641. key: 51966
  642. value: true
  643. }
  644. bool_to_uint32: {
  645. key: true
  646. value: 42
  647. }
  648. `,
  649. wantMessage: &pb2.Maps{
  650. Int32ToStr: map[int32]string{
  651. -101: "-101",
  652. 0xff: "0xff",
  653. 0: "zero",
  654. },
  655. Sfixed64ToBool: map[int64]bool{
  656. 0xcafe: true,
  657. 0: false,
  658. },
  659. BoolToUint32: map[bool]uint32{
  660. true: 42,
  661. false: 101,
  662. },
  663. },
  664. }, {
  665. desc: "map fields 2",
  666. inputMessage: &pb2.Maps{},
  667. inputText: `
  668. uint64_to_enum: {
  669. key: 1
  670. value: FIRST
  671. }
  672. uint64_to_enum: {
  673. key: 2
  674. value: SECOND
  675. }
  676. uint64_to_enum: {
  677. key: 10
  678. value: TENTH
  679. }
  680. `,
  681. wantMessage: &pb2.Maps{
  682. Uint64ToEnum: map[uint64]pb2.Enum{
  683. 1: pb2.Enum_FIRST,
  684. 2: pb2.Enum_SECOND,
  685. 10: pb2.Enum_TENTH,
  686. },
  687. },
  688. }, {
  689. desc: "map fields 3",
  690. inputMessage: &pb2.Maps{},
  691. inputText: `
  692. str_to_nested: {
  693. key: "nested_one"
  694. value: {
  695. opt_string: "nested in a map"
  696. }
  697. }
  698. `,
  699. wantMessage: &pb2.Maps{
  700. StrToNested: map[string]*pb2.Nested{
  701. "nested_one": &pb2.Nested{
  702. OptString: scalar.String("nested in a map"),
  703. },
  704. },
  705. },
  706. }, {
  707. desc: "map fields 4",
  708. inputMessage: &pb2.Maps{},
  709. inputText: `
  710. str_to_oneofs: {
  711. key: "nested"
  712. value: {
  713. msg: {
  714. opt_string: "nested oneof in map field value"
  715. }
  716. }
  717. }
  718. str_to_oneofs: {
  719. key: "string"
  720. value: {
  721. str: "hello"
  722. }
  723. }
  724. `,
  725. wantMessage: &pb2.Maps{
  726. StrToOneofs: map[string]*pb2.Oneofs{
  727. "string": &pb2.Oneofs{
  728. Union: &pb2.Oneofs_Str{
  729. Str: "hello",
  730. },
  731. },
  732. "nested": &pb2.Oneofs{
  733. Union: &pb2.Oneofs_Msg{
  734. Msg: &pb2.Nested{
  735. OptString: scalar.String("nested oneof in map field value"),
  736. },
  737. },
  738. },
  739. },
  740. },
  741. }, {
  742. desc: "map contains duplicate keys",
  743. inputMessage: &pb2.Maps{},
  744. inputText: `
  745. int32_to_str: {
  746. key: 0
  747. value: "cero"
  748. }
  749. int32_to_str: {
  750. key: 0
  751. value: "zero"
  752. }
  753. `,
  754. wantMessage: &pb2.Maps{
  755. Int32ToStr: map[int32]string{
  756. 0: "zero",
  757. },
  758. },
  759. }, {
  760. desc: "map contains duplicate key fields",
  761. inputMessage: &pb2.Maps{},
  762. inputText: `
  763. int32_to_str: {
  764. key: 0
  765. key: 1
  766. value: "cero"
  767. }
  768. `,
  769. wantErr: true,
  770. }, {
  771. desc: "map contains duplicate value fields",
  772. inputMessage: &pb2.Maps{},
  773. inputText: `
  774. int32_to_str: {
  775. key: 1
  776. value: "cero"
  777. value: "uno"
  778. }
  779. `,
  780. wantErr: true,
  781. }, {
  782. desc: "map contains missing key",
  783. inputMessage: &pb2.Maps{},
  784. inputText: `
  785. int32_to_str: {
  786. value: "zero"
  787. }
  788. `,
  789. wantMessage: &pb2.Maps{
  790. Int32ToStr: map[int32]string{
  791. 0: "zero",
  792. },
  793. },
  794. }, {
  795. desc: "map contains missing value",
  796. inputMessage: &pb2.Maps{},
  797. inputText: `
  798. int32_to_str: {
  799. key: 100
  800. }
  801. `,
  802. wantMessage: &pb2.Maps{
  803. Int32ToStr: map[int32]string{
  804. 100: "",
  805. },
  806. },
  807. }, {
  808. desc: "map contains missing key and value",
  809. inputMessage: &pb2.Maps{},
  810. inputText: `
  811. int32_to_str: {}
  812. `,
  813. wantMessage: &pb2.Maps{
  814. Int32ToStr: map[int32]string{
  815. 0: "",
  816. },
  817. },
  818. }, {
  819. desc: "map contains unknown field",
  820. inputMessage: &pb2.Maps{},
  821. inputText: `
  822. int32_to_str: {
  823. key: 0
  824. value: "cero"
  825. unknown: "bad"
  826. }
  827. `,
  828. wantErr: true,
  829. }, {
  830. desc: "map contains extension-like key field",
  831. inputMessage: &pb2.Maps{},
  832. inputText: `
  833. int32_to_str: {
  834. [key]: 10
  835. value: "ten"
  836. }
  837. `,
  838. wantErr: true,
  839. }, {
  840. desc: "map contains invalid key",
  841. inputMessage: &pb2.Maps{},
  842. inputText: `
  843. int32_to_str: {
  844. key: "invalid"
  845. value: "cero"
  846. }
  847. `,
  848. wantErr: true,
  849. }, {
  850. desc: "map contains invalid value",
  851. inputMessage: &pb2.Maps{},
  852. inputText: `
  853. int32_to_str: {
  854. key: 100
  855. value: 101
  856. }
  857. `,
  858. wantErr: true,
  859. }, {
  860. desc: "map using mix of [] and repeated",
  861. inputMessage: &pb2.Maps{},
  862. inputText: `
  863. int32_to_str: {
  864. key: 1
  865. value: "one"
  866. }
  867. int32_to_str: [
  868. {
  869. key: 2
  870. value: "not this"
  871. },
  872. {
  873. },
  874. {
  875. key: 3
  876. value: "three"
  877. }
  878. ]
  879. int32_to_str: {
  880. key: 2
  881. value: "two"
  882. }
  883. `,
  884. wantMessage: &pb2.Maps{
  885. Int32ToStr: map[int32]string{
  886. 0: "",
  887. 1: "one",
  888. 2: "two",
  889. 3: "three",
  890. },
  891. },
  892. }, {
  893. desc: "proto2 required fields not set",
  894. inputMessage: &pb2.Requireds{},
  895. wantErr: true,
  896. }, {
  897. desc: "proto2 required field set but not optional",
  898. inputMessage: &pb2.PartialRequired{},
  899. inputText: "req_string: 'this is required'",
  900. wantMessage: &pb2.PartialRequired{
  901. ReqString: scalar.String("this is required"),
  902. },
  903. }, {
  904. desc: "proto2 required fields partially set",
  905. inputMessage: &pb2.Requireds{},
  906. inputText: `
  907. req_bool: false
  908. req_fixed32: 47
  909. req_sfixed64: 3203386110
  910. req_string: "hello"
  911. req_enum: FIRST
  912. `,
  913. wantMessage: &pb2.Requireds{
  914. ReqBool: scalar.Bool(false),
  915. ReqFixed32: scalar.Uint32(47),
  916. ReqSfixed64: scalar.Int64(0xbeefcafe),
  917. ReqString: scalar.String("hello"),
  918. ReqEnum: pb2.Enum_FIRST.Enum(),
  919. },
  920. wantErr: true,
  921. }, {
  922. desc: "proto2 required fields all set",
  923. inputMessage: &pb2.Requireds{},
  924. inputText: `
  925. req_bool: false
  926. req_fixed32: 0
  927. req_fixed64: 0
  928. req_sfixed32: 0
  929. req_sfixed64: 0
  930. req_float: 0
  931. req_double: 0
  932. req_string: ""
  933. req_bytes: ""
  934. req_enum: UNKNOWN
  935. req_nested: {}
  936. `,
  937. wantMessage: &pb2.Requireds{
  938. ReqBool: scalar.Bool(false),
  939. ReqFixed32: scalar.Uint32(0),
  940. ReqFixed64: scalar.Uint64(0),
  941. ReqSfixed32: scalar.Int32(0),
  942. ReqSfixed64: scalar.Int64(0),
  943. ReqFloat: scalar.Float32(0),
  944. ReqDouble: scalar.Float64(0),
  945. ReqString: scalar.String(""),
  946. ReqEnum: pb2.Enum_UNKNOWN.Enum(),
  947. ReqBytes: []byte{},
  948. ReqNested: &pb2.Nested{},
  949. },
  950. }, {
  951. desc: "indirect required field",
  952. inputMessage: &pb2.IndirectRequired{},
  953. inputText: "opt_nested: {}",
  954. wantMessage: &pb2.IndirectRequired{
  955. OptNested: &pb2.NestedWithRequired{},
  956. },
  957. wantErr: true,
  958. }, {
  959. desc: "indirect required field in repeated",
  960. inputMessage: &pb2.IndirectRequired{},
  961. inputText: `
  962. rpt_nested: {
  963. req_string: "one"
  964. }
  965. rpt_nested: {}
  966. rpt_nested: {
  967. req_string: "three"
  968. }
  969. `,
  970. wantMessage: &pb2.IndirectRequired{
  971. RptNested: []*pb2.NestedWithRequired{
  972. {
  973. ReqString: scalar.String("one"),
  974. },
  975. {},
  976. {
  977. ReqString: scalar.String("three"),
  978. },
  979. },
  980. },
  981. wantErr: true,
  982. }, {
  983. desc: "indirect required field in map",
  984. inputMessage: &pb2.IndirectRequired{},
  985. inputText: `
  986. str_to_nested: {
  987. key: "missing"
  988. }
  989. str_to_nested: {
  990. key: "contains"
  991. value: {
  992. req_string: "here"
  993. }
  994. }
  995. `,
  996. wantMessage: &pb2.IndirectRequired{
  997. StrToNested: map[string]*pb2.NestedWithRequired{
  998. "missing": &pb2.NestedWithRequired{},
  999. "contains": &pb2.NestedWithRequired{
  1000. ReqString: scalar.String("here"),
  1001. },
  1002. },
  1003. },
  1004. wantErr: true,
  1005. }, {
  1006. desc: "ignore reserved field",
  1007. inputMessage: &pb2.Nests{},
  1008. inputText: "reserved_field: 'ignore this'",
  1009. wantMessage: &pb2.Nests{},
  1010. }, {
  1011. desc: "extensions of non-repeated fields",
  1012. inputMessage: &pb2.Extensions{},
  1013. inputText: `opt_string: "non-extension field"
  1014. [pb2.opt_ext_bool]: true
  1015. opt_bool: true
  1016. [pb2.opt_ext_nested]: {
  1017. opt_string: "nested in an extension"
  1018. opt_nested: {
  1019. opt_string: "another nested in an extension"
  1020. }
  1021. }
  1022. [pb2.opt_ext_string]: "extension field"
  1023. opt_int32: 42
  1024. [pb2.opt_ext_enum]: TENTH
  1025. `,
  1026. wantMessage: func() proto.Message {
  1027. m := &pb2.Extensions{
  1028. OptString: scalar.String("non-extension field"),
  1029. OptBool: scalar.Bool(true),
  1030. OptInt32: scalar.Int32(42),
  1031. }
  1032. setExtension(m, pb2.E_OptExtBool, true)
  1033. setExtension(m, pb2.E_OptExtString, "extension field")
  1034. setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TENTH)
  1035. setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
  1036. OptString: scalar.String("nested in an extension"),
  1037. OptNested: &pb2.Nested{
  1038. OptString: scalar.String("another nested in an extension"),
  1039. },
  1040. })
  1041. return m
  1042. }(),
  1043. }, {
  1044. desc: "extensions of repeated fields",
  1045. inputMessage: &pb2.Extensions{},
  1046. inputText: `[pb2.rpt_ext_enum]: TENTH
  1047. [pb2.rpt_ext_enum]: 101
  1048. [pb2.rpt_ext_fixed32]: 42
  1049. [pb2.rpt_ext_enum]: FIRST
  1050. [pb2.rpt_ext_nested]: {
  1051. opt_string: "one"
  1052. }
  1053. [pb2.rpt_ext_nested]: {
  1054. opt_string: "two"
  1055. }
  1056. [pb2.rpt_ext_fixed32]: 47
  1057. [pb2.rpt_ext_nested]: {
  1058. opt_string: "three"
  1059. }
  1060. `,
  1061. wantMessage: func() proto.Message {
  1062. m := &pb2.Extensions{}
  1063. setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TENTH, 101, pb2.Enum_FIRST})
  1064. setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
  1065. setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
  1066. &pb2.Nested{OptString: scalar.String("one")},
  1067. &pb2.Nested{OptString: scalar.String("two")},
  1068. &pb2.Nested{OptString: scalar.String("three")},
  1069. })
  1070. return m
  1071. }(),
  1072. }, {
  1073. desc: "extensions of non-repeated fields in another message",
  1074. inputMessage: &pb2.Extensions{},
  1075. inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
  1076. [pb2.ExtensionsContainer.opt_ext_enum]: TENTH
  1077. [pb2.ExtensionsContainer.opt_ext_nested]: {
  1078. opt_string: "nested in an extension"
  1079. opt_nested: {
  1080. opt_string: "another nested in an extension"
  1081. }
  1082. }
  1083. [pb2.ExtensionsContainer.opt_ext_string]: "extension field"
  1084. `,
  1085. wantMessage: func() proto.Message {
  1086. m := &pb2.Extensions{}
  1087. setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
  1088. setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
  1089. setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TENTH)
  1090. setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
  1091. OptString: scalar.String("nested in an extension"),
  1092. OptNested: &pb2.Nested{
  1093. OptString: scalar.String("another nested in an extension"),
  1094. },
  1095. })
  1096. return m
  1097. }(),
  1098. }, {
  1099. desc: "extensions of repeated fields in another message",
  1100. inputMessage: &pb2.Extensions{},
  1101. inputText: `opt_string: "non-extension field"
  1102. opt_bool: true
  1103. opt_int32: 42
  1104. [pb2.ExtensionsContainer.rpt_ext_nested]: {
  1105. opt_string: "one"
  1106. }
  1107. [pb2.ExtensionsContainer.rpt_ext_enum]: TENTH
  1108. [pb2.ExtensionsContainer.rpt_ext_nested]: {
  1109. opt_string: "two"
  1110. }
  1111. [pb2.ExtensionsContainer.rpt_ext_enum]: 101
  1112. [pb2.ExtensionsContainer.rpt_ext_string]: "hello"
  1113. [pb2.ExtensionsContainer.rpt_ext_enum]: FIRST
  1114. [pb2.ExtensionsContainer.rpt_ext_nested]: {
  1115. opt_string: "three"
  1116. }
  1117. [pb2.ExtensionsContainer.rpt_ext_string]: "world"
  1118. `,
  1119. wantMessage: func() proto.Message {
  1120. m := &pb2.Extensions{
  1121. OptString: scalar.String("non-extension field"),
  1122. OptBool: scalar.Bool(true),
  1123. OptInt32: scalar.Int32(42),
  1124. }
  1125. setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TENTH, 101, pb2.Enum_FIRST})
  1126. setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
  1127. setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
  1128. &pb2.Nested{OptString: scalar.String("one")},
  1129. &pb2.Nested{OptString: scalar.String("two")},
  1130. &pb2.Nested{OptString: scalar.String("three")},
  1131. })
  1132. return m
  1133. }(),
  1134. }, {
  1135. desc: "invalid extension field name",
  1136. inputMessage: &pb2.Extensions{},
  1137. inputText: "[pb2.invalid_message_field]: true",
  1138. wantErr: true,
  1139. }, {
  1140. desc: "MessageSet",
  1141. inputMessage: &pb2.MessageSet{},
  1142. inputText: `
  1143. [pb2.MessageSetExtension]: {
  1144. opt_string: "a messageset extension"
  1145. }
  1146. [pb2.MessageSetExtension.ext_nested]: {
  1147. opt_string: "just a regular extension"
  1148. }
  1149. [pb2.MessageSetExtension.not_message_set_extension]: {
  1150. opt_string: "not a messageset extension"
  1151. }
  1152. `,
  1153. wantMessage: func() proto.Message {
  1154. m := &pb2.MessageSet{}
  1155. setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
  1156. OptString: scalar.String("a messageset extension"),
  1157. })
  1158. setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
  1159. OptString: scalar.String("not a messageset extension"),
  1160. })
  1161. setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
  1162. OptString: scalar.String("just a regular extension"),
  1163. })
  1164. return m
  1165. }(),
  1166. }, {
  1167. desc: "not real MessageSet 1",
  1168. inputMessage: &pb2.FakeMessageSet{},
  1169. inputText: `
  1170. [pb2.FakeMessageSetExtension.message_set_extension]: {
  1171. opt_string: "not a messageset extension"
  1172. }
  1173. `,
  1174. wantMessage: func() proto.Message {
  1175. m := &pb2.FakeMessageSet{}
  1176. setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
  1177. OptString: scalar.String("not a messageset extension"),
  1178. })
  1179. return m
  1180. }(),
  1181. }, {
  1182. desc: "not real MessageSet 2",
  1183. inputMessage: &pb2.FakeMessageSet{},
  1184. inputText: `
  1185. [pb2.FakeMessageSetExtension]: {
  1186. opt_string: "not a messageset extension"
  1187. }
  1188. `,
  1189. wantErr: true,
  1190. }, {
  1191. desc: "not real MessageSet 3",
  1192. inputMessage: &pb2.MessageSet{},
  1193. inputText: `
  1194. [pb2.message_set_extension]: {
  1195. opt_string: "another not a messageset extension"
  1196. }
  1197. `,
  1198. wantMessage: func() proto.Message {
  1199. m := &pb2.MessageSet{}
  1200. setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
  1201. OptString: scalar.String("another not a messageset extension"),
  1202. })
  1203. return m
  1204. }(),
  1205. }, {
  1206. desc: "Any not expanded",
  1207. inputMessage: &pb2.KnownTypes{},
  1208. inputText: `opt_any: {
  1209. type_url: "pb2.Nested"
  1210. value: "some bytes"
  1211. }
  1212. `,
  1213. wantMessage: &pb2.KnownTypes{
  1214. OptAny: &anypb.Any{
  1215. TypeUrl: "pb2.Nested",
  1216. Value: []byte("some bytes"),
  1217. },
  1218. },
  1219. }, {
  1220. desc: "Any not expanded missing value",
  1221. inputMessage: &pb2.KnownTypes{},
  1222. inputText: `opt_any: {
  1223. type_url: "pb2.Nested"
  1224. }
  1225. `,
  1226. wantMessage: &pb2.KnownTypes{
  1227. OptAny: &anypb.Any{
  1228. TypeUrl: "pb2.Nested",
  1229. },
  1230. },
  1231. }, {
  1232. desc: "Any not expanded missing type_url",
  1233. inputMessage: &pb2.KnownTypes{},
  1234. inputText: `opt_any: {
  1235. value: "some bytes"
  1236. }
  1237. `,
  1238. wantMessage: &pb2.KnownTypes{
  1239. OptAny: &anypb.Any{
  1240. Value: []byte("some bytes"),
  1241. },
  1242. },
  1243. }, {
  1244. desc: "Any expanded",
  1245. umo: func() textpb.UnmarshalOptions {
  1246. m := &pb2.Nested{}
  1247. resolver := preg.NewTypes(m.ProtoReflect().Type())
  1248. return textpb.UnmarshalOptions{Resolver: resolver}
  1249. }(),
  1250. inputMessage: &pb2.KnownTypes{},
  1251. inputText: `opt_any: {
  1252. [foobar/pb2.Nested]: {
  1253. opt_string: "embedded inside Any"
  1254. opt_nested: {
  1255. opt_string: "inception"
  1256. }
  1257. }
  1258. }
  1259. `,
  1260. wantMessage: func() proto.Message {
  1261. m := &pb2.Nested{
  1262. OptString: scalar.String("embedded inside Any"),
  1263. OptNested: &pb2.Nested{
  1264. OptString: scalar.String("inception"),
  1265. },
  1266. }
  1267. // TODO: Switch to V2 marshal when ready.
  1268. b, err := protoV1.Marshal(m)
  1269. if err != nil {
  1270. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  1271. }
  1272. return &pb2.KnownTypes{
  1273. OptAny: &anypb.Any{
  1274. TypeUrl: "foobar/pb2.Nested",
  1275. Value: b,
  1276. },
  1277. }
  1278. }(),
  1279. }, {
  1280. desc: "Any expanded with empty value",
  1281. umo: func() textpb.UnmarshalOptions {
  1282. m := &pb2.Nested{}
  1283. resolver := preg.NewTypes(m.ProtoReflect().Type())
  1284. return textpb.UnmarshalOptions{Resolver: resolver}
  1285. }(),
  1286. inputMessage: &pb2.KnownTypes{},
  1287. inputText: `opt_any: {
  1288. [foo.com/pb2.Nested]: {}
  1289. }
  1290. `,
  1291. wantMessage: &pb2.KnownTypes{
  1292. OptAny: &anypb.Any{
  1293. TypeUrl: "foo.com/pb2.Nested",
  1294. },
  1295. },
  1296. }, {
  1297. desc: "Any expanded with missing required error",
  1298. umo: func() textpb.UnmarshalOptions {
  1299. m := &pb2.PartialRequired{}
  1300. resolver := preg.NewTypes(m.ProtoReflect().Type())
  1301. return textpb.UnmarshalOptions{Resolver: resolver}
  1302. }(),
  1303. inputMessage: &pb2.KnownTypes{},
  1304. inputText: `opt_any: {
  1305. [pb2.PartialRequired]: {
  1306. opt_string: "embedded inside Any"
  1307. }
  1308. }
  1309. `,
  1310. wantMessage: func() proto.Message {
  1311. m := &pb2.PartialRequired{
  1312. OptString: scalar.String("embedded inside Any"),
  1313. }
  1314. // TODO: Switch to V2 marshal when ready.
  1315. b, err := protoV1.Marshal(m)
  1316. // Ignore required not set error.
  1317. if _, ok := err.(*protoV1.RequiredNotSetError); !ok {
  1318. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  1319. }
  1320. return &pb2.KnownTypes{
  1321. OptAny: &anypb.Any{
  1322. TypeUrl: "pb2.PartialRequired",
  1323. Value: b,
  1324. },
  1325. }
  1326. }(),
  1327. wantErr: true,
  1328. }, {
  1329. desc: "Any expanded with unregistered type",
  1330. umo: textpb.UnmarshalOptions{Resolver: preg.NewTypes()},
  1331. inputMessage: &pb2.KnownTypes{},
  1332. inputText: `opt_any: {
  1333. [SomeMessage]: {}
  1334. }
  1335. `,
  1336. wantErr: true,
  1337. }, {
  1338. desc: "Any expanded with invalid value",
  1339. umo: func() textpb.UnmarshalOptions {
  1340. m := &pb2.Nested{}
  1341. resolver := preg.NewTypes(m.ProtoReflect().Type())
  1342. return textpb.UnmarshalOptions{Resolver: resolver}
  1343. }(),
  1344. inputMessage: &pb2.KnownTypes{},
  1345. inputText: `opt_any: {
  1346. [pb2.Nested]: 123
  1347. }
  1348. `,
  1349. wantErr: true,
  1350. }, {
  1351. desc: "Any expanded with unknown fields",
  1352. umo: func() textpb.UnmarshalOptions {
  1353. m := &pb2.Nested{}
  1354. resolver := preg.NewTypes(m.ProtoReflect().Type())
  1355. return textpb.UnmarshalOptions{Resolver: resolver}
  1356. }(),
  1357. inputMessage: &pb2.KnownTypes{},
  1358. inputText: `opt_any: {
  1359. [pb2.Nested]: {}
  1360. unknown: ""
  1361. }
  1362. `,
  1363. wantErr: true,
  1364. }, {
  1365. desc: "Any contains expanded and unexpanded fields",
  1366. umo: func() textpb.UnmarshalOptions {
  1367. m := &pb2.Nested{}
  1368. resolver := preg.NewTypes(m.ProtoReflect().Type())
  1369. return textpb.UnmarshalOptions{Resolver: resolver}
  1370. }(),
  1371. inputMessage: &pb2.KnownTypes{},
  1372. inputText: `opt_any: {
  1373. [pb2.Nested]: {}
  1374. type_url: "pb2.Nested"
  1375. }
  1376. `,
  1377. wantErr: true,
  1378. }}
  1379. for _, tt := range tests {
  1380. tt := tt
  1381. t.Run(tt.desc, func(t *testing.T) {
  1382. t.Parallel()
  1383. err := tt.umo.Unmarshal(tt.inputMessage, []byte(tt.inputText))
  1384. if err != nil && !tt.wantErr {
  1385. t.Errorf("Unmarshal() returned error: %v\n\n", err)
  1386. }
  1387. if err == nil && tt.wantErr {
  1388. t.Error("Unmarshal() got nil error, want error\n\n")
  1389. }
  1390. if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
  1391. t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
  1392. }
  1393. })
  1394. }
  1395. }