3 # Protocol Buffers - Google's data interchange format
4 # Copyright 2008 Google Inc. All rights reserved.
5 # http://code.google.com/p/protobuf/
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are
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
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.
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.
33 """Unittest for google.protobuf.internal.descriptor."""
35 __author__ = 'robinson@google.com (Will Robinson)'
38 from google.protobuf import unittest_custom_options_pb2
39 from google.protobuf import unittest_import_pb2
40 from google.protobuf import unittest_pb2
41 from google.protobuf import descriptor_pb2
42 from google.protobuf import descriptor
43 from google.protobuf import text_format
46 TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII = """
47 name: 'TestEmptyMessage'
51 class DescriptorTest(unittest.TestCase):
54 self.my_file = descriptor.FileDescriptor(
55 name='some/filename/some.proto',
56 package='protobuf_unittest'
58 self.my_enum = descriptor.EnumDescriptor(
60 full_name='protobuf_unittest.ForeignEnum',
64 descriptor.EnumValueDescriptor(name='FOREIGN_FOO', index=0, number=4),
65 descriptor.EnumValueDescriptor(name='FOREIGN_BAR', index=1, number=5),
66 descriptor.EnumValueDescriptor(name='FOREIGN_BAZ', index=2, number=6),
68 self.my_message = descriptor.Descriptor(
70 full_name='protobuf_unittest.TestAllTypes.NestedMessage',
75 descriptor.FieldDescriptor(
77 full_name='protobuf_unittest.TestAllTypes.NestedMessage.bb',
79 type=5, cpp_type=1, label=1,
80 has_default_value=False, default_value=0,
81 message_type=None, enum_type=None, containing_type=None,
82 is_extension=False, extension_scope=None),
89 self.my_method = descriptor.MethodDescriptor(
91 full_name='protobuf_unittest.TestService.Bar',
93 containing_service=None,
96 self.my_service = descriptor.ServiceDescriptor(
97 name='TestServiceWithOptions',
98 full_name='protobuf_unittest.TestServiceWithOptions',
105 def testEnumValueName(self):
106 self.assertEqual(self.my_message.EnumValueName('ForeignEnum', 4),
110 self.my_message.enum_types_by_name[
111 'ForeignEnum'].values_by_number[4].name,
112 self.my_message.EnumValueName('ForeignEnum', 4))
114 def testEnumFixups(self):
115 self.assertEqual(self.my_enum, self.my_enum.values[0].type)
117 def testContainingTypeFixups(self):
118 self.assertEqual(self.my_message, self.my_message.fields[0].containing_type)
119 self.assertEqual(self.my_message, self.my_enum.containing_type)
121 def testContainingServiceFixups(self):
122 self.assertEqual(self.my_service, self.my_method.containing_service)
124 def testGetOptions(self):
125 self.assertEqual(self.my_enum.GetOptions(),
126 descriptor_pb2.EnumOptions())
127 self.assertEqual(self.my_enum.values[0].GetOptions(),
128 descriptor_pb2.EnumValueOptions())
129 self.assertEqual(self.my_message.GetOptions(),
130 descriptor_pb2.MessageOptions())
131 self.assertEqual(self.my_message.fields[0].GetOptions(),
132 descriptor_pb2.FieldOptions())
133 self.assertEqual(self.my_method.GetOptions(),
134 descriptor_pb2.MethodOptions())
135 self.assertEqual(self.my_service.GetOptions(),
136 descriptor_pb2.ServiceOptions())
138 def testSimpleCustomOptions(self):
139 file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
140 message_descriptor =\
141 unittest_custom_options_pb2.TestMessageWithCustomOptions.DESCRIPTOR
142 field_descriptor = message_descriptor.fields_by_name["field1"]
143 enum_descriptor = message_descriptor.enum_types_by_name["AnEnum"]
144 enum_value_descriptor =\
145 message_descriptor.enum_values_by_name["ANENUM_VAL2"]
146 service_descriptor =\
147 unittest_custom_options_pb2.TestServiceWithCustomOptions.DESCRIPTOR
148 method_descriptor = service_descriptor.FindMethodByName("Foo")
150 file_options = file_descriptor.GetOptions()
151 file_opt1 = unittest_custom_options_pb2.file_opt1
152 self.assertEqual(9876543210, file_options.Extensions[file_opt1])
153 message_options = message_descriptor.GetOptions()
154 message_opt1 = unittest_custom_options_pb2.message_opt1
155 self.assertEqual(-56, message_options.Extensions[message_opt1])
156 field_options = field_descriptor.GetOptions()
157 field_opt1 = unittest_custom_options_pb2.field_opt1
158 self.assertEqual(8765432109, field_options.Extensions[field_opt1])
159 field_opt2 = unittest_custom_options_pb2.field_opt2
160 self.assertEqual(42, field_options.Extensions[field_opt2])
161 enum_options = enum_descriptor.GetOptions()
162 enum_opt1 = unittest_custom_options_pb2.enum_opt1
163 self.assertEqual(-789, enum_options.Extensions[enum_opt1])
164 enum_value_options = enum_value_descriptor.GetOptions()
165 enum_value_opt1 = unittest_custom_options_pb2.enum_value_opt1
166 self.assertEqual(123, enum_value_options.Extensions[enum_value_opt1])
168 service_options = service_descriptor.GetOptions()
169 service_opt1 = unittest_custom_options_pb2.service_opt1
170 self.assertEqual(-9876543210, service_options.Extensions[service_opt1])
171 method_options = method_descriptor.GetOptions()
172 method_opt1 = unittest_custom_options_pb2.method_opt1
173 self.assertEqual(unittest_custom_options_pb2.METHODOPT1_VAL2,
174 method_options.Extensions[method_opt1])
176 def testDifferentCustomOptionTypes(self):
179 kint32max = 2**31 - 1
180 kint64max = 2**63 - 1
181 kuint32max = 2**32 - 1
182 kuint64max = 2**64 - 1
184 message_descriptor =\
185 unittest_custom_options_pb2.CustomOptionMinIntegerValues.DESCRIPTOR
186 message_options = message_descriptor.GetOptions()
187 self.assertEqual(False, message_options.Extensions[
188 unittest_custom_options_pb2.bool_opt])
189 self.assertEqual(kint32min, message_options.Extensions[
190 unittest_custom_options_pb2.int32_opt])
191 self.assertEqual(kint64min, message_options.Extensions[
192 unittest_custom_options_pb2.int64_opt])
193 self.assertEqual(0, message_options.Extensions[
194 unittest_custom_options_pb2.uint32_opt])
195 self.assertEqual(0, message_options.Extensions[
196 unittest_custom_options_pb2.uint64_opt])
197 self.assertEqual(kint32min, message_options.Extensions[
198 unittest_custom_options_pb2.sint32_opt])
199 self.assertEqual(kint64min, message_options.Extensions[
200 unittest_custom_options_pb2.sint64_opt])
201 self.assertEqual(0, message_options.Extensions[
202 unittest_custom_options_pb2.fixed32_opt])
203 self.assertEqual(0, message_options.Extensions[
204 unittest_custom_options_pb2.fixed64_opt])
205 self.assertEqual(kint32min, message_options.Extensions[
206 unittest_custom_options_pb2.sfixed32_opt])
207 self.assertEqual(kint64min, message_options.Extensions[
208 unittest_custom_options_pb2.sfixed64_opt])
210 message_descriptor =\
211 unittest_custom_options_pb2.CustomOptionMaxIntegerValues.DESCRIPTOR
212 message_options = message_descriptor.GetOptions()
213 self.assertEqual(True, message_options.Extensions[
214 unittest_custom_options_pb2.bool_opt])
215 self.assertEqual(kint32max, message_options.Extensions[
216 unittest_custom_options_pb2.int32_opt])
217 self.assertEqual(kint64max, message_options.Extensions[
218 unittest_custom_options_pb2.int64_opt])
219 self.assertEqual(kuint32max, message_options.Extensions[
220 unittest_custom_options_pb2.uint32_opt])
221 self.assertEqual(kuint64max, message_options.Extensions[
222 unittest_custom_options_pb2.uint64_opt])
223 self.assertEqual(kint32max, message_options.Extensions[
224 unittest_custom_options_pb2.sint32_opt])
225 self.assertEqual(kint64max, message_options.Extensions[
226 unittest_custom_options_pb2.sint64_opt])
227 self.assertEqual(kuint32max, message_options.Extensions[
228 unittest_custom_options_pb2.fixed32_opt])
229 self.assertEqual(kuint64max, message_options.Extensions[
230 unittest_custom_options_pb2.fixed64_opt])
231 self.assertEqual(kint32max, message_options.Extensions[
232 unittest_custom_options_pb2.sfixed32_opt])
233 self.assertEqual(kint64max, message_options.Extensions[
234 unittest_custom_options_pb2.sfixed64_opt])
236 message_descriptor =\
237 unittest_custom_options_pb2.CustomOptionOtherValues.DESCRIPTOR
238 message_options = message_descriptor.GetOptions()
239 self.assertEqual(-100, message_options.Extensions[
240 unittest_custom_options_pb2.int32_opt])
241 self.assertAlmostEqual(12.3456789, message_options.Extensions[
242 unittest_custom_options_pb2.float_opt], 6)
243 self.assertAlmostEqual(1.234567890123456789, message_options.Extensions[
244 unittest_custom_options_pb2.double_opt])
245 self.assertEqual("Hello, \"World\"", message_options.Extensions[
246 unittest_custom_options_pb2.string_opt])
247 self.assertEqual("Hello\0World", message_options.Extensions[
248 unittest_custom_options_pb2.bytes_opt])
249 dummy_enum = unittest_custom_options_pb2.DummyMessageContainingEnum
251 dummy_enum.TEST_OPTION_ENUM_TYPE2,
252 message_options.Extensions[unittest_custom_options_pb2.enum_opt])
254 message_descriptor =\
255 unittest_custom_options_pb2.SettingRealsFromPositiveInts.DESCRIPTOR
256 message_options = message_descriptor.GetOptions()
257 self.assertAlmostEqual(12, message_options.Extensions[
258 unittest_custom_options_pb2.float_opt], 6)
259 self.assertAlmostEqual(154, message_options.Extensions[
260 unittest_custom_options_pb2.double_opt])
262 message_descriptor =\
263 unittest_custom_options_pb2.SettingRealsFromNegativeInts.DESCRIPTOR
264 message_options = message_descriptor.GetOptions()
265 self.assertAlmostEqual(-12, message_options.Extensions[
266 unittest_custom_options_pb2.float_opt], 6)
267 self.assertAlmostEqual(-154, message_options.Extensions[
268 unittest_custom_options_pb2.double_opt])
270 def testComplexExtensionOptions(self):
272 unittest_custom_options_pb2.VariousComplexOptions.DESCRIPTOR
273 options = descriptor.GetOptions()
274 self.assertEqual(42, options.Extensions[
275 unittest_custom_options_pb2.complex_opt1].foo)
276 self.assertEqual(324, options.Extensions[
277 unittest_custom_options_pb2.complex_opt1].Extensions[
278 unittest_custom_options_pb2.quux])
279 self.assertEqual(876, options.Extensions[
280 unittest_custom_options_pb2.complex_opt1].Extensions[
281 unittest_custom_options_pb2.corge].qux)
282 self.assertEqual(987, options.Extensions[
283 unittest_custom_options_pb2.complex_opt2].baz)
284 self.assertEqual(654, options.Extensions[
285 unittest_custom_options_pb2.complex_opt2].Extensions[
286 unittest_custom_options_pb2.grault])
287 self.assertEqual(743, options.Extensions[
288 unittest_custom_options_pb2.complex_opt2].bar.foo)
289 self.assertEqual(1999, options.Extensions[
290 unittest_custom_options_pb2.complex_opt2].bar.Extensions[
291 unittest_custom_options_pb2.quux])
292 self.assertEqual(2008, options.Extensions[
293 unittest_custom_options_pb2.complex_opt2].bar.Extensions[
294 unittest_custom_options_pb2.corge].qux)
295 self.assertEqual(741, options.Extensions[
296 unittest_custom_options_pb2.complex_opt2].Extensions[
297 unittest_custom_options_pb2.garply].foo)
298 self.assertEqual(1998, options.Extensions[
299 unittest_custom_options_pb2.complex_opt2].Extensions[
300 unittest_custom_options_pb2.garply].Extensions[
301 unittest_custom_options_pb2.quux])
302 self.assertEqual(2121, options.Extensions[
303 unittest_custom_options_pb2.complex_opt2].Extensions[
304 unittest_custom_options_pb2.garply].Extensions[
305 unittest_custom_options_pb2.corge].qux)
306 self.assertEqual(1971, options.Extensions[
307 unittest_custom_options_pb2.ComplexOptionType2
308 .ComplexOptionType4.complex_opt4].waldo)
309 self.assertEqual(321, options.Extensions[
310 unittest_custom_options_pb2.complex_opt2].fred.waldo)
311 self.assertEqual(9, options.Extensions[
312 unittest_custom_options_pb2.complex_opt3].qux)
313 self.assertEqual(22, options.Extensions[
314 unittest_custom_options_pb2.complex_opt3].complexoptiontype5.plugh)
315 self.assertEqual(24, options.Extensions[
316 unittest_custom_options_pb2.complexopt6].xyzzy)
318 # Check that aggregate options were parsed and saved correctly in
319 # the appropriate descriptors.
320 def testAggregateOptions(self):
321 file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
322 message_descriptor =\
323 unittest_custom_options_pb2.AggregateMessage.DESCRIPTOR
324 field_descriptor = message_descriptor.fields_by_name["fieldname"]
325 enum_descriptor = unittest_custom_options_pb2.AggregateEnum.DESCRIPTOR
326 enum_value_descriptor = enum_descriptor.values_by_name["VALUE"]
327 service_descriptor =\
328 unittest_custom_options_pb2.AggregateService.DESCRIPTOR
329 method_descriptor = service_descriptor.FindMethodByName("Method")
331 # Tests for the different types of data embedded in fileopt
332 file_options = file_descriptor.GetOptions().Extensions[
333 unittest_custom_options_pb2.fileopt]
334 self.assertEqual(100, file_options.i)
335 self.assertEqual("FileAnnotation", file_options.s)
336 self.assertEqual("NestedFileAnnotation", file_options.sub.s)
337 self.assertEqual("FileExtensionAnnotation", file_options.file.Extensions[
338 unittest_custom_options_pb2.fileopt].s)
339 self.assertEqual("EmbeddedMessageSetElement", file_options.mset.Extensions[
340 unittest_custom_options_pb2.AggregateMessageSetElement
341 .message_set_extension].s)
343 # Simple tests for all the other types of annotations
346 message_descriptor.GetOptions().Extensions[
347 unittest_custom_options_pb2.msgopt].s)
350 field_descriptor.GetOptions().Extensions[
351 unittest_custom_options_pb2.fieldopt].s)
354 enum_descriptor.GetOptions().Extensions[
355 unittest_custom_options_pb2.enumopt].s)
357 "EnumValueAnnotation",
358 enum_value_descriptor.GetOptions().Extensions[
359 unittest_custom_options_pb2.enumvalopt].s)
362 service_descriptor.GetOptions().Extensions[
363 unittest_custom_options_pb2.serviceopt].s)
366 method_descriptor.GetOptions().Extensions[
367 unittest_custom_options_pb2.methodopt].s)
369 def testNestedOptions(self):
371 unittest_custom_options_pb2.NestedOptionType.NestedMessage.DESCRIPTOR
372 self.assertEqual(1001, nested_message.GetOptions().Extensions[
373 unittest_custom_options_pb2.message_opt1])
374 nested_field = nested_message.fields_by_name["nested_field"]
375 self.assertEqual(1002, nested_field.GetOptions().Extensions[
376 unittest_custom_options_pb2.field_opt1])
378 unittest_custom_options_pb2.NestedOptionType.DESCRIPTOR
379 nested_enum = outer_message.enum_types_by_name["NestedEnum"]
380 self.assertEqual(1003, nested_enum.GetOptions().Extensions[
381 unittest_custom_options_pb2.enum_opt1])
382 nested_enum_value = outer_message.enum_values_by_name["NESTED_ENUM_VALUE"]
383 self.assertEqual(1004, nested_enum_value.GetOptions().Extensions[
384 unittest_custom_options_pb2.enum_value_opt1])
385 nested_extension = outer_message.extensions_by_name["nested_extension"]
386 self.assertEqual(1005, nested_extension.GetOptions().Extensions[
387 unittest_custom_options_pb2.field_opt2])
389 def testFileDescriptorReferences(self):
390 self.assertEqual(self.my_enum.file, self.my_file)
391 self.assertEqual(self.my_message.file, self.my_file)
393 def testFileDescriptor(self):
394 self.assertEqual(self.my_file.name, 'some/filename/some.proto')
395 self.assertEqual(self.my_file.package, 'protobuf_unittest')
398 class DescriptorCopyToProtoTest(unittest.TestCase):
399 """Tests for CopyTo functions of Descriptor."""
401 def _AssertProtoEqual(self, actual_proto, expected_class, expected_ascii):
402 expected_proto = expected_class()
403 text_format.Merge(expected_ascii, expected_proto)
406 actual_proto, expected_proto,
407 'Not equal,\nActual:\n%s\nExpected:\n%s\n'
408 % (str(actual_proto), str(expected_proto)))
410 def _InternalTestCopyToProto(self, desc, expected_proto_class,
411 expected_proto_ascii):
412 actual = expected_proto_class()
413 desc.CopyToProto(actual)
414 self._AssertProtoEqual(
415 actual, expected_proto_class, expected_proto_ascii)
417 def testCopyToProto_EmptyMessage(self):
418 self._InternalTestCopyToProto(
419 unittest_pb2.TestEmptyMessage.DESCRIPTOR,
420 descriptor_pb2.DescriptorProto,
421 TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII)
423 def testCopyToProto_NestedMessage(self):
424 TEST_NESTED_MESSAGE_ASCII = """
425 name: 'NestedMessage'
434 self._InternalTestCopyToProto(
435 unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
436 descriptor_pb2.DescriptorProto,
437 TEST_NESTED_MESSAGE_ASCII)
439 def testCopyToProto_ForeignNestedMessage(self):
440 TEST_FOREIGN_NESTED_ASCII = """
441 name: 'TestForeignNested'
443 name: 'foreign_nested'
446 type: 11 # TYPE_MESSAGE
447 type_name: '.protobuf_unittest.TestAllTypes.NestedMessage'
451 self._InternalTestCopyToProto(
452 unittest_pb2.TestForeignNested.DESCRIPTOR,
453 descriptor_pb2.DescriptorProto,
454 TEST_FOREIGN_NESTED_ASCII)
456 def testCopyToProto_ForeignEnum(self):
457 TEST_FOREIGN_ENUM_ASCII = """
473 self._InternalTestCopyToProto(
474 unittest_pb2._FOREIGNENUM,
475 descriptor_pb2.EnumDescriptorProto,
476 TEST_FOREIGN_ENUM_ASCII)
478 def testCopyToProto_Options(self):
479 TEST_DEPRECATED_FIELDS_ASCII = """
480 name: 'TestDeprecatedFields'
482 name: 'deprecated_int32'
492 self._InternalTestCopyToProto(
493 unittest_pb2.TestDeprecatedFields.DESCRIPTOR,
494 descriptor_pb2.DescriptorProto,
495 TEST_DEPRECATED_FIELDS_ASCII)
497 def testCopyToProto_AllExtensions(self):
498 TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII = """
499 name: 'TestEmptyMessageWithExtensions'
506 self._InternalTestCopyToProto(
507 unittest_pb2.TestEmptyMessageWithExtensions.DESCRIPTOR,
508 descriptor_pb2.DescriptorProto,
509 TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII)
511 def testCopyToProto_SeveralExtensions(self):
512 TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII = """
513 name: 'TestMultipleExtensionRanges'
528 self._InternalTestCopyToProto(
529 unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR,
530 descriptor_pb2.DescriptorProto,
531 TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII)
533 def testCopyToProto_FileDescriptor(self):
534 UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = ("""
535 name: 'google/protobuf/unittest_import.proto'
536 package: 'protobuf_unittest_import'
537 dependency: 'google/protobuf/unittest_import_public.proto'
539 name: 'ImportMessage'
564 java_package: 'com.google.protobuf.test'
565 optimize_for: 1 # SPEED
570 self._InternalTestCopyToProto(
571 unittest_import_pb2.DESCRIPTOR,
572 descriptor_pb2.FileDescriptorProto,
573 UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII)
575 def testCopyToProto_ServiceDescriptor(self):
576 TEST_SERVICE_ASCII = """
580 input_type: '.protobuf_unittest.FooRequest'
581 output_type: '.protobuf_unittest.FooResponse'
585 input_type: '.protobuf_unittest.BarRequest'
586 output_type: '.protobuf_unittest.BarResponse'
590 self._InternalTestCopyToProto(
591 unittest_pb2.TestService.DESCRIPTOR,
592 descriptor_pb2.ServiceDescriptorProto,
596 class MakeDescriptorTest(unittest.TestCase):
597 def testMakeDescriptorWithUnsignedIntField(self):
598 file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
599 file_descriptor_proto.name = 'Foo'
600 message_type = file_descriptor_proto.message_type.add()
601 message_type.name = file_descriptor_proto.name
602 field = message_type.field.add()
604 field.name = 'uint64_field'
605 field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
606 field.type = descriptor.FieldDescriptor.TYPE_UINT64
607 result = descriptor.MakeDescriptor(message_type)
608 self.assertEqual(result.fields[0].cpp_type,
609 descriptor.FieldDescriptor.CPPTYPE_UINT64)
612 if __name__ == '__main__':