descriptor_test.py 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047
  1. #! /usr/bin/env python
  2. #
  3. # Protocol Buffers - Google's data interchange format
  4. # Copyright 2008 Google Inc. All rights reserved.
  5. # https://developers.google.com/protocol-buffers/
  6. #
  7. # Redistribution and use in source and binary forms, with or without
  8. # modification, are permitted provided that the following conditions are
  9. # met:
  10. #
  11. # * Redistributions of source code must retain the above copyright
  12. # notice, this list of conditions and the following disclaimer.
  13. # * Redistributions in binary form must reproduce the above
  14. # copyright notice, this list of conditions and the following disclaimer
  15. # in the documentation and/or other materials provided with the
  16. # distribution.
  17. # * Neither the name of Google Inc. nor the names of its
  18. # contributors may be used to endorse or promote products derived from
  19. # this software without specific prior written permission.
  20. #
  21. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. """Unittest for google.protobuf.internal.descriptor."""
  33. __author__ = 'robinson@google.com (Will Robinson)'
  34. import sys
  35. try:
  36. import unittest2 as unittest #PY26
  37. except ImportError:
  38. import unittest
  39. from google.protobuf import unittest_custom_options_pb2
  40. from google.protobuf import unittest_import_pb2
  41. from google.protobuf import unittest_pb2
  42. from google.protobuf import descriptor_pb2
  43. from google.protobuf.internal import api_implementation
  44. from google.protobuf.internal import test_util
  45. from google.protobuf import descriptor
  46. from google.protobuf import descriptor_pool
  47. from google.protobuf import symbol_database
  48. from google.protobuf import text_format
  49. TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII = """
  50. name: 'TestEmptyMessage'
  51. """
  52. class DescriptorTest(unittest.TestCase):
  53. def setUp(self):
  54. file_proto = descriptor_pb2.FileDescriptorProto(
  55. name='some/filename/some.proto',
  56. package='protobuf_unittest')
  57. message_proto = file_proto.message_type.add(
  58. name='NestedMessage')
  59. message_proto.field.add(
  60. name='bb',
  61. number=1,
  62. type=descriptor_pb2.FieldDescriptorProto.TYPE_INT32,
  63. label=descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL)
  64. enum_proto = message_proto.enum_type.add(
  65. name='ForeignEnum')
  66. enum_proto.value.add(name='FOREIGN_FOO', number=4)
  67. enum_proto.value.add(name='FOREIGN_BAR', number=5)
  68. enum_proto.value.add(name='FOREIGN_BAZ', number=6)
  69. file_proto.message_type.add(name='ResponseMessage')
  70. service_proto = file_proto.service.add(
  71. name='Service')
  72. method_proto = service_proto.method.add(
  73. name='CallMethod',
  74. input_type='.protobuf_unittest.NestedMessage',
  75. output_type='.protobuf_unittest.ResponseMessage')
  76. # Note: Calling DescriptorPool.Add() multiple times with the same file only
  77. # works if the input is canonical; in particular, all type names must be
  78. # fully qualified.
  79. self.pool = self.GetDescriptorPool()
  80. self.pool.Add(file_proto)
  81. self.my_file = self.pool.FindFileByName(file_proto.name)
  82. self.my_message = self.my_file.message_types_by_name[message_proto.name]
  83. self.my_enum = self.my_message.enum_types_by_name[enum_proto.name]
  84. self.my_service = self.my_file.services_by_name[service_proto.name]
  85. self.my_method = self.my_service.methods_by_name[method_proto.name]
  86. def GetDescriptorPool(self):
  87. return symbol_database.Default().pool
  88. def testEnumValueName(self):
  89. self.assertEqual(self.my_message.EnumValueName('ForeignEnum', 4),
  90. 'FOREIGN_FOO')
  91. self.assertEqual(
  92. self.my_message.enum_types_by_name[
  93. 'ForeignEnum'].values_by_number[4].name,
  94. self.my_message.EnumValueName('ForeignEnum', 4))
  95. with self.assertRaises(KeyError):
  96. self.my_message.EnumValueName('ForeignEnum', 999)
  97. with self.assertRaises(KeyError):
  98. self.my_message.EnumValueName('NoneEnum', 999)
  99. with self.assertRaises(TypeError):
  100. self.my_message.EnumValueName()
  101. def testEnumFixups(self):
  102. self.assertEqual(self.my_enum, self.my_enum.values[0].type)
  103. def testContainingTypeFixups(self):
  104. self.assertEqual(self.my_message, self.my_message.fields[0].containing_type)
  105. self.assertEqual(self.my_message, self.my_enum.containing_type)
  106. def testContainingServiceFixups(self):
  107. self.assertEqual(self.my_service, self.my_method.containing_service)
  108. def testGetOptions(self):
  109. self.assertEqual(self.my_enum.GetOptions(),
  110. descriptor_pb2.EnumOptions())
  111. self.assertEqual(self.my_enum.values[0].GetOptions(),
  112. descriptor_pb2.EnumValueOptions())
  113. self.assertEqual(self.my_message.GetOptions(),
  114. descriptor_pb2.MessageOptions())
  115. self.assertEqual(self.my_message.fields[0].GetOptions(),
  116. descriptor_pb2.FieldOptions())
  117. self.assertEqual(self.my_method.GetOptions(),
  118. descriptor_pb2.MethodOptions())
  119. self.assertEqual(self.my_service.GetOptions(),
  120. descriptor_pb2.ServiceOptions())
  121. def testSimpleCustomOptions(self):
  122. file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
  123. message_descriptor = (unittest_custom_options_pb2.
  124. TestMessageWithCustomOptions.DESCRIPTOR)
  125. field_descriptor = message_descriptor.fields_by_name['field1']
  126. oneof_descriptor = message_descriptor.oneofs_by_name['AnOneof']
  127. enum_descriptor = message_descriptor.enum_types_by_name['AnEnum']
  128. enum_value_descriptor = (message_descriptor.
  129. enum_values_by_name['ANENUM_VAL2'])
  130. other_enum_value_descriptor = (message_descriptor.
  131. enum_values_by_name['ANENUM_VAL1'])
  132. service_descriptor = (unittest_custom_options_pb2.
  133. TestServiceWithCustomOptions.DESCRIPTOR)
  134. method_descriptor = service_descriptor.FindMethodByName('Foo')
  135. file_options = file_descriptor.GetOptions()
  136. file_opt1 = unittest_custom_options_pb2.file_opt1
  137. self.assertEqual(9876543210, file_options.Extensions[file_opt1])
  138. message_options = message_descriptor.GetOptions()
  139. message_opt1 = unittest_custom_options_pb2.message_opt1
  140. self.assertEqual(-56, message_options.Extensions[message_opt1])
  141. field_options = field_descriptor.GetOptions()
  142. field_opt1 = unittest_custom_options_pb2.field_opt1
  143. self.assertEqual(8765432109, field_options.Extensions[field_opt1])
  144. field_opt2 = unittest_custom_options_pb2.field_opt2
  145. self.assertEqual(42, field_options.Extensions[field_opt2])
  146. oneof_options = oneof_descriptor.GetOptions()
  147. oneof_opt1 = unittest_custom_options_pb2.oneof_opt1
  148. self.assertEqual(-99, oneof_options.Extensions[oneof_opt1])
  149. enum_options = enum_descriptor.GetOptions()
  150. enum_opt1 = unittest_custom_options_pb2.enum_opt1
  151. self.assertEqual(-789, enum_options.Extensions[enum_opt1])
  152. enum_value_options = enum_value_descriptor.GetOptions()
  153. enum_value_opt1 = unittest_custom_options_pb2.enum_value_opt1
  154. self.assertEqual(123, enum_value_options.Extensions[enum_value_opt1])
  155. service_options = service_descriptor.GetOptions()
  156. service_opt1 = unittest_custom_options_pb2.service_opt1
  157. self.assertEqual(-9876543210, service_options.Extensions[service_opt1])
  158. method_options = method_descriptor.GetOptions()
  159. method_opt1 = unittest_custom_options_pb2.method_opt1
  160. self.assertEqual(unittest_custom_options_pb2.METHODOPT1_VAL2,
  161. method_options.Extensions[method_opt1])
  162. message_descriptor = (
  163. unittest_custom_options_pb2.DummyMessageContainingEnum.DESCRIPTOR)
  164. self.assertTrue(file_descriptor.has_options)
  165. self.assertFalse(message_descriptor.has_options)
  166. self.assertTrue(field_descriptor.has_options)
  167. self.assertTrue(oneof_descriptor.has_options)
  168. self.assertTrue(enum_descriptor.has_options)
  169. self.assertTrue(enum_value_descriptor.has_options)
  170. self.assertFalse(other_enum_value_descriptor.has_options)
  171. def testDifferentCustomOptionTypes(self):
  172. kint32min = -2**31
  173. kint64min = -2**63
  174. kint32max = 2**31 - 1
  175. kint64max = 2**63 - 1
  176. kuint32max = 2**32 - 1
  177. kuint64max = 2**64 - 1
  178. message_descriptor =\
  179. unittest_custom_options_pb2.CustomOptionMinIntegerValues.DESCRIPTOR
  180. message_options = message_descriptor.GetOptions()
  181. self.assertEqual(False, message_options.Extensions[
  182. unittest_custom_options_pb2.bool_opt])
  183. self.assertEqual(kint32min, message_options.Extensions[
  184. unittest_custom_options_pb2.int32_opt])
  185. self.assertEqual(kint64min, message_options.Extensions[
  186. unittest_custom_options_pb2.int64_opt])
  187. self.assertEqual(0, message_options.Extensions[
  188. unittest_custom_options_pb2.uint32_opt])
  189. self.assertEqual(0, message_options.Extensions[
  190. unittest_custom_options_pb2.uint64_opt])
  191. self.assertEqual(kint32min, message_options.Extensions[
  192. unittest_custom_options_pb2.sint32_opt])
  193. self.assertEqual(kint64min, message_options.Extensions[
  194. unittest_custom_options_pb2.sint64_opt])
  195. self.assertEqual(0, message_options.Extensions[
  196. unittest_custom_options_pb2.fixed32_opt])
  197. self.assertEqual(0, message_options.Extensions[
  198. unittest_custom_options_pb2.fixed64_opt])
  199. self.assertEqual(kint32min, message_options.Extensions[
  200. unittest_custom_options_pb2.sfixed32_opt])
  201. self.assertEqual(kint64min, message_options.Extensions[
  202. unittest_custom_options_pb2.sfixed64_opt])
  203. message_descriptor =\
  204. unittest_custom_options_pb2.CustomOptionMaxIntegerValues.DESCRIPTOR
  205. message_options = message_descriptor.GetOptions()
  206. self.assertEqual(True, message_options.Extensions[
  207. unittest_custom_options_pb2.bool_opt])
  208. self.assertEqual(kint32max, message_options.Extensions[
  209. unittest_custom_options_pb2.int32_opt])
  210. self.assertEqual(kint64max, message_options.Extensions[
  211. unittest_custom_options_pb2.int64_opt])
  212. self.assertEqual(kuint32max, message_options.Extensions[
  213. unittest_custom_options_pb2.uint32_opt])
  214. self.assertEqual(kuint64max, message_options.Extensions[
  215. unittest_custom_options_pb2.uint64_opt])
  216. self.assertEqual(kint32max, message_options.Extensions[
  217. unittest_custom_options_pb2.sint32_opt])
  218. self.assertEqual(kint64max, message_options.Extensions[
  219. unittest_custom_options_pb2.sint64_opt])
  220. self.assertEqual(kuint32max, message_options.Extensions[
  221. unittest_custom_options_pb2.fixed32_opt])
  222. self.assertEqual(kuint64max, message_options.Extensions[
  223. unittest_custom_options_pb2.fixed64_opt])
  224. self.assertEqual(kint32max, message_options.Extensions[
  225. unittest_custom_options_pb2.sfixed32_opt])
  226. self.assertEqual(kint64max, message_options.Extensions[
  227. unittest_custom_options_pb2.sfixed64_opt])
  228. message_descriptor =\
  229. unittest_custom_options_pb2.CustomOptionOtherValues.DESCRIPTOR
  230. message_options = message_descriptor.GetOptions()
  231. self.assertEqual(-100, message_options.Extensions[
  232. unittest_custom_options_pb2.int32_opt])
  233. self.assertAlmostEqual(12.3456789, message_options.Extensions[
  234. unittest_custom_options_pb2.float_opt], 6)
  235. self.assertAlmostEqual(1.234567890123456789, message_options.Extensions[
  236. unittest_custom_options_pb2.double_opt])
  237. self.assertEqual("Hello, \"World\"", message_options.Extensions[
  238. unittest_custom_options_pb2.string_opt])
  239. self.assertEqual(b"Hello\0World", message_options.Extensions[
  240. unittest_custom_options_pb2.bytes_opt])
  241. dummy_enum = unittest_custom_options_pb2.DummyMessageContainingEnum
  242. self.assertEqual(
  243. dummy_enum.TEST_OPTION_ENUM_TYPE2,
  244. message_options.Extensions[unittest_custom_options_pb2.enum_opt])
  245. message_descriptor =\
  246. unittest_custom_options_pb2.SettingRealsFromPositiveInts.DESCRIPTOR
  247. message_options = message_descriptor.GetOptions()
  248. self.assertAlmostEqual(12, message_options.Extensions[
  249. unittest_custom_options_pb2.float_opt], 6)
  250. self.assertAlmostEqual(154, message_options.Extensions[
  251. unittest_custom_options_pb2.double_opt])
  252. message_descriptor =\
  253. unittest_custom_options_pb2.SettingRealsFromNegativeInts.DESCRIPTOR
  254. message_options = message_descriptor.GetOptions()
  255. self.assertAlmostEqual(-12, message_options.Extensions[
  256. unittest_custom_options_pb2.float_opt], 6)
  257. self.assertAlmostEqual(-154, message_options.Extensions[
  258. unittest_custom_options_pb2.double_opt])
  259. def testComplexExtensionOptions(self):
  260. descriptor =\
  261. unittest_custom_options_pb2.VariousComplexOptions.DESCRIPTOR
  262. options = descriptor.GetOptions()
  263. self.assertEqual(42, options.Extensions[
  264. unittest_custom_options_pb2.complex_opt1].foo)
  265. self.assertEqual(324, options.Extensions[
  266. unittest_custom_options_pb2.complex_opt1].Extensions[
  267. unittest_custom_options_pb2.quux])
  268. self.assertEqual(876, options.Extensions[
  269. unittest_custom_options_pb2.complex_opt1].Extensions[
  270. unittest_custom_options_pb2.corge].qux)
  271. self.assertEqual(987, options.Extensions[
  272. unittest_custom_options_pb2.complex_opt2].baz)
  273. self.assertEqual(654, options.Extensions[
  274. unittest_custom_options_pb2.complex_opt2].Extensions[
  275. unittest_custom_options_pb2.grault])
  276. self.assertEqual(743, options.Extensions[
  277. unittest_custom_options_pb2.complex_opt2].bar.foo)
  278. self.assertEqual(1999, options.Extensions[
  279. unittest_custom_options_pb2.complex_opt2].bar.Extensions[
  280. unittest_custom_options_pb2.quux])
  281. self.assertEqual(2008, options.Extensions[
  282. unittest_custom_options_pb2.complex_opt2].bar.Extensions[
  283. unittest_custom_options_pb2.corge].qux)
  284. self.assertEqual(741, options.Extensions[
  285. unittest_custom_options_pb2.complex_opt2].Extensions[
  286. unittest_custom_options_pb2.garply].foo)
  287. self.assertEqual(1998, options.Extensions[
  288. unittest_custom_options_pb2.complex_opt2].Extensions[
  289. unittest_custom_options_pb2.garply].Extensions[
  290. unittest_custom_options_pb2.quux])
  291. self.assertEqual(2121, options.Extensions[
  292. unittest_custom_options_pb2.complex_opt2].Extensions[
  293. unittest_custom_options_pb2.garply].Extensions[
  294. unittest_custom_options_pb2.corge].qux)
  295. self.assertEqual(1971, options.Extensions[
  296. unittest_custom_options_pb2.ComplexOptionType2
  297. .ComplexOptionType4.complex_opt4].waldo)
  298. self.assertEqual(321, options.Extensions[
  299. unittest_custom_options_pb2.complex_opt2].fred.waldo)
  300. self.assertEqual(9, options.Extensions[
  301. unittest_custom_options_pb2.complex_opt3].qux)
  302. self.assertEqual(22, options.Extensions[
  303. unittest_custom_options_pb2.complex_opt3].complexoptiontype5.plugh)
  304. self.assertEqual(24, options.Extensions[
  305. unittest_custom_options_pb2.complexopt6].xyzzy)
  306. # Check that aggregate options were parsed and saved correctly in
  307. # the appropriate descriptors.
  308. def testAggregateOptions(self):
  309. file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
  310. message_descriptor =\
  311. unittest_custom_options_pb2.AggregateMessage.DESCRIPTOR
  312. field_descriptor = message_descriptor.fields_by_name["fieldname"]
  313. enum_descriptor = unittest_custom_options_pb2.AggregateEnum.DESCRIPTOR
  314. enum_value_descriptor = enum_descriptor.values_by_name["VALUE"]
  315. service_descriptor =\
  316. unittest_custom_options_pb2.AggregateService.DESCRIPTOR
  317. method_descriptor = service_descriptor.FindMethodByName("Method")
  318. # Tests for the different types of data embedded in fileopt
  319. file_options = file_descriptor.GetOptions().Extensions[
  320. unittest_custom_options_pb2.fileopt]
  321. self.assertEqual(100, file_options.i)
  322. self.assertEqual("FileAnnotation", file_options.s)
  323. self.assertEqual("NestedFileAnnotation", file_options.sub.s)
  324. self.assertEqual("FileExtensionAnnotation", file_options.file.Extensions[
  325. unittest_custom_options_pb2.fileopt].s)
  326. self.assertEqual("EmbeddedMessageSetElement", file_options.mset.Extensions[
  327. unittest_custom_options_pb2.AggregateMessageSetElement
  328. .message_set_extension].s)
  329. # Simple tests for all the other types of annotations
  330. self.assertEqual(
  331. "MessageAnnotation",
  332. message_descriptor.GetOptions().Extensions[
  333. unittest_custom_options_pb2.msgopt].s)
  334. self.assertEqual(
  335. "FieldAnnotation",
  336. field_descriptor.GetOptions().Extensions[
  337. unittest_custom_options_pb2.fieldopt].s)
  338. self.assertEqual(
  339. "EnumAnnotation",
  340. enum_descriptor.GetOptions().Extensions[
  341. unittest_custom_options_pb2.enumopt].s)
  342. self.assertEqual(
  343. "EnumValueAnnotation",
  344. enum_value_descriptor.GetOptions().Extensions[
  345. unittest_custom_options_pb2.enumvalopt].s)
  346. self.assertEqual(
  347. "ServiceAnnotation",
  348. service_descriptor.GetOptions().Extensions[
  349. unittest_custom_options_pb2.serviceopt].s)
  350. self.assertEqual(
  351. "MethodAnnotation",
  352. method_descriptor.GetOptions().Extensions[
  353. unittest_custom_options_pb2.methodopt].s)
  354. def testNestedOptions(self):
  355. nested_message =\
  356. unittest_custom_options_pb2.NestedOptionType.NestedMessage.DESCRIPTOR
  357. self.assertEqual(1001, nested_message.GetOptions().Extensions[
  358. unittest_custom_options_pb2.message_opt1])
  359. nested_field = nested_message.fields_by_name["nested_field"]
  360. self.assertEqual(1002, nested_field.GetOptions().Extensions[
  361. unittest_custom_options_pb2.field_opt1])
  362. outer_message =\
  363. unittest_custom_options_pb2.NestedOptionType.DESCRIPTOR
  364. nested_enum = outer_message.enum_types_by_name["NestedEnum"]
  365. self.assertEqual(1003, nested_enum.GetOptions().Extensions[
  366. unittest_custom_options_pb2.enum_opt1])
  367. nested_enum_value = outer_message.enum_values_by_name["NESTED_ENUM_VALUE"]
  368. self.assertEqual(1004, nested_enum_value.GetOptions().Extensions[
  369. unittest_custom_options_pb2.enum_value_opt1])
  370. nested_extension = outer_message.extensions_by_name["nested_extension"]
  371. self.assertEqual(1005, nested_extension.GetOptions().Extensions[
  372. unittest_custom_options_pb2.field_opt2])
  373. def testFileDescriptorReferences(self):
  374. self.assertEqual(self.my_enum.file, self.my_file)
  375. self.assertEqual(self.my_message.file, self.my_file)
  376. def testFileDescriptor(self):
  377. self.assertEqual(self.my_file.name, 'some/filename/some.proto')
  378. self.assertEqual(self.my_file.package, 'protobuf_unittest')
  379. self.assertEqual(self.my_file.pool, self.pool)
  380. self.assertFalse(self.my_file.has_options)
  381. self.assertEqual('proto2', self.my_file.syntax)
  382. file_proto = descriptor_pb2.FileDescriptorProto()
  383. self.my_file.CopyToProto(file_proto)
  384. self.assertEqual(self.my_file.serialized_pb,
  385. file_proto.SerializeToString())
  386. # Generated modules also belong to the default pool.
  387. self.assertEqual(unittest_pb2.DESCRIPTOR.pool, descriptor_pool.Default())
  388. @unittest.skipIf(
  389. api_implementation.Type() != 'cpp' or api_implementation.Version() != 2,
  390. 'Immutability of descriptors is only enforced in v2 implementation')
  391. def testImmutableCppDescriptor(self):
  392. file_descriptor = unittest_pb2.DESCRIPTOR
  393. message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
  394. field_descriptor = message_descriptor.fields_by_name['optional_int32']
  395. enum_descriptor = message_descriptor.enum_types_by_name['NestedEnum']
  396. oneof_descriptor = message_descriptor.oneofs_by_name['oneof_field']
  397. with self.assertRaises(AttributeError):
  398. message_descriptor.fields_by_name = None
  399. with self.assertRaises(TypeError):
  400. message_descriptor.fields_by_name['Another'] = None
  401. with self.assertRaises(TypeError):
  402. message_descriptor.fields.append(None)
  403. with self.assertRaises(AttributeError):
  404. field_descriptor.containing_type = message_descriptor
  405. with self.assertRaises(AttributeError):
  406. file_descriptor.has_options = False
  407. with self.assertRaises(AttributeError):
  408. field_descriptor.has_options = False
  409. with self.assertRaises(AttributeError):
  410. oneof_descriptor.has_options = False
  411. with self.assertRaises(AttributeError):
  412. enum_descriptor.has_options = False
  413. with self.assertRaises(AttributeError) as e:
  414. message_descriptor.has_options = True
  415. self.assertEqual('attribute is not writable: has_options',
  416. str(e.exception))
  417. def testDefault(self):
  418. message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
  419. field = message_descriptor.fields_by_name['repeated_int32']
  420. self.assertEqual(field.default_value, [])
  421. field = message_descriptor.fields_by_name['repeated_nested_message']
  422. self.assertEqual(field.default_value, [])
  423. field = message_descriptor.fields_by_name['optionalgroup']
  424. self.assertEqual(field.default_value, None)
  425. field = message_descriptor.fields_by_name['optional_nested_message']
  426. self.assertEqual(field.default_value, None)
  427. class NewDescriptorTest(DescriptorTest):
  428. """Redo the same tests as above, but with a separate DescriptorPool."""
  429. def GetDescriptorPool(self):
  430. return descriptor_pool.DescriptorPool()
  431. class GeneratedDescriptorTest(unittest.TestCase):
  432. """Tests for the properties of descriptors in generated code."""
  433. def CheckMessageDescriptor(self, message_descriptor):
  434. # Basic properties
  435. self.assertEqual(message_descriptor.name, 'TestAllTypes')
  436. self.assertEqual(message_descriptor.full_name,
  437. 'protobuf_unittest.TestAllTypes')
  438. # Test equality and hashability
  439. self.assertEqual(message_descriptor, message_descriptor)
  440. self.assertEqual(message_descriptor.fields[0].containing_type,
  441. message_descriptor)
  442. self.assertIn(message_descriptor, [message_descriptor])
  443. self.assertIn(message_descriptor, {message_descriptor: None})
  444. # Test field containers
  445. self.CheckDescriptorSequence(message_descriptor.fields)
  446. self.CheckDescriptorMapping(message_descriptor.fields_by_name)
  447. self.CheckDescriptorMapping(message_descriptor.fields_by_number)
  448. self.CheckDescriptorMapping(message_descriptor.fields_by_camelcase_name)
  449. self.CheckDescriptorMapping(message_descriptor.enum_types_by_name)
  450. self.CheckDescriptorMapping(message_descriptor.enum_values_by_name)
  451. self.CheckDescriptorMapping(message_descriptor.oneofs_by_name)
  452. self.CheckDescriptorMapping(message_descriptor.enum_types[0].values_by_name)
  453. # Test extension range
  454. self.assertEqual(message_descriptor.extension_ranges, [])
  455. def CheckFieldDescriptor(self, field_descriptor):
  456. # Basic properties
  457. self.assertEqual(field_descriptor.name, 'optional_int32')
  458. self.assertEqual(field_descriptor.camelcase_name, 'optionalInt32')
  459. self.assertEqual(field_descriptor.full_name,
  460. 'protobuf_unittest.TestAllTypes.optional_int32')
  461. self.assertEqual(field_descriptor.containing_type.name, 'TestAllTypes')
  462. self.assertEqual(field_descriptor.file, unittest_pb2.DESCRIPTOR)
  463. # Test equality and hashability
  464. self.assertEqual(field_descriptor, field_descriptor)
  465. self.assertEqual(
  466. field_descriptor.containing_type.fields_by_name['optional_int32'],
  467. field_descriptor)
  468. self.assertEqual(
  469. field_descriptor.containing_type.fields_by_camelcase_name[
  470. 'optionalInt32'],
  471. field_descriptor)
  472. self.assertIn(field_descriptor, [field_descriptor])
  473. self.assertIn(field_descriptor, {field_descriptor: None})
  474. self.assertEqual(None, field_descriptor.extension_scope)
  475. self.assertEqual(None, field_descriptor.enum_type)
  476. if api_implementation.Type() == 'cpp':
  477. # For test coverage only
  478. self.assertEqual(field_descriptor.id, field_descriptor.id)
  479. def CheckDescriptorSequence(self, sequence):
  480. # Verifies that a property like 'messageDescriptor.fields' has all the
  481. # properties of an immutable abc.Sequence.
  482. self.assertNotEqual(sequence,
  483. unittest_pb2.TestAllExtensions.DESCRIPTOR.fields)
  484. self.assertNotEqual(sequence, [])
  485. self.assertNotEqual(sequence, 1)
  486. self.assertFalse(sequence == 1) # Only for cpp test coverage
  487. self.assertEqual(sequence, sequence)
  488. expected_list = list(sequence)
  489. self.assertEqual(expected_list, sequence)
  490. self.assertGreater(len(sequence), 0) # Sized
  491. self.assertEqual(len(sequence), len(expected_list)) # Iterable
  492. self.assertEqual(sequence[len(sequence) -1], sequence[-1])
  493. item = sequence[0]
  494. self.assertEqual(item, sequence[0])
  495. self.assertIn(item, sequence) # Container
  496. self.assertEqual(sequence.index(item), 0)
  497. self.assertEqual(sequence.count(item), 1)
  498. other_item = unittest_pb2.NestedTestAllTypes.DESCRIPTOR.fields[0]
  499. self.assertNotIn(other_item, sequence)
  500. self.assertEqual(sequence.count(other_item), 0)
  501. self.assertRaises(ValueError, sequence.index, other_item)
  502. self.assertRaises(ValueError, sequence.index, [])
  503. reversed_iterator = reversed(sequence)
  504. self.assertEqual(list(reversed_iterator), list(sequence)[::-1])
  505. self.assertRaises(StopIteration, next, reversed_iterator)
  506. expected_list[0] = 'change value'
  507. self.assertNotEqual(expected_list, sequence)
  508. # TODO(jieluo): Change __repr__ support for DescriptorSequence.
  509. if api_implementation.Type() == 'python':
  510. self.assertEqual(str(list(sequence)), str(sequence))
  511. else:
  512. self.assertEqual(str(sequence)[0], '<')
  513. def CheckDescriptorMapping(self, mapping):
  514. # Verifies that a property like 'messageDescriptor.fields' has all the
  515. # properties of an immutable abc.Mapping.
  516. self.assertNotEqual(
  517. mapping, unittest_pb2.TestAllExtensions.DESCRIPTOR.fields_by_name)
  518. self.assertNotEqual(mapping, {})
  519. self.assertNotEqual(mapping, 1)
  520. self.assertFalse(mapping == 1) # Only for cpp test coverage
  521. excepted_dict = dict(mapping.items())
  522. self.assertEqual(mapping, excepted_dict)
  523. self.assertEqual(mapping, mapping)
  524. self.assertGreater(len(mapping), 0) # Sized
  525. self.assertEqual(len(mapping), len(excepted_dict)) # Iterable
  526. if sys.version_info >= (3,):
  527. key, item = next(iter(mapping.items()))
  528. else:
  529. key, item = mapping.items()[0]
  530. self.assertIn(key, mapping) # Container
  531. self.assertEqual(mapping.get(key), item)
  532. with self.assertRaises(TypeError):
  533. mapping.get()
  534. # TODO(jieluo): Fix python and cpp extension diff.
  535. if api_implementation.Type() == 'python':
  536. self.assertRaises(TypeError, mapping.get, [])
  537. else:
  538. self.assertEqual(None, mapping.get([]))
  539. # keys(), iterkeys() &co
  540. item = (next(iter(mapping.keys())), next(iter(mapping.values())))
  541. self.assertEqual(item, next(iter(mapping.items())))
  542. if sys.version_info < (3,):
  543. def CheckItems(seq, iterator):
  544. self.assertEqual(next(iterator), seq[0])
  545. self.assertEqual(list(iterator), seq[1:])
  546. CheckItems(mapping.keys(), mapping.iterkeys())
  547. CheckItems(mapping.values(), mapping.itervalues())
  548. CheckItems(mapping.items(), mapping.iteritems())
  549. excepted_dict[key] = 'change value'
  550. self.assertNotEqual(mapping, excepted_dict)
  551. del excepted_dict[key]
  552. excepted_dict['new_key'] = 'new'
  553. self.assertNotEqual(mapping, excepted_dict)
  554. self.assertRaises(KeyError, mapping.__getitem__, 'key_error')
  555. self.assertRaises(KeyError, mapping.__getitem__, len(mapping) + 1)
  556. # TODO(jieluo): Add __repr__ support for DescriptorMapping.
  557. if api_implementation.Type() == 'python':
  558. self.assertEqual(len(str(dict(mapping.items()))), len(str(mapping)))
  559. else:
  560. self.assertEqual(str(mapping)[0], '<')
  561. def testDescriptor(self):
  562. message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
  563. self.CheckMessageDescriptor(message_descriptor)
  564. field_descriptor = message_descriptor.fields_by_name['optional_int32']
  565. self.CheckFieldDescriptor(field_descriptor)
  566. field_descriptor = message_descriptor.fields_by_camelcase_name[
  567. 'optionalInt32']
  568. self.CheckFieldDescriptor(field_descriptor)
  569. enum_descriptor = unittest_pb2.DESCRIPTOR.enum_types_by_name[
  570. 'ForeignEnum']
  571. self.assertEqual(None, enum_descriptor.containing_type)
  572. # Test extension range
  573. self.assertEqual(
  574. unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges,
  575. [(1, 536870912)])
  576. self.assertEqual(
  577. unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges,
  578. [(42, 43), (4143, 4244), (65536, 536870912)])
  579. def testCppDescriptorContainer(self):
  580. containing_file = unittest_pb2.DESCRIPTOR
  581. self.CheckDescriptorSequence(containing_file.dependencies)
  582. self.CheckDescriptorMapping(containing_file.message_types_by_name)
  583. self.CheckDescriptorMapping(containing_file.enum_types_by_name)
  584. self.CheckDescriptorMapping(containing_file.services_by_name)
  585. self.CheckDescriptorMapping(containing_file.extensions_by_name)
  586. self.CheckDescriptorMapping(
  587. unittest_pb2.TestNestedExtension.DESCRIPTOR.extensions_by_name)
  588. def testCppDescriptorContainer_Iterator(self):
  589. # Same test with the iterator
  590. enum = unittest_pb2.TestAllTypes.DESCRIPTOR.enum_types_by_name['NestedEnum']
  591. values_iter = iter(enum.values)
  592. del enum
  593. self.assertEqual('FOO', next(values_iter).name)
  594. def testServiceDescriptor(self):
  595. service_descriptor = unittest_pb2.DESCRIPTOR.services_by_name['TestService']
  596. self.assertEqual(service_descriptor.name, 'TestService')
  597. self.assertEqual(service_descriptor.methods[0].name, 'Foo')
  598. self.assertIs(service_descriptor.file, unittest_pb2.DESCRIPTOR)
  599. self.assertEqual(service_descriptor.index, 0)
  600. self.CheckDescriptorMapping(service_descriptor.methods_by_name)
  601. def testOneofDescriptor(self):
  602. message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
  603. oneof_descriptor = message_descriptor.oneofs_by_name['oneof_field']
  604. self.assertFalse(oneof_descriptor.has_options)
  605. self.assertEqual(message_descriptor, oneof_descriptor.containing_type)
  606. self.assertEqual('oneof_field', oneof_descriptor.name)
  607. self.assertEqual('protobuf_unittest.TestAllTypes.oneof_field',
  608. oneof_descriptor.full_name)
  609. self.assertEqual(0, oneof_descriptor.index)
  610. class DescriptorCopyToProtoTest(unittest.TestCase):
  611. """Tests for CopyTo functions of Descriptor."""
  612. def _AssertProtoEqual(self, actual_proto, expected_class, expected_ascii):
  613. expected_proto = expected_class()
  614. text_format.Merge(expected_ascii, expected_proto)
  615. self.assertEqual(
  616. actual_proto, expected_proto,
  617. 'Not equal,\nActual:\n%s\nExpected:\n%s\n'
  618. % (str(actual_proto), str(expected_proto)))
  619. def _InternalTestCopyToProto(self, desc, expected_proto_class,
  620. expected_proto_ascii):
  621. actual = expected_proto_class()
  622. desc.CopyToProto(actual)
  623. self._AssertProtoEqual(
  624. actual, expected_proto_class, expected_proto_ascii)
  625. def testCopyToProto_EmptyMessage(self):
  626. self._InternalTestCopyToProto(
  627. unittest_pb2.TestEmptyMessage.DESCRIPTOR,
  628. descriptor_pb2.DescriptorProto,
  629. TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII)
  630. def testCopyToProto_NestedMessage(self):
  631. TEST_NESTED_MESSAGE_ASCII = """
  632. name: 'NestedMessage'
  633. field: <
  634. name: 'bb'
  635. number: 1
  636. label: 1 # Optional
  637. type: 5 # TYPE_INT32
  638. >
  639. """
  640. self._InternalTestCopyToProto(
  641. unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
  642. descriptor_pb2.DescriptorProto,
  643. TEST_NESTED_MESSAGE_ASCII)
  644. def testCopyToProto_ForeignNestedMessage(self):
  645. TEST_FOREIGN_NESTED_ASCII = """
  646. name: 'TestForeignNested'
  647. field: <
  648. name: 'foreign_nested'
  649. number: 1
  650. label: 1 # Optional
  651. type: 11 # TYPE_MESSAGE
  652. type_name: '.protobuf_unittest.TestAllTypes.NestedMessage'
  653. >
  654. """
  655. self._InternalTestCopyToProto(
  656. unittest_pb2.TestForeignNested.DESCRIPTOR,
  657. descriptor_pb2.DescriptorProto,
  658. TEST_FOREIGN_NESTED_ASCII)
  659. def testCopyToProto_ForeignEnum(self):
  660. TEST_FOREIGN_ENUM_ASCII = """
  661. name: 'ForeignEnum'
  662. value: <
  663. name: 'FOREIGN_FOO'
  664. number: 4
  665. >
  666. value: <
  667. name: 'FOREIGN_BAR'
  668. number: 5
  669. >
  670. value: <
  671. name: 'FOREIGN_BAZ'
  672. number: 6
  673. >
  674. """
  675. self._InternalTestCopyToProto(
  676. unittest_pb2.ForeignEnum.DESCRIPTOR,
  677. descriptor_pb2.EnumDescriptorProto,
  678. TEST_FOREIGN_ENUM_ASCII)
  679. def testCopyToProto_Options(self):
  680. TEST_DEPRECATED_FIELDS_ASCII = """
  681. name: 'TestDeprecatedFields'
  682. field: <
  683. name: 'deprecated_int32'
  684. number: 1
  685. label: 1 # Optional
  686. type: 5 # TYPE_INT32
  687. options: <
  688. deprecated: true
  689. >
  690. >
  691. field {
  692. name: "deprecated_int32_in_oneof"
  693. number: 2
  694. label: LABEL_OPTIONAL
  695. type: TYPE_INT32
  696. options {
  697. deprecated: true
  698. }
  699. oneof_index: 0
  700. }
  701. oneof_decl {
  702. name: "oneof_fields"
  703. }
  704. """
  705. self._InternalTestCopyToProto(
  706. unittest_pb2.TestDeprecatedFields.DESCRIPTOR,
  707. descriptor_pb2.DescriptorProto,
  708. TEST_DEPRECATED_FIELDS_ASCII)
  709. def testCopyToProto_AllExtensions(self):
  710. TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII = """
  711. name: 'TestEmptyMessageWithExtensions'
  712. extension_range: <
  713. start: 1
  714. end: 536870912
  715. >
  716. """
  717. self._InternalTestCopyToProto(
  718. unittest_pb2.TestEmptyMessageWithExtensions.DESCRIPTOR,
  719. descriptor_pb2.DescriptorProto,
  720. TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII)
  721. def testCopyToProto_SeveralExtensions(self):
  722. TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII = """
  723. name: 'TestMultipleExtensionRanges'
  724. extension_range: <
  725. start: 42
  726. end: 43
  727. >
  728. extension_range: <
  729. start: 4143
  730. end: 4244
  731. >
  732. extension_range: <
  733. start: 65536
  734. end: 536870912
  735. >
  736. """
  737. self._InternalTestCopyToProto(
  738. unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR,
  739. descriptor_pb2.DescriptorProto,
  740. TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII)
  741. def testCopyToProto_FileDescriptor(self):
  742. UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = ("""
  743. name: 'google/protobuf/unittest_import.proto'
  744. package: 'protobuf_unittest_import'
  745. dependency: 'google/protobuf/unittest_import_public.proto'
  746. message_type: <
  747. name: 'ImportMessage'
  748. field: <
  749. name: 'd'
  750. number: 1
  751. label: 1 # Optional
  752. type: 5 # TYPE_INT32
  753. >
  754. >
  755. """ +
  756. """enum_type: <
  757. name: 'ImportEnum'
  758. value: <
  759. name: 'IMPORT_FOO'
  760. number: 7
  761. >
  762. value: <
  763. name: 'IMPORT_BAR'
  764. number: 8
  765. >
  766. value: <
  767. name: 'IMPORT_BAZ'
  768. number: 9
  769. >
  770. >
  771. enum_type: <
  772. name: 'ImportEnumForMap'
  773. value: <
  774. name: 'UNKNOWN'
  775. number: 0
  776. >
  777. value: <
  778. name: 'FOO'
  779. number: 1
  780. >
  781. value: <
  782. name: 'BAR'
  783. number: 2
  784. >
  785. >
  786. options: <
  787. java_package: 'com.google.protobuf.test'
  788. optimize_for: 1 # SPEED
  789. """ +
  790. """
  791. cc_enable_arenas: true
  792. >
  793. public_dependency: 0
  794. """)
  795. self._InternalTestCopyToProto(
  796. unittest_import_pb2.DESCRIPTOR,
  797. descriptor_pb2.FileDescriptorProto,
  798. UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII)
  799. def testCopyToProto_ServiceDescriptor(self):
  800. TEST_SERVICE_ASCII = """
  801. name: 'TestService'
  802. method: <
  803. name: 'Foo'
  804. input_type: '.protobuf_unittest.FooRequest'
  805. output_type: '.protobuf_unittest.FooResponse'
  806. >
  807. method: <
  808. name: 'Bar'
  809. input_type: '.protobuf_unittest.BarRequest'
  810. output_type: '.protobuf_unittest.BarResponse'
  811. >
  812. """
  813. self._InternalTestCopyToProto(
  814. unittest_pb2.TestService.DESCRIPTOR,
  815. descriptor_pb2.ServiceDescriptorProto,
  816. TEST_SERVICE_ASCII)
  817. @unittest.skipIf(
  818. api_implementation.Type() == 'python',
  819. 'It is not implemented in python.')
  820. # TODO(jieluo): Add support for pure python or remove in c extension.
  821. def testCopyToProto_MethodDescriptor(self):
  822. expected_ascii = """
  823. name: 'Foo'
  824. input_type: '.protobuf_unittest.FooRequest'
  825. output_type: '.protobuf_unittest.FooResponse'
  826. """
  827. method_descriptor = unittest_pb2.TestService.DESCRIPTOR.FindMethodByName(
  828. 'Foo')
  829. self._InternalTestCopyToProto(
  830. method_descriptor,
  831. descriptor_pb2.MethodDescriptorProto,
  832. expected_ascii)
  833. @unittest.skipIf(
  834. api_implementation.Type() == 'python',
  835. 'Pure python does not raise error.')
  836. # TODO(jieluo): Fix pure python to check with the proto type.
  837. def testCopyToProto_TypeError(self):
  838. file_proto = descriptor_pb2.FileDescriptorProto()
  839. self.assertRaises(TypeError,
  840. unittest_pb2.TestEmptyMessage.DESCRIPTOR.CopyToProto,
  841. file_proto)
  842. self.assertRaises(TypeError,
  843. unittest_pb2.ForeignEnum.DESCRIPTOR.CopyToProto,
  844. file_proto)
  845. self.assertRaises(TypeError,
  846. unittest_pb2.TestService.DESCRIPTOR.CopyToProto,
  847. file_proto)
  848. proto = descriptor_pb2.DescriptorProto()
  849. self.assertRaises(TypeError,
  850. unittest_import_pb2.DESCRIPTOR.CopyToProto,
  851. proto)
  852. class MakeDescriptorTest(unittest.TestCase):
  853. def testMakeDescriptorWithNestedFields(self):
  854. file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
  855. file_descriptor_proto.name = 'Foo2'
  856. message_type = file_descriptor_proto.message_type.add()
  857. message_type.name = file_descriptor_proto.name
  858. nested_type = message_type.nested_type.add()
  859. nested_type.name = 'Sub'
  860. enum_type = nested_type.enum_type.add()
  861. enum_type.name = 'FOO'
  862. enum_type_val = enum_type.value.add()
  863. enum_type_val.name = 'BAR'
  864. enum_type_val.number = 3
  865. field = message_type.field.add()
  866. field.number = 1
  867. field.name = 'uint64_field'
  868. field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
  869. field.type = descriptor.FieldDescriptor.TYPE_UINT64
  870. field = message_type.field.add()
  871. field.number = 2
  872. field.name = 'nested_message_field'
  873. field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
  874. field.type = descriptor.FieldDescriptor.TYPE_MESSAGE
  875. field.type_name = 'Sub'
  876. enum_field = nested_type.field.add()
  877. enum_field.number = 2
  878. enum_field.name = 'bar_field'
  879. enum_field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
  880. enum_field.type = descriptor.FieldDescriptor.TYPE_ENUM
  881. enum_field.type_name = 'Foo2.Sub.FOO'
  882. result = descriptor.MakeDescriptor(message_type)
  883. self.assertEqual(result.fields[0].cpp_type,
  884. descriptor.FieldDescriptor.CPPTYPE_UINT64)
  885. self.assertEqual(result.fields[1].cpp_type,
  886. descriptor.FieldDescriptor.CPPTYPE_MESSAGE)
  887. self.assertEqual(result.fields[1].message_type.containing_type,
  888. result)
  889. self.assertEqual(result.nested_types[0].fields[0].full_name,
  890. 'Foo2.Sub.bar_field')
  891. self.assertEqual(result.nested_types[0].fields[0].enum_type,
  892. result.nested_types[0].enum_types[0])
  893. self.assertFalse(result.has_options)
  894. self.assertFalse(result.fields[0].has_options)
  895. if api_implementation.Type() == 'cpp':
  896. with self.assertRaises(AttributeError):
  897. result.fields[0].has_options = False
  898. def testMakeDescriptorWithUnsignedIntField(self):
  899. file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
  900. file_descriptor_proto.name = 'Foo'
  901. message_type = file_descriptor_proto.message_type.add()
  902. message_type.name = file_descriptor_proto.name
  903. enum_type = message_type.enum_type.add()
  904. enum_type.name = 'FOO'
  905. enum_type_val = enum_type.value.add()
  906. enum_type_val.name = 'BAR'
  907. enum_type_val.number = 3
  908. field = message_type.field.add()
  909. field.number = 1
  910. field.name = 'uint64_field'
  911. field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
  912. field.type = descriptor.FieldDescriptor.TYPE_UINT64
  913. enum_field = message_type.field.add()
  914. enum_field.number = 2
  915. enum_field.name = 'bar_field'
  916. enum_field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
  917. enum_field.type = descriptor.FieldDescriptor.TYPE_ENUM
  918. enum_field.type_name = 'Foo.FOO'
  919. result = descriptor.MakeDescriptor(message_type)
  920. self.assertEqual(result.fields[0].cpp_type,
  921. descriptor.FieldDescriptor.CPPTYPE_UINT64)
  922. def testMakeDescriptorWithOptions(self):
  923. descriptor_proto = descriptor_pb2.DescriptorProto()
  924. aggregate_message = unittest_custom_options_pb2.AggregateMessage
  925. aggregate_message.DESCRIPTOR.CopyToProto(descriptor_proto)
  926. reformed_descriptor = descriptor.MakeDescriptor(descriptor_proto)
  927. options = reformed_descriptor.GetOptions()
  928. self.assertEqual(101,
  929. options.Extensions[unittest_custom_options_pb2.msgopt].i)
  930. def testCamelcaseName(self):
  931. descriptor_proto = descriptor_pb2.DescriptorProto()
  932. descriptor_proto.name = 'Bar'
  933. names = ['foo_foo', 'FooBar', 'fooBaz', 'fooFoo', 'foobar']
  934. camelcase_names = ['fooFoo', 'fooBar', 'fooBaz', 'fooFoo', 'foobar']
  935. for index in range(len(names)):
  936. field = descriptor_proto.field.add()
  937. field.number = index + 1
  938. field.name = names[index]
  939. result = descriptor.MakeDescriptor(descriptor_proto)
  940. for index in range(len(camelcase_names)):
  941. self.assertEqual(result.fields[index].camelcase_name,
  942. camelcase_names[index])
  943. def testJsonName(self):
  944. descriptor_proto = descriptor_pb2.DescriptorProto()
  945. descriptor_proto.name = 'TestJsonName'
  946. names = ['field_name', 'fieldName', 'FieldName',
  947. '_field_name', 'FIELD_NAME', 'json_name']
  948. json_names = ['fieldName', 'fieldName', 'FieldName',
  949. 'FieldName', 'FIELDNAME', '@type']
  950. for index in range(len(names)):
  951. field = descriptor_proto.field.add()
  952. field.number = index + 1
  953. field.name = names[index]
  954. field.json_name = '@type'
  955. result = descriptor.MakeDescriptor(descriptor_proto)
  956. for index in range(len(json_names)):
  957. self.assertEqual(result.fields[index].json_name,
  958. json_names[index])
  959. if __name__ == '__main__':
  960. unittest.main()