decode_test.go 34 KB

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