decode_test.go 35 KB

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