decode_test.go 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537
  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. "google.golang.org/protobuf/internal/errors"
  11. pimpl "google.golang.org/protobuf/internal/impl"
  12. "google.golang.org/protobuf/internal/scalar"
  13. "google.golang.org/protobuf/proto"
  14. preg "google.golang.org/protobuf/reflect/protoregistry"
  15. "google.golang.org/protobuf/encoding/testprotos/pb2"
  16. "google.golang.org/protobuf/encoding/testprotos/pb3"
  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. }{{
  28. desc: "proto2 empty message",
  29. inputMessage: &pb2.Scalars{},
  30. wantMessage: &pb2.Scalars{},
  31. }, {
  32. desc: "proto2 optional scalars set to zero values",
  33. inputMessage: &pb2.Scalars{},
  34. inputText: `opt_bool: false
  35. opt_int32: 0
  36. opt_int64: 0
  37. opt_uint32: 0
  38. opt_uint64: 0
  39. opt_sint32: 0
  40. opt_sint64: 0
  41. opt_fixed32: 0
  42. opt_fixed64: 0
  43. opt_sfixed32: 0
  44. opt_sfixed64: 0
  45. opt_float: 0
  46. opt_double: 0
  47. opt_bytes: ""
  48. opt_string: ""
  49. `,
  50. wantMessage: &pb2.Scalars{
  51. OptBool: scalar.Bool(false),
  52. OptInt32: scalar.Int32(0),
  53. OptInt64: scalar.Int64(0),
  54. OptUint32: scalar.Uint32(0),
  55. OptUint64: scalar.Uint64(0),
  56. OptSint32: scalar.Int32(0),
  57. OptSint64: scalar.Int64(0),
  58. OptFixed32: scalar.Uint32(0),
  59. OptFixed64: scalar.Uint64(0),
  60. OptSfixed32: scalar.Int32(0),
  61. OptSfixed64: scalar.Int64(0),
  62. OptFloat: scalar.Float32(0),
  63. OptDouble: scalar.Float64(0),
  64. OptBytes: []byte{},
  65. OptString: scalar.String(""),
  66. },
  67. }, {
  68. desc: "proto3 scalars set to zero values",
  69. inputMessage: &pb3.Scalars{},
  70. inputText: `s_bool: false
  71. s_int32: 0
  72. s_int64: 0
  73. s_uint32: 0
  74. s_uint64: 0
  75. s_sint32: 0
  76. s_sint64: 0
  77. s_fixed32: 0
  78. s_fixed64: 0
  79. s_sfixed32: 0
  80. s_sfixed64: 0
  81. s_float: 0
  82. s_double: 0
  83. s_bytes: ""
  84. s_string: ""
  85. `,
  86. wantMessage: &pb3.Scalars{},
  87. }, {
  88. desc: "proto2 optional scalars",
  89. inputMessage: &pb2.Scalars{},
  90. inputText: `opt_bool: true
  91. opt_int32: 255
  92. opt_int64: 3735928559
  93. opt_uint32: 0xff
  94. opt_uint64: 0xdeadbeef
  95. opt_sint32: -1001
  96. opt_sint64: -0xffff
  97. opt_fixed64: 64
  98. opt_sfixed32: -32
  99. opt_float: 1.234
  100. opt_double: 1.23e+100
  101. opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
  102. opt_string: "谷歌"
  103. `,
  104. wantMessage: &pb2.Scalars{
  105. OptBool: scalar.Bool(true),
  106. OptInt32: scalar.Int32(0xff),
  107. OptInt64: scalar.Int64(0xdeadbeef),
  108. OptUint32: scalar.Uint32(0xff),
  109. OptUint64: scalar.Uint64(0xdeadbeef),
  110. OptSint32: scalar.Int32(-1001),
  111. OptSint64: scalar.Int64(-0xffff),
  112. OptFixed64: scalar.Uint64(64),
  113. OptSfixed32: scalar.Int32(-32),
  114. OptFloat: scalar.Float32(1.234),
  115. OptDouble: scalar.Float64(1.23e100),
  116. OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
  117. OptString: scalar.String("谷歌"),
  118. },
  119. }, {
  120. desc: "proto3 scalars",
  121. inputMessage: &pb3.Scalars{},
  122. inputText: `s_bool: true
  123. s_int32: 255
  124. s_int64: 3735928559
  125. s_uint32: 0xff
  126. s_uint64: 0xdeadbeef
  127. s_sint32: -1001
  128. s_sint64: -0xffff
  129. s_fixed64: 64
  130. s_sfixed32: -32
  131. s_float: 1.234
  132. s_double: 1.23e+100
  133. s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
  134. s_string: "谷歌"
  135. `,
  136. wantMessage: &pb3.Scalars{
  137. SBool: true,
  138. SInt32: 0xff,
  139. SInt64: 0xdeadbeef,
  140. SUint32: 0xff,
  141. SUint64: 0xdeadbeef,
  142. SSint32: -1001,
  143. SSint64: -0xffff,
  144. SFixed64: 64,
  145. SSfixed32: -32,
  146. SFloat: 1.234,
  147. SDouble: 1.23e100,
  148. SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
  149. SString: "谷歌",
  150. },
  151. }, {
  152. desc: "string with invalid UTF-8",
  153. inputMessage: &pb3.Scalars{},
  154. inputText: `s_string: "abc\xff"`,
  155. wantMessage: &pb3.Scalars{
  156. SString: "abc\xff",
  157. },
  158. wantErr: true,
  159. }, {
  160. desc: "proto2 message contains unknown field",
  161. inputMessage: &pb2.Scalars{},
  162. inputText: "unknown_field: 123",
  163. wantErr: true,
  164. }, {
  165. desc: "proto3 message contains unknown field",
  166. inputMessage: &pb3.Scalars{},
  167. inputText: "unknown_field: 456",
  168. wantErr: true,
  169. }, {
  170. desc: "proto2 numeric key field",
  171. inputMessage: &pb2.Scalars{},
  172. inputText: "1: true",
  173. wantErr: true,
  174. }, {
  175. desc: "proto3 numeric key field",
  176. inputMessage: &pb3.Scalars{},
  177. inputText: "1: true",
  178. wantErr: true,
  179. }, {
  180. desc: "invalid bool value",
  181. inputMessage: &pb3.Scalars{},
  182. inputText: "s_bool: 123",
  183. wantErr: true,
  184. }, {
  185. desc: "invalid int32 value",
  186. inputMessage: &pb3.Scalars{},
  187. inputText: "s_int32: not_a_num",
  188. wantErr: true,
  189. }, {
  190. desc: "invalid int64 value",
  191. inputMessage: &pb3.Scalars{},
  192. inputText: "s_int64: 'not a num either'",
  193. wantErr: true,
  194. }, {
  195. desc: "invalid uint32 value",
  196. inputMessage: &pb3.Scalars{},
  197. inputText: "s_fixed32: -42",
  198. wantErr: true,
  199. }, {
  200. desc: "invalid uint64 value",
  201. inputMessage: &pb3.Scalars{},
  202. inputText: "s_uint64: -47",
  203. wantErr: true,
  204. }, {
  205. desc: "invalid sint32 value",
  206. inputMessage: &pb3.Scalars{},
  207. inputText: "s_sint32: '42'",
  208. wantErr: true,
  209. }, {
  210. desc: "invalid sint64 value",
  211. inputMessage: &pb3.Scalars{},
  212. inputText: "s_sint64: '-47'",
  213. wantErr: true,
  214. }, {
  215. desc: "invalid fixed32 value",
  216. inputMessage: &pb3.Scalars{},
  217. inputText: "s_fixed32: -42",
  218. wantErr: true,
  219. }, {
  220. desc: "invalid fixed64 value",
  221. inputMessage: &pb3.Scalars{},
  222. inputText: "s_fixed64: -42",
  223. wantErr: true,
  224. }, {
  225. desc: "invalid sfixed32 value",
  226. inputMessage: &pb3.Scalars{},
  227. inputText: "s_sfixed32: 'not valid'",
  228. wantErr: true,
  229. }, {
  230. desc: "invalid sfixed64 value",
  231. inputMessage: &pb3.Scalars{},
  232. inputText: "s_sfixed64: bad",
  233. wantErr: true,
  234. }, {
  235. desc: "float positive infinity",
  236. inputMessage: &pb3.Scalars{},
  237. inputText: "s_float: inf",
  238. wantMessage: &pb3.Scalars{
  239. SFloat: float32(math.Inf(1)),
  240. },
  241. }, {
  242. desc: "float negative infinity",
  243. inputMessage: &pb3.Scalars{},
  244. inputText: "s_float: -inf",
  245. wantMessage: &pb3.Scalars{
  246. SFloat: float32(math.Inf(-1)),
  247. },
  248. }, {
  249. desc: "double positive infinity",
  250. inputMessage: &pb3.Scalars{},
  251. inputText: "s_double: inf",
  252. wantMessage: &pb3.Scalars{
  253. SDouble: math.Inf(1),
  254. },
  255. }, {
  256. desc: "double negative infinity",
  257. inputMessage: &pb3.Scalars{},
  258. inputText: "s_double: -inf",
  259. wantMessage: &pb3.Scalars{
  260. SDouble: math.Inf(-1),
  261. },
  262. }, {
  263. desc: "invalid string value",
  264. inputMessage: &pb3.Scalars{},
  265. inputText: "s_string: invalid_string",
  266. wantErr: true,
  267. }, {
  268. desc: "proto2 bytes set to empty string",
  269. inputMessage: &pb2.Scalars{},
  270. inputText: "opt_bytes: ''",
  271. wantMessage: &pb2.Scalars{
  272. OptBytes: []byte(""),
  273. },
  274. }, {
  275. desc: "proto3 bytes set to empty string",
  276. inputMessage: &pb3.Scalars{},
  277. inputText: "s_bytes: ''",
  278. wantMessage: &pb3.Scalars{},
  279. }, {
  280. desc: "proto2 duplicate singular field",
  281. inputMessage: &pb2.Scalars{},
  282. inputText: `
  283. opt_bool: true
  284. opt_bool: false
  285. `,
  286. wantErr: true,
  287. }, {
  288. desc: "proto2 more duplicate singular field",
  289. inputMessage: &pb2.Scalars{},
  290. inputText: `
  291. opt_bool: true
  292. opt_string: "hello"
  293. opt_bool: false
  294. `,
  295. wantErr: true,
  296. }, {
  297. desc: "proto2 invalid singular field",
  298. inputMessage: &pb2.Scalars{},
  299. inputText: `
  300. opt_bool: [true, false]
  301. `,
  302. wantErr: true,
  303. }, {
  304. desc: "proto3 duplicate singular field",
  305. inputMessage: &pb3.Scalars{},
  306. inputText: `
  307. s_bool: false
  308. s_bool: true
  309. `,
  310. wantErr: true,
  311. }, {
  312. desc: "proto3 more duplicate singular field",
  313. inputMessage: &pb3.Scalars{},
  314. inputText: `
  315. s_bool: false
  316. s_string: ""
  317. s_bool: true
  318. `,
  319. wantErr: true,
  320. }, {
  321. desc: "proto2 enum",
  322. inputMessage: &pb2.Enums{},
  323. inputText: `
  324. opt_enum: ONE
  325. opt_nested_enum: UNO
  326. `,
  327. wantMessage: &pb2.Enums{
  328. OptEnum: pb2.Enum_ONE.Enum(),
  329. OptNestedEnum: pb2.Enums_UNO.Enum(),
  330. },
  331. }, {
  332. desc: "proto2 enum set to numeric values",
  333. inputMessage: &pb2.Enums{},
  334. inputText: `
  335. opt_enum: 2
  336. opt_nested_enum: 2
  337. `,
  338. wantMessage: &pb2.Enums{
  339. OptEnum: pb2.Enum_TWO.Enum(),
  340. OptNestedEnum: pb2.Enums_DOS.Enum(),
  341. },
  342. }, {
  343. desc: "proto2 enum set to unnamed numeric values",
  344. inputMessage: &pb2.Enums{},
  345. inputText: `
  346. opt_enum: 101
  347. opt_nested_enum: -101
  348. `,
  349. wantMessage: &pb2.Enums{
  350. OptEnum: pb2Enum(101),
  351. OptNestedEnum: pb2Enums_NestedEnum(-101),
  352. },
  353. }, {
  354. desc: "proto2 enum set to invalid named",
  355. inputMessage: &pb2.Enums{},
  356. inputText: `
  357. opt_enum: UNNAMED
  358. opt_nested_enum: UNNAMED_TOO
  359. `,
  360. wantErr: true,
  361. }, {
  362. desc: "proto3 enum name value",
  363. inputMessage: &pb3.Enums{},
  364. inputText: `
  365. s_enum: ONE
  366. s_nested_enum: DIEZ
  367. `,
  368. wantMessage: &pb3.Enums{
  369. SEnum: pb3.Enum_ONE,
  370. SNestedEnum: pb3.Enums_DIEZ,
  371. },
  372. }, {
  373. desc: "proto3 enum numeric value",
  374. inputMessage: &pb3.Enums{},
  375. inputText: `
  376. s_enum: 2
  377. s_nested_enum: 2
  378. `,
  379. wantMessage: &pb3.Enums{
  380. SEnum: pb3.Enum_TWO,
  381. SNestedEnum: pb3.Enums_DOS,
  382. },
  383. }, {
  384. desc: "proto3 enum unnamed numeric value",
  385. inputMessage: &pb3.Enums{},
  386. inputText: `
  387. s_enum: 0x7fffffff
  388. s_nested_enum: -0x80000000
  389. `,
  390. wantMessage: &pb3.Enums{
  391. SEnum: 0x7fffffff,
  392. SNestedEnum: -0x80000000,
  393. },
  394. }, {
  395. desc: "proto2 nested empty messages",
  396. inputMessage: &pb2.Nests{},
  397. inputText: `
  398. opt_nested: {}
  399. OptGroup: {}
  400. `,
  401. wantMessage: &pb2.Nests{
  402. OptNested: &pb2.Nested{},
  403. Optgroup: &pb2.Nests_OptGroup{},
  404. },
  405. }, {
  406. desc: "proto2 nested messages",
  407. inputMessage: &pb2.Nests{},
  408. inputText: `
  409. opt_nested: {
  410. opt_string: "nested message"
  411. opt_nested: {
  412. opt_string: "another nested message"
  413. }
  414. }
  415. `,
  416. wantMessage: &pb2.Nests{
  417. OptNested: &pb2.Nested{
  418. OptString: scalar.String("nested message"),
  419. OptNested: &pb2.Nested{
  420. OptString: scalar.String("another nested message"),
  421. },
  422. },
  423. },
  424. }, {
  425. desc: "proto3 nested empty message",
  426. inputMessage: &pb3.Nests{},
  427. inputText: "s_nested: {}",
  428. wantMessage: &pb3.Nests{
  429. SNested: &pb3.Nested{},
  430. },
  431. }, {
  432. desc: "proto3 nested message",
  433. inputMessage: &pb3.Nests{},
  434. inputText: `
  435. s_nested: {
  436. s_string: "nested message"
  437. s_nested: {
  438. s_string: "another nested message"
  439. }
  440. }
  441. `,
  442. wantMessage: &pb3.Nests{
  443. SNested: &pb3.Nested{
  444. SString: "nested message",
  445. SNested: &pb3.Nested{
  446. SString: "another nested message",
  447. },
  448. },
  449. },
  450. }, {
  451. desc: "proto3 nested message contains invalid UTF-8",
  452. inputMessage: &pb3.Nests{},
  453. inputText: `s_nested: {
  454. s_string: "abc\xff"
  455. }
  456. `,
  457. wantMessage: &pb3.Nests{
  458. SNested: &pb3.Nested{
  459. SString: "abc\xff",
  460. },
  461. },
  462. wantErr: true,
  463. }, {
  464. desc: "oneof set to empty string",
  465. inputMessage: &pb3.Oneofs{},
  466. inputText: "oneof_string: ''",
  467. wantMessage: &pb3.Oneofs{
  468. Union: &pb3.Oneofs_OneofString{},
  469. },
  470. }, {
  471. desc: "oneof set to string",
  472. inputMessage: &pb3.Oneofs{},
  473. inputText: "oneof_string: 'hello'",
  474. wantMessage: &pb3.Oneofs{
  475. Union: &pb3.Oneofs_OneofString{
  476. OneofString: "hello",
  477. },
  478. },
  479. }, {
  480. desc: "oneof set to enum",
  481. inputMessage: &pb3.Oneofs{},
  482. inputText: "oneof_enum: TEN",
  483. wantMessage: &pb3.Oneofs{
  484. Union: &pb3.Oneofs_OneofEnum{
  485. OneofEnum: pb3.Enum_TEN,
  486. },
  487. },
  488. }, {
  489. desc: "oneof set to empty message",
  490. inputMessage: &pb3.Oneofs{},
  491. inputText: "oneof_nested: {}",
  492. wantMessage: &pb3.Oneofs{
  493. Union: &pb3.Oneofs_OneofNested{
  494. OneofNested: &pb3.Nested{},
  495. },
  496. },
  497. }, {
  498. desc: "oneof set to message",
  499. inputMessage: &pb3.Oneofs{},
  500. inputText: `
  501. oneof_nested: {
  502. s_string: "nested message"
  503. }
  504. `,
  505. wantMessage: &pb3.Oneofs{
  506. Union: &pb3.Oneofs_OneofNested{
  507. OneofNested: &pb3.Nested{
  508. SString: "nested message",
  509. },
  510. },
  511. },
  512. }, {
  513. desc: "oneof set to more than one field",
  514. inputMessage: &pb3.Oneofs{},
  515. inputText: `
  516. oneof_enum: ZERO
  517. oneof_string: "hello"
  518. `,
  519. wantErr: true,
  520. }, {
  521. desc: "repeated scalar using same field name",
  522. inputMessage: &pb2.Repeats{},
  523. inputText: `
  524. rpt_string: "a"
  525. rpt_string: "b"
  526. rpt_int32: 0xff
  527. rpt_float: 1.23
  528. rpt_bytes: "bytes"
  529. `,
  530. wantMessage: &pb2.Repeats{
  531. RptString: []string{"a", "b"},
  532. RptInt32: []int32{0xff},
  533. RptFloat: []float32{1.23},
  534. RptBytes: [][]byte{[]byte("bytes")},
  535. },
  536. }, {
  537. desc: "repeated using mix of [] and repeated field name",
  538. inputMessage: &pb2.Repeats{},
  539. inputText: `
  540. rpt_string: "a"
  541. rpt_bool: true
  542. rpt_string: ["x", "y"]
  543. rpt_bool: [ false, true ]
  544. rpt_string: "b"
  545. `,
  546. wantMessage: &pb2.Repeats{
  547. RptString: []string{"a", "x", "y", "b"},
  548. RptBool: []bool{true, false, true},
  549. },
  550. }, {
  551. desc: "repeated contains invalid UTF-8",
  552. inputMessage: &pb2.Repeats{},
  553. inputText: `rpt_string: "abc\xff"`,
  554. wantMessage: &pb2.Repeats{
  555. RptString: []string{"abc\xff"},
  556. },
  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: scalar.String("repeat nested one"),
  591. },
  592. {
  593. OptString: scalar.String("repeat nested two"),
  594. OptNested: &pb2.Nested{
  595. OptString: scalar.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. wantMessage: &pb3.Maps{
  877. Int32ToStr: map[int32]string{
  878. 101: "abc\xff",
  879. },
  880. },
  881. wantErr: true,
  882. }, {
  883. desc: "map field key contains invalid UTF-8",
  884. inputMessage: &pb3.Maps{},
  885. inputText: `str_to_nested: {
  886. key: "abc\xff"
  887. value: {}
  888. }
  889. `,
  890. wantMessage: &pb3.Maps{
  891. StrToNested: map[string]*pb3.Nested{
  892. "abc\xff": {},
  893. },
  894. },
  895. wantErr: true,
  896. }, {
  897. desc: "map contains unknown field",
  898. inputMessage: &pb3.Maps{},
  899. inputText: `
  900. int32_to_str: {
  901. key: 0
  902. value: "cero"
  903. unknown: "bad"
  904. }
  905. `,
  906. wantErr: true,
  907. }, {
  908. desc: "map contains extension-like key field",
  909. inputMessage: &pb3.Maps{},
  910. inputText: `
  911. int32_to_str: {
  912. [key]: 10
  913. value: "ten"
  914. }
  915. `,
  916. wantErr: true,
  917. }, {
  918. desc: "map contains invalid key",
  919. inputMessage: &pb3.Maps{},
  920. inputText: `
  921. int32_to_str: {
  922. key: "invalid"
  923. value: "cero"
  924. }
  925. `,
  926. wantErr: true,
  927. }, {
  928. desc: "map contains invalid value",
  929. inputMessage: &pb3.Maps{},
  930. inputText: `
  931. int32_to_str: {
  932. key: 100
  933. value: 101
  934. }
  935. `,
  936. wantErr: true,
  937. }, {
  938. desc: "map using mix of [] and repeated",
  939. inputMessage: &pb3.Maps{},
  940. inputText: `
  941. int32_to_str: {
  942. key: 1
  943. value: "one"
  944. }
  945. int32_to_str: [
  946. {
  947. key: 2
  948. value: "not this"
  949. },
  950. {
  951. },
  952. {
  953. key: 3
  954. value: "three"
  955. }
  956. ]
  957. int32_to_str: {
  958. key: 2
  959. value: "two"
  960. }
  961. `,
  962. wantMessage: &pb3.Maps{
  963. Int32ToStr: map[int32]string{
  964. 0: "",
  965. 1: "one",
  966. 2: "two",
  967. 3: "three",
  968. },
  969. },
  970. }, {
  971. desc: "required fields not set",
  972. inputMessage: &pb2.Requireds{},
  973. wantErr: true,
  974. }, {
  975. desc: "required field set",
  976. inputMessage: &pb2.PartialRequired{},
  977. inputText: "req_string: 'this is required'",
  978. wantMessage: &pb2.PartialRequired{
  979. ReqString: scalar.String("this is required"),
  980. },
  981. }, {
  982. desc: "required fields partially set",
  983. inputMessage: &pb2.Requireds{},
  984. inputText: `
  985. req_bool: false
  986. req_sfixed64: 3203386110
  987. req_string: "hello"
  988. req_enum: ONE
  989. `,
  990. wantMessage: &pb2.Requireds{
  991. ReqBool: scalar.Bool(false),
  992. ReqSfixed64: scalar.Int64(0xbeefcafe),
  993. ReqString: scalar.String("hello"),
  994. ReqEnum: pb2.Enum_ONE.Enum(),
  995. },
  996. wantErr: true,
  997. }, {
  998. desc: "required fields partially set with AllowPartial",
  999. umo: prototext.UnmarshalOptions{AllowPartial: true},
  1000. inputMessage: &pb2.Requireds{},
  1001. inputText: `
  1002. req_bool: false
  1003. req_sfixed64: 3203386110
  1004. req_string: "hello"
  1005. req_enum: ONE
  1006. `,
  1007. wantMessage: &pb2.Requireds{
  1008. ReqBool: scalar.Bool(false),
  1009. ReqSfixed64: scalar.Int64(0xbeefcafe),
  1010. ReqString: scalar.String("hello"),
  1011. ReqEnum: pb2.Enum_ONE.Enum(),
  1012. },
  1013. }, {
  1014. desc: "required fields all set",
  1015. inputMessage: &pb2.Requireds{},
  1016. inputText: `
  1017. req_bool: false
  1018. req_sfixed64: 0
  1019. req_double: 0
  1020. req_string: ""
  1021. req_enum: ONE
  1022. req_nested: {}
  1023. `,
  1024. wantMessage: &pb2.Requireds{
  1025. ReqBool: scalar.Bool(false),
  1026. ReqSfixed64: scalar.Int64(0),
  1027. ReqDouble: scalar.Float64(0),
  1028. ReqString: scalar.String(""),
  1029. ReqEnum: pb2.Enum_ONE.Enum(),
  1030. ReqNested: &pb2.Nested{},
  1031. },
  1032. }, {
  1033. desc: "indirect required field",
  1034. inputMessage: &pb2.IndirectRequired{},
  1035. inputText: "opt_nested: {}",
  1036. wantMessage: &pb2.IndirectRequired{
  1037. OptNested: &pb2.NestedWithRequired{},
  1038. },
  1039. wantErr: true,
  1040. }, {
  1041. desc: "indirect required field with AllowPartial",
  1042. umo: prototext.UnmarshalOptions{AllowPartial: true},
  1043. inputMessage: &pb2.IndirectRequired{},
  1044. inputText: "opt_nested: {}",
  1045. wantMessage: &pb2.IndirectRequired{
  1046. OptNested: &pb2.NestedWithRequired{},
  1047. },
  1048. }, {
  1049. desc: "indirect required field in repeated",
  1050. inputMessage: &pb2.IndirectRequired{},
  1051. inputText: `
  1052. rpt_nested: {
  1053. req_string: "one"
  1054. }
  1055. rpt_nested: {}
  1056. `,
  1057. wantMessage: &pb2.IndirectRequired{
  1058. RptNested: []*pb2.NestedWithRequired{
  1059. {
  1060. ReqString: scalar.String("one"),
  1061. },
  1062. {},
  1063. },
  1064. },
  1065. wantErr: true,
  1066. }, {
  1067. desc: "indirect required field in repeated with AllowPartial",
  1068. umo: prototext.UnmarshalOptions{AllowPartial: true},
  1069. inputMessage: &pb2.IndirectRequired{},
  1070. inputText: `
  1071. rpt_nested: {
  1072. req_string: "one"
  1073. }
  1074. rpt_nested: {}
  1075. `,
  1076. wantMessage: &pb2.IndirectRequired{
  1077. RptNested: []*pb2.NestedWithRequired{
  1078. {
  1079. ReqString: scalar.String("one"),
  1080. },
  1081. {},
  1082. },
  1083. },
  1084. }, {
  1085. desc: "indirect required field in map",
  1086. inputMessage: &pb2.IndirectRequired{},
  1087. inputText: `
  1088. str_to_nested: {
  1089. key: "missing"
  1090. }
  1091. str_to_nested: {
  1092. key: "contains"
  1093. value: {
  1094. req_string: "here"
  1095. }
  1096. }
  1097. `,
  1098. wantMessage: &pb2.IndirectRequired{
  1099. StrToNested: map[string]*pb2.NestedWithRequired{
  1100. "missing": &pb2.NestedWithRequired{},
  1101. "contains": &pb2.NestedWithRequired{
  1102. ReqString: scalar.String("here"),
  1103. },
  1104. },
  1105. },
  1106. wantErr: true,
  1107. }, {
  1108. desc: "indirect required field in map with AllowPartial",
  1109. umo: prototext.UnmarshalOptions{AllowPartial: true},
  1110. inputMessage: &pb2.IndirectRequired{},
  1111. inputText: `
  1112. str_to_nested: {
  1113. key: "missing"
  1114. }
  1115. str_to_nested: {
  1116. key: "contains"
  1117. value: {
  1118. req_string: "here"
  1119. }
  1120. }
  1121. `,
  1122. wantMessage: &pb2.IndirectRequired{
  1123. StrToNested: map[string]*pb2.NestedWithRequired{
  1124. "missing": &pb2.NestedWithRequired{},
  1125. "contains": &pb2.NestedWithRequired{
  1126. ReqString: scalar.String("here"),
  1127. },
  1128. },
  1129. },
  1130. }, {
  1131. desc: "indirect required field in oneof",
  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. wantErr: true,
  1141. }, {
  1142. desc: "indirect required field in oneof with AllowPartial",
  1143. umo: prototext.UnmarshalOptions{AllowPartial: true},
  1144. inputMessage: &pb2.IndirectRequired{},
  1145. inputText: `oneof_nested: {}
  1146. `,
  1147. wantMessage: &pb2.IndirectRequired{
  1148. Union: &pb2.IndirectRequired_OneofNested{
  1149. OneofNested: &pb2.NestedWithRequired{},
  1150. },
  1151. },
  1152. }, {
  1153. desc: "ignore reserved field",
  1154. inputMessage: &pb2.Nests{},
  1155. inputText: "reserved_field: 'ignore this'",
  1156. wantMessage: &pb2.Nests{},
  1157. }, {
  1158. desc: "extensions of non-repeated fields",
  1159. inputMessage: &pb2.Extensions{},
  1160. inputText: `opt_string: "non-extension field"
  1161. [pb2.opt_ext_bool]: true
  1162. opt_bool: true
  1163. [pb2.opt_ext_nested]: {
  1164. opt_string: "nested in an extension"
  1165. opt_nested: {
  1166. opt_string: "another nested in an extension"
  1167. }
  1168. }
  1169. [pb2.opt_ext_string]: "extension field"
  1170. opt_int32: 42
  1171. [pb2.opt_ext_enum]: TEN
  1172. `,
  1173. wantMessage: func() proto.Message {
  1174. m := &pb2.Extensions{
  1175. OptString: scalar.String("non-extension field"),
  1176. OptBool: scalar.Bool(true),
  1177. OptInt32: scalar.Int32(42),
  1178. }
  1179. setExtension(m, pb2.E_OptExtBool, true)
  1180. setExtension(m, pb2.E_OptExtString, "extension field")
  1181. setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
  1182. setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
  1183. OptString: scalar.String("nested in an extension"),
  1184. OptNested: &pb2.Nested{
  1185. OptString: scalar.String("another nested in an extension"),
  1186. },
  1187. })
  1188. return m
  1189. }(),
  1190. }, {
  1191. desc: "extension field contains invalid UTF-8",
  1192. inputMessage: &pb2.Extensions{},
  1193. inputText: `[pb2.opt_ext_string]: "abc\xff"`,
  1194. wantMessage: func() proto.Message {
  1195. m := &pb2.Extensions{}
  1196. setExtension(m, pb2.E_OptExtString, "abc\xff")
  1197. return m
  1198. }(),
  1199. wantErr: true,
  1200. }, {
  1201. desc: "extensions of repeated fields",
  1202. inputMessage: &pb2.Extensions{},
  1203. inputText: `[pb2.rpt_ext_enum]: TEN
  1204. [pb2.rpt_ext_enum]: 101
  1205. [pb2.rpt_ext_fixed32]: 42
  1206. [pb2.rpt_ext_enum]: ONE
  1207. [pb2.rpt_ext_nested]: {
  1208. opt_string: "one"
  1209. }
  1210. [pb2.rpt_ext_nested]: {
  1211. opt_string: "two"
  1212. }
  1213. [pb2.rpt_ext_fixed32]: 47
  1214. [pb2.rpt_ext_nested]: {
  1215. opt_string: "three"
  1216. }
  1217. `,
  1218. wantMessage: func() proto.Message {
  1219. m := &pb2.Extensions{}
  1220. setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
  1221. setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
  1222. setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
  1223. &pb2.Nested{OptString: scalar.String("one")},
  1224. &pb2.Nested{OptString: scalar.String("two")},
  1225. &pb2.Nested{OptString: scalar.String("three")},
  1226. })
  1227. return m
  1228. }(),
  1229. }, {
  1230. desc: "extensions of non-repeated fields in another message",
  1231. inputMessage: &pb2.Extensions{},
  1232. inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
  1233. [pb2.ExtensionsContainer.opt_ext_enum]: TEN
  1234. [pb2.ExtensionsContainer.opt_ext_nested]: {
  1235. opt_string: "nested in an extension"
  1236. opt_nested: {
  1237. opt_string: "another nested in an extension"
  1238. }
  1239. }
  1240. [pb2.ExtensionsContainer.opt_ext_string]: "extension field"
  1241. `,
  1242. wantMessage: func() proto.Message {
  1243. m := &pb2.Extensions{}
  1244. setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
  1245. setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
  1246. setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
  1247. setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
  1248. OptString: scalar.String("nested in an extension"),
  1249. OptNested: &pb2.Nested{
  1250. OptString: scalar.String("another nested in an extension"),
  1251. },
  1252. })
  1253. return m
  1254. }(),
  1255. }, {
  1256. desc: "extensions of repeated fields in another message",
  1257. inputMessage: &pb2.Extensions{},
  1258. inputText: `opt_string: "non-extension field"
  1259. opt_bool: true
  1260. opt_int32: 42
  1261. [pb2.ExtensionsContainer.rpt_ext_nested]: {
  1262. opt_string: "one"
  1263. }
  1264. [pb2.ExtensionsContainer.rpt_ext_enum]: TEN
  1265. [pb2.ExtensionsContainer.rpt_ext_nested]: {
  1266. opt_string: "two"
  1267. }
  1268. [pb2.ExtensionsContainer.rpt_ext_enum]: 101
  1269. [pb2.ExtensionsContainer.rpt_ext_string]: "hello"
  1270. [pb2.ExtensionsContainer.rpt_ext_enum]: ONE
  1271. [pb2.ExtensionsContainer.rpt_ext_nested]: {
  1272. opt_string: "three"
  1273. }
  1274. [pb2.ExtensionsContainer.rpt_ext_string]: "world"
  1275. `,
  1276. wantMessage: func() proto.Message {
  1277. m := &pb2.Extensions{
  1278. OptString: scalar.String("non-extension field"),
  1279. OptBool: scalar.Bool(true),
  1280. OptInt32: scalar.Int32(42),
  1281. }
  1282. setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
  1283. setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
  1284. setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
  1285. &pb2.Nested{OptString: scalar.String("one")},
  1286. &pb2.Nested{OptString: scalar.String("two")},
  1287. &pb2.Nested{OptString: scalar.String("three")},
  1288. })
  1289. return m
  1290. }(),
  1291. }, {
  1292. desc: "invalid extension field name",
  1293. inputMessage: &pb2.Extensions{},
  1294. inputText: "[pb2.invalid_message_field]: true",
  1295. wantErr: true,
  1296. }, {
  1297. desc: "MessageSet",
  1298. inputMessage: &pb2.MessageSet{},
  1299. inputText: `
  1300. [pb2.MessageSetExtension]: {
  1301. opt_string: "a messageset extension"
  1302. }
  1303. [pb2.MessageSetExtension.ext_nested]: {
  1304. opt_string: "just a regular extension"
  1305. }
  1306. [pb2.MessageSetExtension.not_message_set_extension]: {
  1307. opt_string: "not a messageset extension"
  1308. }
  1309. `,
  1310. wantMessage: func() proto.Message {
  1311. m := &pb2.MessageSet{}
  1312. setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
  1313. OptString: scalar.String("a messageset extension"),
  1314. })
  1315. setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
  1316. OptString: scalar.String("not a messageset extension"),
  1317. })
  1318. setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
  1319. OptString: scalar.String("just a regular extension"),
  1320. })
  1321. return m
  1322. }(),
  1323. }, {
  1324. desc: "not real MessageSet 1",
  1325. inputMessage: &pb2.FakeMessageSet{},
  1326. inputText: `
  1327. [pb2.FakeMessageSetExtension.message_set_extension]: {
  1328. opt_string: "not a messageset extension"
  1329. }
  1330. `,
  1331. wantMessage: func() proto.Message {
  1332. m := &pb2.FakeMessageSet{}
  1333. setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
  1334. OptString: scalar.String("not a messageset extension"),
  1335. })
  1336. return m
  1337. }(),
  1338. }, {
  1339. desc: "not real MessageSet 2",
  1340. inputMessage: &pb2.FakeMessageSet{},
  1341. inputText: `
  1342. [pb2.FakeMessageSetExtension]: {
  1343. opt_string: "not a messageset extension"
  1344. }
  1345. `,
  1346. wantErr: true,
  1347. }, {
  1348. desc: "not real MessageSet 3",
  1349. inputMessage: &pb2.MessageSet{},
  1350. inputText: `
  1351. [pb2.message_set_extension]: {
  1352. opt_string: "another not a messageset extension"
  1353. }`,
  1354. wantMessage: func() proto.Message {
  1355. m := &pb2.MessageSet{}
  1356. setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
  1357. OptString: scalar.String("another not a messageset extension"),
  1358. })
  1359. return m
  1360. }(),
  1361. }, {
  1362. desc: "Any not expanded",
  1363. inputMessage: &anypb.Any{},
  1364. inputText: `
  1365. type_url: "pb2.Nested"
  1366. value: "some bytes"
  1367. `,
  1368. wantMessage: &anypb.Any{
  1369. TypeUrl: "pb2.Nested",
  1370. Value: []byte("some bytes"),
  1371. },
  1372. }, {
  1373. desc: "Any not expanded missing value",
  1374. inputMessage: &anypb.Any{},
  1375. inputText: `type_url: "pb2.Nested"`,
  1376. wantMessage: &anypb.Any{
  1377. TypeUrl: "pb2.Nested",
  1378. },
  1379. }, {
  1380. desc: "Any not expanded missing type_url",
  1381. inputMessage: &anypb.Any{},
  1382. inputText: `value: "some bytes"`,
  1383. wantMessage: &anypb.Any{
  1384. Value: []byte("some bytes"),
  1385. },
  1386. }, {
  1387. desc: "Any expanded",
  1388. umo: prototext.UnmarshalOptions{
  1389. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
  1390. },
  1391. inputMessage: &anypb.Any{},
  1392. inputText: `
  1393. [foobar/pb2.Nested]: {
  1394. opt_string: "embedded inside Any"
  1395. opt_nested: {
  1396. opt_string: "inception"
  1397. }
  1398. }
  1399. `,
  1400. wantMessage: func() proto.Message {
  1401. m := &pb2.Nested{
  1402. OptString: scalar.String("embedded inside Any"),
  1403. OptNested: &pb2.Nested{
  1404. OptString: scalar.String("inception"),
  1405. },
  1406. }
  1407. b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
  1408. if err != nil {
  1409. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  1410. }
  1411. return &anypb.Any{
  1412. TypeUrl: "foobar/pb2.Nested",
  1413. Value: b,
  1414. }
  1415. }(),
  1416. }, {
  1417. desc: "Any expanded with empty value",
  1418. umo: prototext.UnmarshalOptions{
  1419. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
  1420. },
  1421. inputMessage: &anypb.Any{},
  1422. inputText: `[foo.com/pb2.Nested]: {}`,
  1423. wantMessage: &anypb.Any{
  1424. TypeUrl: "foo.com/pb2.Nested",
  1425. },
  1426. }, {
  1427. desc: "Any expanded with missing required",
  1428. umo: prototext.UnmarshalOptions{
  1429. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
  1430. },
  1431. inputMessage: &anypb.Any{},
  1432. inputText: `
  1433. [pb2.PartialRequired]: {
  1434. opt_string: "embedded inside Any"
  1435. }
  1436. `,
  1437. wantMessage: func() proto.Message {
  1438. m := &pb2.PartialRequired{
  1439. OptString: scalar.String("embedded inside Any"),
  1440. }
  1441. b, err := proto.MarshalOptions{
  1442. AllowPartial: true,
  1443. Deterministic: true,
  1444. }.Marshal(m)
  1445. if err != nil {
  1446. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  1447. }
  1448. return &anypb.Any{
  1449. TypeUrl: "pb2.PartialRequired",
  1450. Value: b,
  1451. }
  1452. }(),
  1453. }, {
  1454. desc: "Any with invalid UTF-8",
  1455. umo: prototext.UnmarshalOptions{
  1456. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb3.Nested{})),
  1457. },
  1458. inputMessage: &anypb.Any{},
  1459. inputText: `
  1460. [pb3.Nested]: {
  1461. s_string: "abc\xff"
  1462. }
  1463. `,
  1464. wantMessage: func() proto.Message {
  1465. m := &pb3.Nested{
  1466. SString: "abc\xff",
  1467. }
  1468. var nerr errors.NonFatal
  1469. b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
  1470. if !nerr.Merge(err) {
  1471. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  1472. }
  1473. return &anypb.Any{
  1474. TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
  1475. Value: b,
  1476. }
  1477. }(),
  1478. wantErr: true,
  1479. }, {
  1480. desc: "Any expanded with unregistered type",
  1481. umo: prototext.UnmarshalOptions{Resolver: preg.NewTypes()},
  1482. inputMessage: &anypb.Any{},
  1483. inputText: `[SomeMessage]: {}`,
  1484. wantErr: true,
  1485. }, {
  1486. desc: "Any expanded with invalid value",
  1487. umo: prototext.UnmarshalOptions{
  1488. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
  1489. },
  1490. inputMessage: &anypb.Any{},
  1491. inputText: `[pb2.Nested]: 123`,
  1492. wantErr: true,
  1493. }, {
  1494. desc: "Any expanded with unknown fields",
  1495. umo: prototext.UnmarshalOptions{
  1496. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
  1497. },
  1498. inputMessage: &anypb.Any{},
  1499. inputText: `
  1500. [pb2.Nested]: {}
  1501. unknown: ""
  1502. `,
  1503. wantErr: true,
  1504. }, {
  1505. desc: "Any contains expanded and unexpanded fields",
  1506. umo: prototext.UnmarshalOptions{
  1507. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
  1508. },
  1509. inputMessage: &anypb.Any{},
  1510. inputText: `
  1511. [pb2.Nested]: {}
  1512. type_url: "pb2.Nested"
  1513. `,
  1514. wantErr: true,
  1515. }}
  1516. for _, tt := range tests {
  1517. tt := tt
  1518. t.Run(tt.desc, func(t *testing.T) {
  1519. err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
  1520. if err != nil && !tt.wantErr {
  1521. t.Errorf("Unmarshal() returned error: %v\n\n", err)
  1522. }
  1523. if err == nil && tt.wantErr {
  1524. t.Error("Unmarshal() got nil error, want error\n\n")
  1525. }
  1526. if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
  1527. t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
  1528. }
  1529. })
  1530. }
  1531. }