decode_test.go 35 KB

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