decode_test.go 34 KB

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