decode_test.go 33 KB

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