1#! /usr/bin/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 33"""Tests for google.protobuf.descriptor_pool.""" 34 35__author__ = 'matthewtoia@google.com (Matt Toia)' 36 37import os 38import unittest 39 40from google.apputils import basetest 41from google.protobuf import unittest_pb2 42from google.protobuf import descriptor_pb2 43from google.protobuf.internal import api_implementation 44from google.protobuf.internal import descriptor_pool_test1_pb2 45from google.protobuf.internal import descriptor_pool_test2_pb2 46from google.protobuf.internal import factory_test1_pb2 47from google.protobuf.internal import factory_test2_pb2 48from google.protobuf import descriptor 49from google.protobuf import descriptor_database 50from google.protobuf import descriptor_pool 51 52 53class DescriptorPoolTest(basetest.TestCase): 54 55 def setUp(self): 56 self.pool = descriptor_pool.DescriptorPool() 57 self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString( 58 factory_test1_pb2.DESCRIPTOR.serialized_pb) 59 self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString( 60 factory_test2_pb2.DESCRIPTOR.serialized_pb) 61 self.pool.Add(self.factory_test1_fd) 62 self.pool.Add(self.factory_test2_fd) 63 64 def testFindFileByName(self): 65 name1 = 'google/protobuf/internal/factory_test1.proto' 66 file_desc1 = self.pool.FindFileByName(name1) 67 self.assertIsInstance(file_desc1, descriptor.FileDescriptor) 68 self.assertEquals(name1, file_desc1.name) 69 self.assertEquals('google.protobuf.python.internal', file_desc1.package) 70 self.assertIn('Factory1Message', file_desc1.message_types_by_name) 71 72 name2 = 'google/protobuf/internal/factory_test2.proto' 73 file_desc2 = self.pool.FindFileByName(name2) 74 self.assertIsInstance(file_desc2, descriptor.FileDescriptor) 75 self.assertEquals(name2, file_desc2.name) 76 self.assertEquals('google.protobuf.python.internal', file_desc2.package) 77 self.assertIn('Factory2Message', file_desc2.message_types_by_name) 78 79 def testFindFileByNameFailure(self): 80 with self.assertRaises(KeyError): 81 self.pool.FindFileByName('Does not exist') 82 83 def testFindFileContainingSymbol(self): 84 file_desc1 = self.pool.FindFileContainingSymbol( 85 'google.protobuf.python.internal.Factory1Message') 86 self.assertIsInstance(file_desc1, descriptor.FileDescriptor) 87 self.assertEquals('google/protobuf/internal/factory_test1.proto', 88 file_desc1.name) 89 self.assertEquals('google.protobuf.python.internal', file_desc1.package) 90 self.assertIn('Factory1Message', file_desc1.message_types_by_name) 91 92 file_desc2 = self.pool.FindFileContainingSymbol( 93 'google.protobuf.python.internal.Factory2Message') 94 self.assertIsInstance(file_desc2, descriptor.FileDescriptor) 95 self.assertEquals('google/protobuf/internal/factory_test2.proto', 96 file_desc2.name) 97 self.assertEquals('google.protobuf.python.internal', file_desc2.package) 98 self.assertIn('Factory2Message', file_desc2.message_types_by_name) 99 100 def testFindFileContainingSymbolFailure(self): 101 with self.assertRaises(KeyError): 102 self.pool.FindFileContainingSymbol('Does not exist') 103 104 def testFindMessageTypeByName(self): 105 msg1 = self.pool.FindMessageTypeByName( 106 'google.protobuf.python.internal.Factory1Message') 107 self.assertIsInstance(msg1, descriptor.Descriptor) 108 self.assertEquals('Factory1Message', msg1.name) 109 self.assertEquals('google.protobuf.python.internal.Factory1Message', 110 msg1.full_name) 111 self.assertEquals(None, msg1.containing_type) 112 113 nested_msg1 = msg1.nested_types[0] 114 self.assertEquals('NestedFactory1Message', nested_msg1.name) 115 self.assertEquals(msg1, nested_msg1.containing_type) 116 117 nested_enum1 = msg1.enum_types[0] 118 self.assertEquals('NestedFactory1Enum', nested_enum1.name) 119 self.assertEquals(msg1, nested_enum1.containing_type) 120 121 self.assertEquals(nested_msg1, msg1.fields_by_name[ 122 'nested_factory_1_message'].message_type) 123 self.assertEquals(nested_enum1, msg1.fields_by_name[ 124 'nested_factory_1_enum'].enum_type) 125 126 msg2 = self.pool.FindMessageTypeByName( 127 'google.protobuf.python.internal.Factory2Message') 128 self.assertIsInstance(msg2, descriptor.Descriptor) 129 self.assertEquals('Factory2Message', msg2.name) 130 self.assertEquals('google.protobuf.python.internal.Factory2Message', 131 msg2.full_name) 132 self.assertIsNone(msg2.containing_type) 133 134 nested_msg2 = msg2.nested_types[0] 135 self.assertEquals('NestedFactory2Message', nested_msg2.name) 136 self.assertEquals(msg2, nested_msg2.containing_type) 137 138 nested_enum2 = msg2.enum_types[0] 139 self.assertEquals('NestedFactory2Enum', nested_enum2.name) 140 self.assertEquals(msg2, nested_enum2.containing_type) 141 142 self.assertEquals(nested_msg2, msg2.fields_by_name[ 143 'nested_factory_2_message'].message_type) 144 self.assertEquals(nested_enum2, msg2.fields_by_name[ 145 'nested_factory_2_enum'].enum_type) 146 147 self.assertTrue(msg2.fields_by_name['int_with_default'].has_default_value) 148 self.assertEquals( 149 1776, msg2.fields_by_name['int_with_default'].default_value) 150 151 self.assertTrue( 152 msg2.fields_by_name['double_with_default'].has_default_value) 153 self.assertEquals( 154 9.99, msg2.fields_by_name['double_with_default'].default_value) 155 156 self.assertTrue( 157 msg2.fields_by_name['string_with_default'].has_default_value) 158 self.assertEquals( 159 'hello world', msg2.fields_by_name['string_with_default'].default_value) 160 161 self.assertTrue(msg2.fields_by_name['bool_with_default'].has_default_value) 162 self.assertFalse(msg2.fields_by_name['bool_with_default'].default_value) 163 164 self.assertTrue(msg2.fields_by_name['enum_with_default'].has_default_value) 165 self.assertEquals( 166 1, msg2.fields_by_name['enum_with_default'].default_value) 167 168 msg3 = self.pool.FindMessageTypeByName( 169 'google.protobuf.python.internal.Factory2Message.NestedFactory2Message') 170 self.assertEquals(nested_msg2, msg3) 171 172 self.assertTrue(msg2.fields_by_name['bytes_with_default'].has_default_value) 173 self.assertEquals( 174 b'a\xfb\x00c', 175 msg2.fields_by_name['bytes_with_default'].default_value) 176 177 self.assertEqual(1, len(msg2.oneofs)) 178 self.assertEqual(1, len(msg2.oneofs_by_name)) 179 self.assertEqual(2, len(msg2.oneofs[0].fields)) 180 for name in ['oneof_int', 'oneof_string']: 181 self.assertEqual(msg2.oneofs[0], 182 msg2.fields_by_name[name].containing_oneof) 183 self.assertIn(msg2.fields_by_name[name], msg2.oneofs[0].fields) 184 185 def testFindMessageTypeByNameFailure(self): 186 with self.assertRaises(KeyError): 187 self.pool.FindMessageTypeByName('Does not exist') 188 189 def testFindEnumTypeByName(self): 190 enum1 = self.pool.FindEnumTypeByName( 191 'google.protobuf.python.internal.Factory1Enum') 192 self.assertIsInstance(enum1, descriptor.EnumDescriptor) 193 self.assertEquals(0, enum1.values_by_name['FACTORY_1_VALUE_0'].number) 194 self.assertEquals(1, enum1.values_by_name['FACTORY_1_VALUE_1'].number) 195 196 nested_enum1 = self.pool.FindEnumTypeByName( 197 'google.protobuf.python.internal.Factory1Message.NestedFactory1Enum') 198 self.assertIsInstance(nested_enum1, descriptor.EnumDescriptor) 199 self.assertEquals( 200 0, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_0'].number) 201 self.assertEquals( 202 1, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_1'].number) 203 204 enum2 = self.pool.FindEnumTypeByName( 205 'google.protobuf.python.internal.Factory2Enum') 206 self.assertIsInstance(enum2, descriptor.EnumDescriptor) 207 self.assertEquals(0, enum2.values_by_name['FACTORY_2_VALUE_0'].number) 208 self.assertEquals(1, enum2.values_by_name['FACTORY_2_VALUE_1'].number) 209 210 nested_enum2 = self.pool.FindEnumTypeByName( 211 'google.protobuf.python.internal.Factory2Message.NestedFactory2Enum') 212 self.assertIsInstance(nested_enum2, descriptor.EnumDescriptor) 213 self.assertEquals( 214 0, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_0'].number) 215 self.assertEquals( 216 1, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_1'].number) 217 218 def testFindEnumTypeByNameFailure(self): 219 with self.assertRaises(KeyError): 220 self.pool.FindEnumTypeByName('Does not exist') 221 222 def testUserDefinedDB(self): 223 db = descriptor_database.DescriptorDatabase() 224 self.pool = descriptor_pool.DescriptorPool(db) 225 db.Add(self.factory_test1_fd) 226 db.Add(self.factory_test2_fd) 227 self.testFindMessageTypeByName() 228 229 def testComplexNesting(self): 230 test1_desc = descriptor_pb2.FileDescriptorProto.FromString( 231 descriptor_pool_test1_pb2.DESCRIPTOR.serialized_pb) 232 test2_desc = descriptor_pb2.FileDescriptorProto.FromString( 233 descriptor_pool_test2_pb2.DESCRIPTOR.serialized_pb) 234 self.pool.Add(test1_desc) 235 self.pool.Add(test2_desc) 236 TEST1_FILE.CheckFile(self, self.pool) 237 TEST2_FILE.CheckFile(self, self.pool) 238 239 240 241class ProtoFile(object): 242 243 def __init__(self, name, package, messages, dependencies=None): 244 self.name = name 245 self.package = package 246 self.messages = messages 247 self.dependencies = dependencies or [] 248 249 def CheckFile(self, test, pool): 250 file_desc = pool.FindFileByName(self.name) 251 test.assertEquals(self.name, file_desc.name) 252 test.assertEquals(self.package, file_desc.package) 253 dependencies_names = [f.name for f in file_desc.dependencies] 254 test.assertEqual(self.dependencies, dependencies_names) 255 for name, msg_type in self.messages.items(): 256 msg_type.CheckType(test, None, name, file_desc) 257 258 259class EnumType(object): 260 261 def __init__(self, values): 262 self.values = values 263 264 def CheckType(self, test, msg_desc, name, file_desc): 265 enum_desc = msg_desc.enum_types_by_name[name] 266 test.assertEqual(name, enum_desc.name) 267 expected_enum_full_name = '.'.join([msg_desc.full_name, name]) 268 test.assertEqual(expected_enum_full_name, enum_desc.full_name) 269 test.assertEqual(msg_desc, enum_desc.containing_type) 270 test.assertEqual(file_desc, enum_desc.file) 271 for index, (value, number) in enumerate(self.values): 272 value_desc = enum_desc.values_by_name[value] 273 test.assertEqual(value, value_desc.name) 274 test.assertEqual(index, value_desc.index) 275 test.assertEqual(number, value_desc.number) 276 test.assertEqual(enum_desc, value_desc.type) 277 test.assertIn(value, msg_desc.enum_values_by_name) 278 279 280class MessageType(object): 281 282 def __init__(self, type_dict, field_list, is_extendable=False, 283 extensions=None): 284 self.type_dict = type_dict 285 self.field_list = field_list 286 self.is_extendable = is_extendable 287 self.extensions = extensions or [] 288 289 def CheckType(self, test, containing_type_desc, name, file_desc): 290 if containing_type_desc is None: 291 desc = file_desc.message_types_by_name[name] 292 expected_full_name = '.'.join([file_desc.package, name]) 293 else: 294 desc = containing_type_desc.nested_types_by_name[name] 295 expected_full_name = '.'.join([containing_type_desc.full_name, name]) 296 297 test.assertEqual(name, desc.name) 298 test.assertEqual(expected_full_name, desc.full_name) 299 test.assertEqual(containing_type_desc, desc.containing_type) 300 test.assertEqual(desc.file, file_desc) 301 test.assertEqual(self.is_extendable, desc.is_extendable) 302 for name, subtype in self.type_dict.items(): 303 subtype.CheckType(test, desc, name, file_desc) 304 305 for index, (name, field) in enumerate(self.field_list): 306 field.CheckField(test, desc, name, index) 307 308 for index, (name, field) in enumerate(self.extensions): 309 field.CheckField(test, desc, name, index) 310 311 312class EnumField(object): 313 314 def __init__(self, number, type_name, default_value): 315 self.number = number 316 self.type_name = type_name 317 self.default_value = default_value 318 319 def CheckField(self, test, msg_desc, name, index): 320 field_desc = msg_desc.fields_by_name[name] 321 enum_desc = msg_desc.enum_types_by_name[self.type_name] 322 test.assertEqual(name, field_desc.name) 323 expected_field_full_name = '.'.join([msg_desc.full_name, name]) 324 test.assertEqual(expected_field_full_name, field_desc.full_name) 325 test.assertEqual(index, field_desc.index) 326 test.assertEqual(self.number, field_desc.number) 327 test.assertEqual(descriptor.FieldDescriptor.TYPE_ENUM, field_desc.type) 328 test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_ENUM, 329 field_desc.cpp_type) 330 test.assertTrue(field_desc.has_default_value) 331 test.assertEqual(enum_desc.values_by_name[self.default_value].index, 332 field_desc.default_value) 333 test.assertEqual(msg_desc, field_desc.containing_type) 334 test.assertEqual(enum_desc, field_desc.enum_type) 335 336 337class MessageField(object): 338 339 def __init__(self, number, type_name): 340 self.number = number 341 self.type_name = type_name 342 343 def CheckField(self, test, msg_desc, name, index): 344 field_desc = msg_desc.fields_by_name[name] 345 field_type_desc = msg_desc.nested_types_by_name[self.type_name] 346 test.assertEqual(name, field_desc.name) 347 expected_field_full_name = '.'.join([msg_desc.full_name, name]) 348 test.assertEqual(expected_field_full_name, field_desc.full_name) 349 test.assertEqual(index, field_desc.index) 350 test.assertEqual(self.number, field_desc.number) 351 test.assertEqual(descriptor.FieldDescriptor.TYPE_MESSAGE, field_desc.type) 352 test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_MESSAGE, 353 field_desc.cpp_type) 354 test.assertFalse(field_desc.has_default_value) 355 test.assertEqual(msg_desc, field_desc.containing_type) 356 test.assertEqual(field_type_desc, field_desc.message_type) 357 358 359class StringField(object): 360 361 def __init__(self, number, default_value): 362 self.number = number 363 self.default_value = default_value 364 365 def CheckField(self, test, msg_desc, name, index): 366 field_desc = msg_desc.fields_by_name[name] 367 test.assertEqual(name, field_desc.name) 368 expected_field_full_name = '.'.join([msg_desc.full_name, name]) 369 test.assertEqual(expected_field_full_name, field_desc.full_name) 370 test.assertEqual(index, field_desc.index) 371 test.assertEqual(self.number, field_desc.number) 372 test.assertEqual(descriptor.FieldDescriptor.TYPE_STRING, field_desc.type) 373 test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_STRING, 374 field_desc.cpp_type) 375 test.assertTrue(field_desc.has_default_value) 376 test.assertEqual(self.default_value, field_desc.default_value) 377 378 379class ExtensionField(object): 380 381 def __init__(self, number, extended_type): 382 self.number = number 383 self.extended_type = extended_type 384 385 def CheckField(self, test, msg_desc, name, index): 386 field_desc = msg_desc.extensions_by_name[name] 387 test.assertEqual(name, field_desc.name) 388 expected_field_full_name = '.'.join([msg_desc.full_name, name]) 389 test.assertEqual(expected_field_full_name, field_desc.full_name) 390 test.assertEqual(self.number, field_desc.number) 391 test.assertEqual(index, field_desc.index) 392 test.assertEqual(descriptor.FieldDescriptor.TYPE_MESSAGE, field_desc.type) 393 test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_MESSAGE, 394 field_desc.cpp_type) 395 test.assertFalse(field_desc.has_default_value) 396 test.assertTrue(field_desc.is_extension) 397 test.assertEqual(msg_desc, field_desc.extension_scope) 398 test.assertEqual(msg_desc, field_desc.message_type) 399 test.assertEqual(self.extended_type, field_desc.containing_type.name) 400 401 402class AddDescriptorTest(basetest.TestCase): 403 404 def _TestMessage(self, prefix): 405 pool = descriptor_pool.DescriptorPool() 406 pool.AddDescriptor(unittest_pb2.TestAllTypes.DESCRIPTOR) 407 self.assertEquals( 408 'protobuf_unittest.TestAllTypes', 409 pool.FindMessageTypeByName( 410 prefix + 'protobuf_unittest.TestAllTypes').full_name) 411 412 # AddDescriptor is not recursive. 413 with self.assertRaises(KeyError): 414 pool.FindMessageTypeByName( 415 prefix + 'protobuf_unittest.TestAllTypes.NestedMessage') 416 417 pool.AddDescriptor(unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR) 418 self.assertEquals( 419 'protobuf_unittest.TestAllTypes.NestedMessage', 420 pool.FindMessageTypeByName( 421 prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').full_name) 422 423 # Files are implicitly also indexed when messages are added. 424 self.assertEquals( 425 'google/protobuf/unittest.proto', 426 pool.FindFileByName( 427 'google/protobuf/unittest.proto').name) 428 429 self.assertEquals( 430 'google/protobuf/unittest.proto', 431 pool.FindFileContainingSymbol( 432 prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').name) 433 434 def testMessage(self): 435 self._TestMessage('') 436 self._TestMessage('.') 437 438 def _TestEnum(self, prefix): 439 pool = descriptor_pool.DescriptorPool() 440 pool.AddEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR) 441 self.assertEquals( 442 'protobuf_unittest.ForeignEnum', 443 pool.FindEnumTypeByName( 444 prefix + 'protobuf_unittest.ForeignEnum').full_name) 445 446 # AddEnumDescriptor is not recursive. 447 with self.assertRaises(KeyError): 448 pool.FindEnumTypeByName( 449 prefix + 'protobuf_unittest.ForeignEnum.NestedEnum') 450 451 pool.AddEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR) 452 self.assertEquals( 453 'protobuf_unittest.TestAllTypes.NestedEnum', 454 pool.FindEnumTypeByName( 455 prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').full_name) 456 457 # Files are implicitly also indexed when enums are added. 458 self.assertEquals( 459 'google/protobuf/unittest.proto', 460 pool.FindFileByName( 461 'google/protobuf/unittest.proto').name) 462 463 self.assertEquals( 464 'google/protobuf/unittest.proto', 465 pool.FindFileContainingSymbol( 466 prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').name) 467 468 def testEnum(self): 469 self._TestEnum('') 470 self._TestEnum('.') 471 472 def testFile(self): 473 pool = descriptor_pool.DescriptorPool() 474 pool.AddFileDescriptor(unittest_pb2.DESCRIPTOR) 475 self.assertEquals( 476 'google/protobuf/unittest.proto', 477 pool.FindFileByName( 478 'google/protobuf/unittest.proto').name) 479 480 # AddFileDescriptor is not recursive; messages and enums within files must 481 # be explicitly registered. 482 with self.assertRaises(KeyError): 483 pool.FindFileContainingSymbol( 484 'protobuf_unittest.TestAllTypes') 485 486 487TEST1_FILE = ProtoFile( 488 'google/protobuf/internal/descriptor_pool_test1.proto', 489 'google.protobuf.python.internal', 490 { 491 'DescriptorPoolTest1': MessageType({ 492 'NestedEnum': EnumType([('ALPHA', 1), ('BETA', 2)]), 493 'NestedMessage': MessageType({ 494 'NestedEnum': EnumType([('EPSILON', 5), ('ZETA', 6)]), 495 'DeepNestedMessage': MessageType({ 496 'NestedEnum': EnumType([('ETA', 7), ('THETA', 8)]), 497 }, [ 498 ('nested_enum', EnumField(1, 'NestedEnum', 'ETA')), 499 ('nested_field', StringField(2, 'theta')), 500 ]), 501 }, [ 502 ('nested_enum', EnumField(1, 'NestedEnum', 'ZETA')), 503 ('nested_field', StringField(2, 'beta')), 504 ('deep_nested_message', MessageField(3, 'DeepNestedMessage')), 505 ]) 506 }, [ 507 ('nested_enum', EnumField(1, 'NestedEnum', 'BETA')), 508 ('nested_message', MessageField(2, 'NestedMessage')), 509 ], is_extendable=True), 510 511 'DescriptorPoolTest2': MessageType({ 512 'NestedEnum': EnumType([('GAMMA', 3), ('DELTA', 4)]), 513 'NestedMessage': MessageType({ 514 'NestedEnum': EnumType([('IOTA', 9), ('KAPPA', 10)]), 515 'DeepNestedMessage': MessageType({ 516 'NestedEnum': EnumType([('LAMBDA', 11), ('MU', 12)]), 517 }, [ 518 ('nested_enum', EnumField(1, 'NestedEnum', 'MU')), 519 ('nested_field', StringField(2, 'lambda')), 520 ]), 521 }, [ 522 ('nested_enum', EnumField(1, 'NestedEnum', 'IOTA')), 523 ('nested_field', StringField(2, 'delta')), 524 ('deep_nested_message', MessageField(3, 'DeepNestedMessage')), 525 ]) 526 }, [ 527 ('nested_enum', EnumField(1, 'NestedEnum', 'GAMMA')), 528 ('nested_message', MessageField(2, 'NestedMessage')), 529 ]), 530 }) 531 532 533TEST2_FILE = ProtoFile( 534 'google/protobuf/internal/descriptor_pool_test2.proto', 535 'google.protobuf.python.internal', 536 { 537 'DescriptorPoolTest3': MessageType({ 538 'NestedEnum': EnumType([('NU', 13), ('XI', 14)]), 539 'NestedMessage': MessageType({ 540 'NestedEnum': EnumType([('OMICRON', 15), ('PI', 16)]), 541 'DeepNestedMessage': MessageType({ 542 'NestedEnum': EnumType([('RHO', 17), ('SIGMA', 18)]), 543 }, [ 544 ('nested_enum', EnumField(1, 'NestedEnum', 'RHO')), 545 ('nested_field', StringField(2, 'sigma')), 546 ]), 547 }, [ 548 ('nested_enum', EnumField(1, 'NestedEnum', 'PI')), 549 ('nested_field', StringField(2, 'nu')), 550 ('deep_nested_message', MessageField(3, 'DeepNestedMessage')), 551 ]) 552 }, [ 553 ('nested_enum', EnumField(1, 'NestedEnum', 'XI')), 554 ('nested_message', MessageField(2, 'NestedMessage')), 555 ], extensions=[ 556 ('descriptor_pool_test', 557 ExtensionField(1001, 'DescriptorPoolTest1')), 558 ]), 559 }, 560 dependencies=['google/protobuf/internal/descriptor_pool_test1.proto']) 561 562 563if __name__ == '__main__': 564 basetest.main() 565