decode_test.go 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505
  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. pimpl "google.golang.org/protobuf/internal/impl"
  10. "google.golang.org/protobuf/internal/scalar"
  11. "google.golang.org/protobuf/proto"
  12. preg "google.golang.org/protobuf/reflect/protoregistry"
  13. "google.golang.org/protobuf/encoding/testprotos/pb2"
  14. "google.golang.org/protobuf/encoding/testprotos/pb3"
  15. "google.golang.org/protobuf/types/known/anypb"
  16. )
  17. func TestUnmarshal(t *testing.T) {
  18. tests := []struct {
  19. desc string
  20. umo prototext.UnmarshalOptions
  21. inputMessage proto.Message
  22. inputText string
  23. wantMessage proto.Message
  24. wantErr bool // TODO: Verify error message content.
  25. }{{
  26. desc: "proto2 empty message",
  27. inputMessage: &pb2.Scalars{},
  28. wantMessage: &pb2.Scalars{},
  29. }, {
  30. desc: "proto2 optional scalars set to zero values",
  31. inputMessage: &pb2.Scalars{},
  32. inputText: `opt_bool: false
  33. opt_int32: 0
  34. opt_int64: 0
  35. opt_uint32: 0
  36. opt_uint64: 0
  37. opt_sint32: 0
  38. opt_sint64: 0
  39. opt_fixed32: 0
  40. opt_fixed64: 0
  41. opt_sfixed32: 0
  42. opt_sfixed64: 0
  43. opt_float: 0
  44. opt_double: 0
  45. opt_bytes: ""
  46. opt_string: ""
  47. `,
  48. wantMessage: &pb2.Scalars{
  49. OptBool: scalar.Bool(false),
  50. OptInt32: scalar.Int32(0),
  51. OptInt64: scalar.Int64(0),
  52. OptUint32: scalar.Uint32(0),
  53. OptUint64: scalar.Uint64(0),
  54. OptSint32: scalar.Int32(0),
  55. OptSint64: scalar.Int64(0),
  56. OptFixed32: scalar.Uint32(0),
  57. OptFixed64: scalar.Uint64(0),
  58. OptSfixed32: scalar.Int32(0),
  59. OptSfixed64: scalar.Int64(0),
  60. OptFloat: scalar.Float32(0),
  61. OptDouble: scalar.Float64(0),
  62. OptBytes: []byte{},
  63. OptString: scalar.String(""),
  64. },
  65. }, {
  66. desc: "proto3 scalars set to zero values",
  67. inputMessage: &pb3.Scalars{},
  68. inputText: `s_bool: false
  69. s_int32: 0
  70. s_int64: 0
  71. s_uint32: 0
  72. s_uint64: 0
  73. s_sint32: 0
  74. s_sint64: 0
  75. s_fixed32: 0
  76. s_fixed64: 0
  77. s_sfixed32: 0
  78. s_sfixed64: 0
  79. s_float: 0
  80. s_double: 0
  81. s_bytes: ""
  82. s_string: ""
  83. `,
  84. wantMessage: &pb3.Scalars{},
  85. }, {
  86. desc: "proto2 optional scalars",
  87. inputMessage: &pb2.Scalars{},
  88. inputText: `opt_bool: true
  89. opt_int32: 255
  90. opt_int64: 3735928559
  91. opt_uint32: 0xff
  92. opt_uint64: 0xdeadbeef
  93. opt_sint32: -1001
  94. opt_sint64: -0xffff
  95. opt_fixed64: 64
  96. opt_sfixed32: -32
  97. opt_float: 1.234
  98. opt_double: 1.23e+100
  99. opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
  100. opt_string: "谷歌"
  101. `,
  102. wantMessage: &pb2.Scalars{
  103. OptBool: scalar.Bool(true),
  104. OptInt32: scalar.Int32(0xff),
  105. OptInt64: scalar.Int64(0xdeadbeef),
  106. OptUint32: scalar.Uint32(0xff),
  107. OptUint64: scalar.Uint64(0xdeadbeef),
  108. OptSint32: scalar.Int32(-1001),
  109. OptSint64: scalar.Int64(-0xffff),
  110. OptFixed64: scalar.Uint64(64),
  111. OptSfixed32: scalar.Int32(-32),
  112. OptFloat: scalar.Float32(1.234),
  113. OptDouble: scalar.Float64(1.23e100),
  114. OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
  115. OptString: scalar.String("谷歌"),
  116. },
  117. }, {
  118. desc: "case sensitive",
  119. inputMessage: &pb3.Scalars{},
  120. inputText: `S_BOOL: true`,
  121. wantErr: true,
  122. }, {
  123. desc: "proto3 scalars",
  124. inputMessage: &pb3.Scalars{},
  125. inputText: `s_bool: true
  126. s_int32: 255
  127. s_int64: 3735928559
  128. s_uint32: 0xff
  129. s_uint64: 0xdeadbeef
  130. s_sint32: -1001
  131. s_sint64: -0xffff
  132. s_fixed64: 64
  133. s_sfixed32: -32
  134. s_float: 1.234
  135. s_double: 1.23e+100
  136. s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
  137. s_string: "谷歌"
  138. `,
  139. wantMessage: &pb3.Scalars{
  140. SBool: true,
  141. SInt32: 0xff,
  142. SInt64: 0xdeadbeef,
  143. SUint32: 0xff,
  144. SUint64: 0xdeadbeef,
  145. SSint32: -1001,
  146. SSint64: -0xffff,
  147. SFixed64: 64,
  148. SSfixed32: -32,
  149. SFloat: 1.234,
  150. SDouble: 1.23e100,
  151. SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
  152. SString: "谷歌",
  153. },
  154. }, {
  155. desc: "string with invalid UTF-8",
  156. inputMessage: &pb3.Scalars{},
  157. inputText: `s_string: "abc\xff"`,
  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: pb2.Enum(101).Enum(),
  351. OptNestedEnum: pb2.Enums_NestedEnum(-101).Enum(),
  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: "group field name",
  407. inputMessage: &pb2.Nests{},
  408. inputText: `optgroup: {}`,
  409. wantErr: true,
  410. }, {
  411. desc: "proto2 nested messages",
  412. inputMessage: &pb2.Nests{},
  413. inputText: `
  414. opt_nested: {
  415. opt_string: "nested message"
  416. opt_nested: {
  417. opt_string: "another nested message"
  418. }
  419. }
  420. `,
  421. wantMessage: &pb2.Nests{
  422. OptNested: &pb2.Nested{
  423. OptString: scalar.String("nested message"),
  424. OptNested: &pb2.Nested{
  425. OptString: scalar.String("another nested message"),
  426. },
  427. },
  428. },
  429. }, {
  430. desc: "proto3 nested empty message",
  431. inputMessage: &pb3.Nests{},
  432. inputText: "s_nested: {}",
  433. wantMessage: &pb3.Nests{
  434. SNested: &pb3.Nested{},
  435. },
  436. }, {
  437. desc: "proto3 nested message",
  438. inputMessage: &pb3.Nests{},
  439. inputText: `
  440. s_nested: {
  441. s_string: "nested message"
  442. s_nested: {
  443. s_string: "another nested message"
  444. }
  445. }
  446. `,
  447. wantMessage: &pb3.Nests{
  448. SNested: &pb3.Nested{
  449. SString: "nested message",
  450. SNested: &pb3.Nested{
  451. SString: "another nested message",
  452. },
  453. },
  454. },
  455. }, {
  456. desc: "proto3 nested message contains invalid UTF-8",
  457. inputMessage: &pb3.Nests{},
  458. inputText: `s_nested: {
  459. s_string: "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. wantErr: true,
  555. }, {
  556. desc: "repeated enums",
  557. inputMessage: &pb2.Enums{},
  558. inputText: `
  559. rpt_enum: TEN
  560. rpt_enum: 1
  561. rpt_nested_enum: [DOS, 2]
  562. rpt_enum: 42
  563. rpt_nested_enum: -47
  564. `,
  565. wantMessage: &pb2.Enums{
  566. RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
  567. RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
  568. },
  569. }, {
  570. desc: "repeated nested messages",
  571. inputMessage: &pb2.Nests{},
  572. inputText: `
  573. rpt_nested: {
  574. opt_string: "repeat nested one"
  575. }
  576. rpt_nested: {
  577. opt_string: "repeat nested two"
  578. opt_nested: {
  579. opt_string: "inside repeat nested two"
  580. }
  581. }
  582. rpt_nested: {}
  583. `,
  584. wantMessage: &pb2.Nests{
  585. RptNested: []*pb2.Nested{
  586. {
  587. OptString: scalar.String("repeat nested one"),
  588. },
  589. {
  590. OptString: scalar.String("repeat nested two"),
  591. OptNested: &pb2.Nested{
  592. OptString: scalar.String("inside repeat nested two"),
  593. },
  594. },
  595. {},
  596. },
  597. },
  598. }, {
  599. desc: "repeated group fields",
  600. inputMessage: &pb2.Nests{},
  601. inputText: `
  602. RptGroup: {
  603. rpt_string: "hello"
  604. rpt_string: "world"
  605. }
  606. RptGroup: {}
  607. `,
  608. wantMessage: &pb2.Nests{
  609. Rptgroup: []*pb2.Nests_RptGroup{
  610. {
  611. RptString: []string{"hello", "world"},
  612. },
  613. {},
  614. },
  615. },
  616. }, {
  617. desc: "map fields 1",
  618. inputMessage: &pb3.Maps{},
  619. inputText: `
  620. int32_to_str: {
  621. key: -101
  622. value: "-101"
  623. }
  624. int32_to_str: {
  625. key: 0
  626. value: "zero"
  627. }
  628. bool_to_uint32: {
  629. key: false
  630. value: 101
  631. }
  632. int32_to_str: {
  633. key: 255
  634. value: "0xff"
  635. }
  636. bool_to_uint32: {
  637. key: true
  638. value: 42
  639. }
  640. `,
  641. wantMessage: &pb3.Maps{
  642. Int32ToStr: map[int32]string{
  643. -101: "-101",
  644. 0xff: "0xff",
  645. 0: "zero",
  646. },
  647. BoolToUint32: map[bool]uint32{
  648. true: 42,
  649. false: 101,
  650. },
  651. },
  652. }, {
  653. desc: "map fields 2",
  654. inputMessage: &pb3.Maps{},
  655. inputText: `
  656. uint64_to_enum: {
  657. key: 1
  658. value: ONE
  659. }
  660. uint64_to_enum: {
  661. key: 2
  662. value: 2
  663. }
  664. uint64_to_enum: {
  665. key: 10
  666. value: 101
  667. }
  668. `,
  669. wantMessage: &pb3.Maps{
  670. Uint64ToEnum: map[uint64]pb3.Enum{
  671. 1: pb3.Enum_ONE,
  672. 2: pb3.Enum_TWO,
  673. 10: 101,
  674. },
  675. },
  676. }, {
  677. desc: "map fields 3",
  678. inputMessage: &pb3.Maps{},
  679. inputText: `
  680. str_to_nested: {
  681. key: "nested_one"
  682. value: {
  683. s_string: "nested in a map"
  684. }
  685. }
  686. `,
  687. wantMessage: &pb3.Maps{
  688. StrToNested: map[string]*pb3.Nested{
  689. "nested_one": &pb3.Nested{
  690. SString: "nested in a map",
  691. },
  692. },
  693. },
  694. }, {
  695. desc: "map fields 4",
  696. inputMessage: &pb3.Maps{},
  697. inputText: `
  698. str_to_oneofs: {
  699. key: "nested"
  700. value: {
  701. oneof_nested: {
  702. s_string: "nested oneof in map field value"
  703. }
  704. }
  705. }
  706. str_to_oneofs: {
  707. key: "string"
  708. value: {
  709. oneof_string: "hello"
  710. }
  711. }
  712. `,
  713. wantMessage: &pb3.Maps{
  714. StrToOneofs: map[string]*pb3.Oneofs{
  715. "string": &pb3.Oneofs{
  716. Union: &pb3.Oneofs_OneofString{
  717. OneofString: "hello",
  718. },
  719. },
  720. "nested": &pb3.Oneofs{
  721. Union: &pb3.Oneofs_OneofNested{
  722. OneofNested: &pb3.Nested{
  723. SString: "nested oneof in map field value",
  724. },
  725. },
  726. },
  727. },
  728. },
  729. }, {
  730. desc: "map contains duplicate keys",
  731. inputMessage: &pb3.Maps{},
  732. inputText: `
  733. int32_to_str: {
  734. key: 0
  735. value: "cero"
  736. }
  737. int32_to_str: {
  738. key: 0
  739. value: "zero"
  740. }
  741. `,
  742. wantMessage: &pb3.Maps{
  743. Int32ToStr: map[int32]string{
  744. 0: "zero",
  745. },
  746. },
  747. }, {
  748. desc: "map contains duplicate key fields",
  749. inputMessage: &pb3.Maps{},
  750. inputText: `
  751. int32_to_str: {
  752. key: 0
  753. key: 1
  754. value: "cero"
  755. }
  756. `,
  757. wantErr: true,
  758. }, {
  759. desc: "map contains duplicate value fields",
  760. inputMessage: &pb3.Maps{},
  761. inputText: `
  762. int32_to_str: {
  763. key: 1
  764. value: "cero"
  765. value: "uno"
  766. }
  767. `,
  768. wantErr: true,
  769. }, {
  770. desc: "map contains missing key",
  771. inputMessage: &pb3.Maps{},
  772. inputText: `
  773. int32_to_str: {
  774. value: "zero"
  775. }
  776. bool_to_uint32: {
  777. value: 47
  778. }
  779. str_to_nested: {
  780. value: {}
  781. }
  782. `,
  783. wantMessage: &pb3.Maps{
  784. Int32ToStr: map[int32]string{
  785. 0: "zero",
  786. },
  787. BoolToUint32: map[bool]uint32{
  788. false: 47,
  789. },
  790. StrToNested: map[string]*pb3.Nested{
  791. "": {},
  792. },
  793. },
  794. }, {
  795. desc: "map contains missing value",
  796. inputMessage: &pb3.Maps{},
  797. inputText: `
  798. int32_to_str: {
  799. key: 100
  800. }
  801. bool_to_uint32: {
  802. key: true
  803. }
  804. uint64_to_enum: {
  805. key: 101
  806. }
  807. str_to_nested: {
  808. key: "hello"
  809. }
  810. `,
  811. wantMessage: &pb3.Maps{
  812. Int32ToStr: map[int32]string{
  813. 100: "",
  814. },
  815. BoolToUint32: map[bool]uint32{
  816. true: 0,
  817. },
  818. Uint64ToEnum: map[uint64]pb3.Enum{
  819. 101: pb3.Enum_ZERO,
  820. },
  821. StrToNested: map[string]*pb3.Nested{
  822. "hello": {},
  823. },
  824. },
  825. }, {
  826. desc: "map contains missing key and value",
  827. inputMessage: &pb3.Maps{},
  828. inputText: `
  829. int32_to_str: {}
  830. bool_to_uint32: {}
  831. uint64_to_enum: {}
  832. str_to_nested: {}
  833. `,
  834. wantMessage: &pb3.Maps{
  835. Int32ToStr: map[int32]string{
  836. 0: "",
  837. },
  838. BoolToUint32: map[bool]uint32{
  839. false: 0,
  840. },
  841. Uint64ToEnum: map[uint64]pb3.Enum{
  842. 0: pb3.Enum_ZERO,
  843. },
  844. StrToNested: map[string]*pb3.Nested{
  845. "": {},
  846. },
  847. },
  848. }, {
  849. desc: "map contains overriding entries",
  850. inputMessage: &pb3.Maps{},
  851. inputText: `
  852. int32_to_str: {
  853. key: 0
  854. }
  855. int32_to_str: {
  856. value: "empty"
  857. }
  858. int32_to_str: {}
  859. `,
  860. wantMessage: &pb3.Maps{
  861. Int32ToStr: map[int32]string{
  862. 0: "",
  863. },
  864. },
  865. }, {
  866. desc: "map field value contains invalid UTF-8",
  867. inputMessage: &pb3.Maps{},
  868. inputText: `int32_to_str: {
  869. key: 101
  870. value: "abc\xff"
  871. }
  872. `,
  873. wantErr: true,
  874. }, {
  875. desc: "map field key contains invalid UTF-8",
  876. inputMessage: &pb3.Maps{},
  877. inputText: `str_to_nested: {
  878. key: "abc\xff"
  879. value: {}
  880. }
  881. `,
  882. wantErr: true,
  883. }, {
  884. desc: "map contains unknown field",
  885. inputMessage: &pb3.Maps{},
  886. inputText: `
  887. int32_to_str: {
  888. key: 0
  889. value: "cero"
  890. unknown: "bad"
  891. }
  892. `,
  893. wantErr: true,
  894. }, {
  895. desc: "map contains extension-like key field",
  896. inputMessage: &pb3.Maps{},
  897. inputText: `
  898. int32_to_str: {
  899. [key]: 10
  900. value: "ten"
  901. }
  902. `,
  903. wantErr: true,
  904. }, {
  905. desc: "map contains invalid key",
  906. inputMessage: &pb3.Maps{},
  907. inputText: `
  908. int32_to_str: {
  909. key: "invalid"
  910. value: "cero"
  911. }
  912. `,
  913. wantErr: true,
  914. }, {
  915. desc: "map contains invalid value",
  916. inputMessage: &pb3.Maps{},
  917. inputText: `
  918. int32_to_str: {
  919. key: 100
  920. value: 101
  921. }
  922. `,
  923. wantErr: true,
  924. }, {
  925. desc: "map using mix of [] and repeated",
  926. inputMessage: &pb3.Maps{},
  927. inputText: `
  928. int32_to_str: {
  929. key: 1
  930. value: "one"
  931. }
  932. int32_to_str: [
  933. {
  934. key: 2
  935. value: "not this"
  936. },
  937. {
  938. },
  939. {
  940. key: 3
  941. value: "three"
  942. }
  943. ]
  944. int32_to_str: {
  945. key: 2
  946. value: "two"
  947. }
  948. `,
  949. wantMessage: &pb3.Maps{
  950. Int32ToStr: map[int32]string{
  951. 0: "",
  952. 1: "one",
  953. 2: "two",
  954. 3: "three",
  955. },
  956. },
  957. }, {
  958. desc: "required fields not set",
  959. inputMessage: &pb2.Requireds{},
  960. wantErr: true,
  961. }, {
  962. desc: "required field set",
  963. inputMessage: &pb2.PartialRequired{},
  964. inputText: "req_string: 'this is required'",
  965. wantMessage: &pb2.PartialRequired{
  966. ReqString: scalar.String("this is required"),
  967. },
  968. }, {
  969. desc: "required fields partially set",
  970. inputMessage: &pb2.Requireds{},
  971. inputText: `
  972. req_bool: false
  973. req_sfixed64: 3203386110
  974. req_string: "hello"
  975. req_enum: ONE
  976. `,
  977. wantMessage: &pb2.Requireds{
  978. ReqBool: scalar.Bool(false),
  979. ReqSfixed64: scalar.Int64(0xbeefcafe),
  980. ReqString: scalar.String("hello"),
  981. ReqEnum: pb2.Enum_ONE.Enum(),
  982. },
  983. wantErr: true,
  984. }, {
  985. desc: "required fields partially set with AllowPartial",
  986. umo: prototext.UnmarshalOptions{AllowPartial: true},
  987. inputMessage: &pb2.Requireds{},
  988. inputText: `
  989. req_bool: false
  990. req_sfixed64: 3203386110
  991. req_string: "hello"
  992. req_enum: ONE
  993. `,
  994. wantMessage: &pb2.Requireds{
  995. ReqBool: scalar.Bool(false),
  996. ReqSfixed64: scalar.Int64(0xbeefcafe),
  997. ReqString: scalar.String("hello"),
  998. ReqEnum: pb2.Enum_ONE.Enum(),
  999. },
  1000. }, {
  1001. desc: "required fields all set",
  1002. inputMessage: &pb2.Requireds{},
  1003. inputText: `
  1004. req_bool: false
  1005. req_sfixed64: 0
  1006. req_double: 0
  1007. req_string: ""
  1008. req_enum: ONE
  1009. req_nested: {}
  1010. `,
  1011. wantMessage: &pb2.Requireds{
  1012. ReqBool: scalar.Bool(false),
  1013. ReqSfixed64: scalar.Int64(0),
  1014. ReqDouble: scalar.Float64(0),
  1015. ReqString: scalar.String(""),
  1016. ReqEnum: pb2.Enum_ONE.Enum(),
  1017. ReqNested: &pb2.Nested{},
  1018. },
  1019. }, {
  1020. desc: "indirect required field",
  1021. inputMessage: &pb2.IndirectRequired{},
  1022. inputText: "opt_nested: {}",
  1023. wantMessage: &pb2.IndirectRequired{
  1024. OptNested: &pb2.NestedWithRequired{},
  1025. },
  1026. wantErr: true,
  1027. }, {
  1028. desc: "indirect required field with AllowPartial",
  1029. umo: prototext.UnmarshalOptions{AllowPartial: true},
  1030. inputMessage: &pb2.IndirectRequired{},
  1031. inputText: "opt_nested: {}",
  1032. wantMessage: &pb2.IndirectRequired{
  1033. OptNested: &pb2.NestedWithRequired{},
  1034. },
  1035. }, {
  1036. desc: "indirect required field in repeated",
  1037. inputMessage: &pb2.IndirectRequired{},
  1038. inputText: `
  1039. rpt_nested: {
  1040. req_string: "one"
  1041. }
  1042. rpt_nested: {}
  1043. `,
  1044. wantMessage: &pb2.IndirectRequired{
  1045. RptNested: []*pb2.NestedWithRequired{
  1046. {
  1047. ReqString: scalar.String("one"),
  1048. },
  1049. {},
  1050. },
  1051. },
  1052. wantErr: true,
  1053. }, {
  1054. desc: "indirect required field in repeated with AllowPartial",
  1055. umo: prototext.UnmarshalOptions{AllowPartial: true},
  1056. inputMessage: &pb2.IndirectRequired{},
  1057. inputText: `
  1058. rpt_nested: {
  1059. req_string: "one"
  1060. }
  1061. rpt_nested: {}
  1062. `,
  1063. wantMessage: &pb2.IndirectRequired{
  1064. RptNested: []*pb2.NestedWithRequired{
  1065. {
  1066. ReqString: scalar.String("one"),
  1067. },
  1068. {},
  1069. },
  1070. },
  1071. }, {
  1072. desc: "indirect required field in map",
  1073. inputMessage: &pb2.IndirectRequired{},
  1074. inputText: `
  1075. str_to_nested: {
  1076. key: "missing"
  1077. }
  1078. str_to_nested: {
  1079. key: "contains"
  1080. value: {
  1081. req_string: "here"
  1082. }
  1083. }
  1084. `,
  1085. wantMessage: &pb2.IndirectRequired{
  1086. StrToNested: map[string]*pb2.NestedWithRequired{
  1087. "missing": &pb2.NestedWithRequired{},
  1088. "contains": &pb2.NestedWithRequired{
  1089. ReqString: scalar.String("here"),
  1090. },
  1091. },
  1092. },
  1093. wantErr: true,
  1094. }, {
  1095. desc: "indirect required field in map with AllowPartial",
  1096. umo: prototext.UnmarshalOptions{AllowPartial: true},
  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: scalar.String("here"),
  1114. },
  1115. },
  1116. },
  1117. }, {
  1118. desc: "indirect required field in oneof",
  1119. inputMessage: &pb2.IndirectRequired{},
  1120. inputText: `oneof_nested: {}
  1121. `,
  1122. wantMessage: &pb2.IndirectRequired{
  1123. Union: &pb2.IndirectRequired_OneofNested{
  1124. OneofNested: &pb2.NestedWithRequired{},
  1125. },
  1126. },
  1127. wantErr: true,
  1128. }, {
  1129. desc: "indirect required field in oneof with AllowPartial",
  1130. umo: prototext.UnmarshalOptions{AllowPartial: true},
  1131. inputMessage: &pb2.IndirectRequired{},
  1132. inputText: `oneof_nested: {}
  1133. `,
  1134. wantMessage: &pb2.IndirectRequired{
  1135. Union: &pb2.IndirectRequired_OneofNested{
  1136. OneofNested: &pb2.NestedWithRequired{},
  1137. },
  1138. },
  1139. }, {
  1140. desc: "ignore reserved field",
  1141. inputMessage: &pb2.Nests{},
  1142. inputText: "reserved_field: 'ignore this'",
  1143. wantMessage: &pb2.Nests{},
  1144. }, {
  1145. desc: "extensions of non-repeated fields",
  1146. inputMessage: &pb2.Extensions{},
  1147. inputText: `opt_string: "non-extension field"
  1148. [pb2.opt_ext_bool]: true
  1149. opt_bool: true
  1150. [pb2.opt_ext_nested]: {
  1151. opt_string: "nested in an extension"
  1152. opt_nested: {
  1153. opt_string: "another nested in an extension"
  1154. }
  1155. }
  1156. [pb2.opt_ext_string]: "extension field"
  1157. opt_int32: 42
  1158. [pb2.opt_ext_enum]: TEN
  1159. `,
  1160. wantMessage: func() proto.Message {
  1161. m := &pb2.Extensions{
  1162. OptString: scalar.String("non-extension field"),
  1163. OptBool: scalar.Bool(true),
  1164. OptInt32: scalar.Int32(42),
  1165. }
  1166. setExtension(m, pb2.E_OptExtBool, true)
  1167. setExtension(m, pb2.E_OptExtString, "extension field")
  1168. setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
  1169. setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
  1170. OptString: scalar.String("nested in an extension"),
  1171. OptNested: &pb2.Nested{
  1172. OptString: scalar.String("another nested in an extension"),
  1173. },
  1174. })
  1175. return m
  1176. }(),
  1177. }, {
  1178. desc: "extension field contains invalid UTF-8",
  1179. inputMessage: &pb2.Extensions{},
  1180. inputText: `[pb2.opt_ext_string]: "abc\xff"`,
  1181. wantErr: true,
  1182. }, {
  1183. desc: "extensions of repeated fields",
  1184. inputMessage: &pb2.Extensions{},
  1185. inputText: `[pb2.rpt_ext_enum]: TEN
  1186. [pb2.rpt_ext_enum]: 101
  1187. [pb2.rpt_ext_fixed32]: 42
  1188. [pb2.rpt_ext_enum]: ONE
  1189. [pb2.rpt_ext_nested]: {
  1190. opt_string: "one"
  1191. }
  1192. [pb2.rpt_ext_nested]: {
  1193. opt_string: "two"
  1194. }
  1195. [pb2.rpt_ext_fixed32]: 47
  1196. [pb2.rpt_ext_nested]: {
  1197. opt_string: "three"
  1198. }
  1199. `,
  1200. wantMessage: func() proto.Message {
  1201. m := &pb2.Extensions{}
  1202. setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
  1203. setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
  1204. setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
  1205. &pb2.Nested{OptString: scalar.String("one")},
  1206. &pb2.Nested{OptString: scalar.String("two")},
  1207. &pb2.Nested{OptString: scalar.String("three")},
  1208. })
  1209. return m
  1210. }(),
  1211. }, {
  1212. desc: "extensions of non-repeated fields in another message",
  1213. inputMessage: &pb2.Extensions{},
  1214. inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
  1215. [pb2.ExtensionsContainer.opt_ext_enum]: TEN
  1216. [pb2.ExtensionsContainer.opt_ext_nested]: {
  1217. opt_string: "nested in an extension"
  1218. opt_nested: {
  1219. opt_string: "another nested in an extension"
  1220. }
  1221. }
  1222. [pb2.ExtensionsContainer.opt_ext_string]: "extension field"
  1223. `,
  1224. wantMessage: func() proto.Message {
  1225. m := &pb2.Extensions{}
  1226. setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
  1227. setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
  1228. setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
  1229. setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
  1230. OptString: scalar.String("nested in an extension"),
  1231. OptNested: &pb2.Nested{
  1232. OptString: scalar.String("another nested in an extension"),
  1233. },
  1234. })
  1235. return m
  1236. }(),
  1237. }, {
  1238. desc: "extensions of repeated fields in another message",
  1239. inputMessage: &pb2.Extensions{},
  1240. inputText: `opt_string: "non-extension field"
  1241. opt_bool: true
  1242. opt_int32: 42
  1243. [pb2.ExtensionsContainer.rpt_ext_nested]: {
  1244. opt_string: "one"
  1245. }
  1246. [pb2.ExtensionsContainer.rpt_ext_enum]: TEN
  1247. [pb2.ExtensionsContainer.rpt_ext_nested]: {
  1248. opt_string: "two"
  1249. }
  1250. [pb2.ExtensionsContainer.rpt_ext_enum]: 101
  1251. [pb2.ExtensionsContainer.rpt_ext_string]: "hello"
  1252. [pb2.ExtensionsContainer.rpt_ext_enum]: ONE
  1253. [pb2.ExtensionsContainer.rpt_ext_nested]: {
  1254. opt_string: "three"
  1255. }
  1256. [pb2.ExtensionsContainer.rpt_ext_string]: "world"
  1257. `,
  1258. wantMessage: func() proto.Message {
  1259. m := &pb2.Extensions{
  1260. OptString: scalar.String("non-extension field"),
  1261. OptBool: scalar.Bool(true),
  1262. OptInt32: scalar.Int32(42),
  1263. }
  1264. setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
  1265. setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
  1266. setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
  1267. &pb2.Nested{OptString: scalar.String("one")},
  1268. &pb2.Nested{OptString: scalar.String("two")},
  1269. &pb2.Nested{OptString: scalar.String("three")},
  1270. })
  1271. return m
  1272. }(),
  1273. }, {
  1274. desc: "invalid extension field name",
  1275. inputMessage: &pb2.Extensions{},
  1276. inputText: "[pb2.invalid_message_field]: true",
  1277. wantErr: true,
  1278. }, {
  1279. desc: "MessageSet",
  1280. inputMessage: &pb2.MessageSet{},
  1281. inputText: `
  1282. [pb2.MessageSetExtension]: {
  1283. opt_string: "a messageset extension"
  1284. }
  1285. [pb2.MessageSetExtension.ext_nested]: {
  1286. opt_string: "just a regular extension"
  1287. }
  1288. [pb2.MessageSetExtension.not_message_set_extension]: {
  1289. opt_string: "not a messageset extension"
  1290. }
  1291. `,
  1292. wantMessage: func() proto.Message {
  1293. m := &pb2.MessageSet{}
  1294. setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
  1295. OptString: scalar.String("a messageset extension"),
  1296. })
  1297. setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
  1298. OptString: scalar.String("not a messageset extension"),
  1299. })
  1300. setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
  1301. OptString: scalar.String("just a regular extension"),
  1302. })
  1303. return m
  1304. }(),
  1305. }, {
  1306. desc: "not real MessageSet 1",
  1307. inputMessage: &pb2.FakeMessageSet{},
  1308. inputText: `
  1309. [pb2.FakeMessageSetExtension.message_set_extension]: {
  1310. opt_string: "not a messageset extension"
  1311. }
  1312. `,
  1313. wantMessage: func() proto.Message {
  1314. m := &pb2.FakeMessageSet{}
  1315. setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
  1316. OptString: scalar.String("not a messageset extension"),
  1317. })
  1318. return m
  1319. }(),
  1320. }, {
  1321. desc: "not real MessageSet 2",
  1322. inputMessage: &pb2.FakeMessageSet{},
  1323. inputText: `
  1324. [pb2.FakeMessageSetExtension]: {
  1325. opt_string: "not a messageset extension"
  1326. }
  1327. `,
  1328. wantErr: true,
  1329. }, {
  1330. desc: "not real MessageSet 3",
  1331. inputMessage: &pb2.MessageSet{},
  1332. inputText: `
  1333. [pb2.message_set_extension]: {
  1334. opt_string: "another not a messageset extension"
  1335. }`,
  1336. wantMessage: func() proto.Message {
  1337. m := &pb2.MessageSet{}
  1338. setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
  1339. OptString: scalar.String("another not a messageset extension"),
  1340. })
  1341. return m
  1342. }(),
  1343. }, {
  1344. desc: "Any not expanded",
  1345. inputMessage: &anypb.Any{},
  1346. inputText: `
  1347. type_url: "pb2.Nested"
  1348. value: "some bytes"
  1349. `,
  1350. wantMessage: &anypb.Any{
  1351. TypeUrl: "pb2.Nested",
  1352. Value: []byte("some bytes"),
  1353. },
  1354. }, {
  1355. desc: "Any not expanded missing value",
  1356. inputMessage: &anypb.Any{},
  1357. inputText: `type_url: "pb2.Nested"`,
  1358. wantMessage: &anypb.Any{
  1359. TypeUrl: "pb2.Nested",
  1360. },
  1361. }, {
  1362. desc: "Any not expanded missing type_url",
  1363. inputMessage: &anypb.Any{},
  1364. inputText: `value: "some bytes"`,
  1365. wantMessage: &anypb.Any{
  1366. Value: []byte("some bytes"),
  1367. },
  1368. }, {
  1369. desc: "Any expanded",
  1370. umo: prototext.UnmarshalOptions{
  1371. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
  1372. },
  1373. inputMessage: &anypb.Any{},
  1374. inputText: `
  1375. [foobar/pb2.Nested]: {
  1376. opt_string: "embedded inside Any"
  1377. opt_nested: {
  1378. opt_string: "inception"
  1379. }
  1380. }
  1381. `,
  1382. wantMessage: func() proto.Message {
  1383. m := &pb2.Nested{
  1384. OptString: scalar.String("embedded inside Any"),
  1385. OptNested: &pb2.Nested{
  1386. OptString: scalar.String("inception"),
  1387. },
  1388. }
  1389. b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
  1390. if err != nil {
  1391. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  1392. }
  1393. return &anypb.Any{
  1394. TypeUrl: "foobar/pb2.Nested",
  1395. Value: b,
  1396. }
  1397. }(),
  1398. }, {
  1399. desc: "Any expanded with empty value",
  1400. umo: prototext.UnmarshalOptions{
  1401. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
  1402. },
  1403. inputMessage: &anypb.Any{},
  1404. inputText: `[foo.com/pb2.Nested]: {}`,
  1405. wantMessage: &anypb.Any{
  1406. TypeUrl: "foo.com/pb2.Nested",
  1407. },
  1408. }, {
  1409. desc: "Any expanded with missing required",
  1410. umo: prototext.UnmarshalOptions{
  1411. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
  1412. },
  1413. inputMessage: &anypb.Any{},
  1414. inputText: `
  1415. [pb2.PartialRequired]: {
  1416. opt_string: "embedded inside Any"
  1417. }
  1418. `,
  1419. wantMessage: func() proto.Message {
  1420. m := &pb2.PartialRequired{
  1421. OptString: scalar.String("embedded inside Any"),
  1422. }
  1423. b, err := proto.MarshalOptions{
  1424. AllowPartial: true,
  1425. Deterministic: true,
  1426. }.Marshal(m)
  1427. if err != nil {
  1428. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  1429. }
  1430. return &anypb.Any{
  1431. TypeUrl: "pb2.PartialRequired",
  1432. Value: b,
  1433. }
  1434. }(),
  1435. }, {
  1436. desc: "Any with invalid UTF-8",
  1437. umo: prototext.UnmarshalOptions{
  1438. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb3.Nested{})),
  1439. },
  1440. inputMessage: &anypb.Any{},
  1441. inputText: `
  1442. [pb3.Nested]: {
  1443. s_string: "abc\xff"
  1444. }
  1445. `,
  1446. wantErr: true,
  1447. }, {
  1448. desc: "Any expanded with unregistered type",
  1449. umo: prototext.UnmarshalOptions{Resolver: preg.NewTypes()},
  1450. inputMessage: &anypb.Any{},
  1451. inputText: `[SomeMessage]: {}`,
  1452. wantErr: true,
  1453. }, {
  1454. desc: "Any expanded with invalid value",
  1455. umo: prototext.UnmarshalOptions{
  1456. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
  1457. },
  1458. inputMessage: &anypb.Any{},
  1459. inputText: `[pb2.Nested]: 123`,
  1460. wantErr: true,
  1461. }, {
  1462. desc: "Any expanded with unknown fields",
  1463. umo: prototext.UnmarshalOptions{
  1464. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
  1465. },
  1466. inputMessage: &anypb.Any{},
  1467. inputText: `
  1468. [pb2.Nested]: {}
  1469. unknown: ""
  1470. `,
  1471. wantErr: true,
  1472. }, {
  1473. desc: "Any contains expanded and unexpanded fields",
  1474. umo: prototext.UnmarshalOptions{
  1475. Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
  1476. },
  1477. inputMessage: &anypb.Any{},
  1478. inputText: `
  1479. [pb2.Nested]: {}
  1480. type_url: "pb2.Nested"
  1481. `,
  1482. wantErr: true,
  1483. }}
  1484. for _, tt := range tests {
  1485. tt := tt
  1486. t.Run(tt.desc, func(t *testing.T) {
  1487. err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
  1488. if err != nil && !tt.wantErr {
  1489. t.Errorf("Unmarshal() returned error: %v\n\n", err)
  1490. }
  1491. if err == nil && tt.wantErr {
  1492. t.Error("Unmarshal() got nil error, want error\n\n")
  1493. }
  1494. if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
  1495. t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
  1496. }
  1497. })
  1498. }
  1499. }