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