Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/google/protobuf/descriptor.py: 53%

427 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-25 06:32 +0000

1# Protocol Buffers - Google's data interchange format 

2# Copyright 2008 Google Inc. All rights reserved. 

3# 

4# Use of this source code is governed by a BSD-style 

5# license that can be found in the LICENSE file or at 

6# https://developers.google.com/open-source/licenses/bsd 

7 

8"""Descriptors essentially contain exactly the information found in a .proto 

9file, in types that make this information accessible in Python. 

10""" 

11 

12__author__ = 'robinson@google.com (Will Robinson)' 

13 

14import threading 

15import warnings 

16 

17from google.protobuf.internal import api_implementation 

18 

19_USE_C_DESCRIPTORS = False 

20if api_implementation.Type() != 'python': 

21 # Used by MakeDescriptor in cpp mode 

22 import binascii 

23 import os 

24 # pylint: disable=protected-access 

25 _message = api_implementation._c_module 

26 # TODO: Remove this import after fix api_implementation 

27 if _message is None: 

28 from google.protobuf.pyext import _message 

29 _USE_C_DESCRIPTORS = True 

30 

31 

32class Error(Exception): 

33 """Base error for this module.""" 

34 

35 

36class TypeTransformationError(Error): 

37 """Error transforming between python proto type and corresponding C++ type.""" 

38 

39 

40if _USE_C_DESCRIPTORS: 

41 # This metaclass allows to override the behavior of code like 

42 # isinstance(my_descriptor, FieldDescriptor) 

43 # and make it return True when the descriptor is an instance of the extension 

44 # type written in C++. 

45 class DescriptorMetaclass(type): 

46 

47 def __instancecheck__(cls, obj): 

48 if super(DescriptorMetaclass, cls).__instancecheck__(obj): 

49 return True 

50 if isinstance(obj, cls._C_DESCRIPTOR_CLASS): 

51 return True 

52 return False 

53else: 

54 # The standard metaclass; nothing changes. 

55 DescriptorMetaclass = type 

56 

57 

58class _Lock(object): 

59 """Wrapper class of threading.Lock(), which is allowed by 'with'.""" 

60 

61 def __new__(cls): 

62 self = object.__new__(cls) 

63 self._lock = threading.Lock() # pylint: disable=protected-access 

64 return self 

65 

66 def __enter__(self): 

67 self._lock.acquire() 

68 

69 def __exit__(self, exc_type, exc_value, exc_tb): 

70 self._lock.release() 

71 

72 

73_lock = threading.Lock() 

74 

75 

76def _Deprecated(name): 

77 if _Deprecated.count > 0: 

78 _Deprecated.count -= 1 

79 warnings.warn( 

80 'Call to deprecated create function %s(). Note: Create unlinked ' 

81 'descriptors is going to go away. Please use get/find descriptors from ' 

82 'generated code or query the descriptor_pool.' 

83 % name, 

84 category=DeprecationWarning, stacklevel=3) 

85 

86 

87# Deprecated warnings will print 100 times at most which should be enough for 

88# users to notice and do not cause timeout. 

89_Deprecated.count = 100 

90 

91 

92_internal_create_key = object() 

93 

94 

95class DescriptorBase(metaclass=DescriptorMetaclass): 

96 

97 """Descriptors base class. 

98 

99 This class is the base of all descriptor classes. It provides common options 

100 related functionality. 

101 

102 Attributes: 

103 has_options: True if the descriptor has non-default options. Usually it is 

104 not necessary to read this -- just call GetOptions() which will happily 

105 return the default instance. However, it's sometimes useful for 

106 efficiency, and also useful inside the protobuf implementation to avoid 

107 some bootstrapping issues. 

108 file (FileDescriptor): Reference to file info. 

109 """ 

110 

111 if _USE_C_DESCRIPTORS: 

112 # The class, or tuple of classes, that are considered as "virtual 

113 # subclasses" of this descriptor class. 

114 _C_DESCRIPTOR_CLASS = () 

115 

116 def __init__(self, file, options, serialized_options, options_class_name): 

117 """Initialize the descriptor given its options message and the name of the 

118 class of the options message. The name of the class is required in case 

119 the options message is None and has to be created. 

120 """ 

121 self.file = file 

122 self._options = options 

123 self._options_class_name = options_class_name 

124 self._serialized_options = serialized_options 

125 

126 # Does this descriptor have non-default options? 

127 self.has_options = (self._options is not None) or ( 

128 self._serialized_options is not None 

129 ) 

130 

131 def _SetOptions(self, options, options_class_name): 

132 """Sets the descriptor's options 

133 

134 This function is used in generated proto2 files to update descriptor 

135 options. It must not be used outside proto2. 

136 """ 

137 self._options = options 

138 self._options_class_name = options_class_name 

139 

140 # Does this descriptor have non-default options? 

141 self.has_options = options is not None 

142 

143 def GetOptions(self): 

144 """Retrieves descriptor options. 

145 

146 This method returns the options set or creates the default options for the 

147 descriptor. 

148 """ 

149 if self._options: 

150 return self._options 

151 

152 from google.protobuf import descriptor_pb2 

153 try: 

154 options_class = getattr(descriptor_pb2, 

155 self._options_class_name) 

156 except AttributeError: 

157 raise RuntimeError('Unknown options class name %s!' % 

158 (self._options_class_name)) 

159 

160 if self._serialized_options is None: 

161 with _lock: 

162 self._options = options_class() 

163 else: 

164 options = _ParseOptions(options_class(), self._serialized_options) 

165 with _lock: 

166 self._options = options 

167 

168 return self._options 

169 

170 

171class _NestedDescriptorBase(DescriptorBase): 

172 """Common class for descriptors that can be nested.""" 

173 

174 def __init__(self, options, options_class_name, name, full_name, 

175 file, containing_type, serialized_start=None, 

176 serialized_end=None, serialized_options=None): 

177 """Constructor. 

178 

179 Args: 

180 options: Protocol message options or None to use default message options. 

181 options_class_name (str): The class name of the above options. 

182 name (str): Name of this protocol message type. 

183 full_name (str): Fully-qualified name of this protocol message type, which 

184 will include protocol "package" name and the name of any enclosing 

185 types. 

186 containing_type: if provided, this is a nested descriptor, with this 

187 descriptor as parent, otherwise None. 

188 serialized_start: The start index (inclusive) in block in the 

189 file.serialized_pb that describes this descriptor. 

190 serialized_end: The end index (exclusive) in block in the 

191 file.serialized_pb that describes this descriptor. 

192 serialized_options: Protocol message serialized options or None. 

193 """ 

194 super(_NestedDescriptorBase, self).__init__( 

195 file, options, serialized_options, options_class_name 

196 ) 

197 

198 self.name = name 

199 # TODO: Add function to calculate full_name instead of having it in 

200 # memory? 

201 self.full_name = full_name 

202 self.containing_type = containing_type 

203 

204 self._serialized_start = serialized_start 

205 self._serialized_end = serialized_end 

206 

207 def CopyToProto(self, proto): 

208 """Copies this to the matching proto in descriptor_pb2. 

209 

210 Args: 

211 proto: An empty proto instance from descriptor_pb2. 

212 

213 Raises: 

214 Error: If self couldn't be serialized, due to to few constructor 

215 arguments. 

216 """ 

217 if (self.file is not None and 

218 self._serialized_start is not None and 

219 self._serialized_end is not None): 

220 proto.ParseFromString(self.file.serialized_pb[ 

221 self._serialized_start:self._serialized_end]) 

222 else: 

223 raise Error('Descriptor does not contain serialization.') 

224 

225 

226class Descriptor(_NestedDescriptorBase): 

227 

228 """Descriptor for a protocol message type. 

229 

230 Attributes: 

231 name (str): Name of this protocol message type. 

232 full_name (str): Fully-qualified name of this protocol message type, 

233 which will include protocol "package" name and the name of any 

234 enclosing types. 

235 containing_type (Descriptor): Reference to the descriptor of the type 

236 containing us, or None if this is top-level. 

237 fields (list[FieldDescriptor]): Field descriptors for all fields in 

238 this type. 

239 fields_by_number (dict(int, FieldDescriptor)): Same 

240 :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed 

241 by "number" attribute in each FieldDescriptor. 

242 fields_by_name (dict(str, FieldDescriptor)): Same 

243 :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed by 

244 "name" attribute in each :class:`FieldDescriptor`. 

245 nested_types (list[Descriptor]): Descriptor references 

246 for all protocol message types nested within this one. 

247 nested_types_by_name (dict(str, Descriptor)): Same Descriptor 

248 objects as in :attr:`nested_types`, but indexed by "name" attribute 

249 in each Descriptor. 

250 enum_types (list[EnumDescriptor]): :class:`EnumDescriptor` references 

251 for all enums contained within this type. 

252 enum_types_by_name (dict(str, EnumDescriptor)): Same 

253 :class:`EnumDescriptor` objects as in :attr:`enum_types`, but 

254 indexed by "name" attribute in each EnumDescriptor. 

255 enum_values_by_name (dict(str, EnumValueDescriptor)): Dict mapping 

256 from enum value name to :class:`EnumValueDescriptor` for that value. 

257 extensions (list[FieldDescriptor]): All extensions defined directly 

258 within this message type (NOT within a nested type). 

259 extensions_by_name (dict(str, FieldDescriptor)): Same FieldDescriptor 

260 objects as :attr:`extensions`, but indexed by "name" attribute of each 

261 FieldDescriptor. 

262 is_extendable (bool): Does this type define any extension ranges? 

263 oneofs (list[OneofDescriptor]): The list of descriptors for oneof fields 

264 in this message. 

265 oneofs_by_name (dict(str, OneofDescriptor)): Same objects as in 

266 :attr:`oneofs`, but indexed by "name" attribute. 

267 file (FileDescriptor): Reference to file descriptor. 

268 is_map_entry: If the message type is a map entry. 

269 

270 """ 

271 

272 if _USE_C_DESCRIPTORS: 

273 _C_DESCRIPTOR_CLASS = _message.Descriptor 

274 

275 def __new__( 

276 cls, 

277 name=None, 

278 full_name=None, 

279 filename=None, 

280 containing_type=None, 

281 fields=None, 

282 nested_types=None, 

283 enum_types=None, 

284 extensions=None, 

285 options=None, 

286 serialized_options=None, 

287 is_extendable=True, 

288 extension_ranges=None, 

289 oneofs=None, 

290 file=None, # pylint: disable=redefined-builtin 

291 serialized_start=None, 

292 serialized_end=None, 

293 syntax=None, 

294 is_map_entry=False, 

295 create_key=None): 

296 _message.Message._CheckCalledFromGeneratedFile() 

297 return _message.default_pool.FindMessageTypeByName(full_name) 

298 

299 # NOTE: The file argument redefining a builtin is nothing we can 

300 # fix right now since we don't know how many clients already rely on the 

301 # name of the argument. 

302 def __init__(self, name, full_name, filename, containing_type, fields, 

303 nested_types, enum_types, extensions, options=None, 

304 serialized_options=None, 

305 is_extendable=True, extension_ranges=None, oneofs=None, 

306 file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin 

307 syntax=None, is_map_entry=False, create_key=None): 

308 """Arguments to __init__() are as described in the description 

309 of Descriptor fields above. 

310 

311 Note that filename is an obsolete argument, that is not used anymore. 

312 Please use file.name to access this as an attribute. 

313 """ 

314 if create_key is not _internal_create_key: 

315 _Deprecated('Descriptor') 

316 

317 super(Descriptor, self).__init__( 

318 options, 'MessageOptions', name, full_name, file, 

319 containing_type, serialized_start=serialized_start, 

320 serialized_end=serialized_end, serialized_options=serialized_options) 

321 

322 # We have fields in addition to fields_by_name and fields_by_number, 

323 # so that: 

324 # 1. Clients can index fields by "order in which they're listed." 

325 # 2. Clients can easily iterate over all fields with the terse 

326 # syntax: for f in descriptor.fields: ... 

327 self.fields = fields 

328 for field in self.fields: 

329 field.containing_type = self 

330 self.fields_by_number = dict((f.number, f) for f in fields) 

331 self.fields_by_name = dict((f.name, f) for f in fields) 

332 self._fields_by_camelcase_name = None 

333 

334 self.nested_types = nested_types 

335 for nested_type in nested_types: 

336 nested_type.containing_type = self 

337 self.nested_types_by_name = dict((t.name, t) for t in nested_types) 

338 

339 self.enum_types = enum_types 

340 for enum_type in self.enum_types: 

341 enum_type.containing_type = self 

342 self.enum_types_by_name = dict((t.name, t) for t in enum_types) 

343 self.enum_values_by_name = dict( 

344 (v.name, v) for t in enum_types for v in t.values) 

345 

346 self.extensions = extensions 

347 for extension in self.extensions: 

348 extension.extension_scope = self 

349 self.extensions_by_name = dict((f.name, f) for f in extensions) 

350 self.is_extendable = is_extendable 

351 self.extension_ranges = extension_ranges 

352 self.oneofs = oneofs if oneofs is not None else [] 

353 self.oneofs_by_name = dict((o.name, o) for o in self.oneofs) 

354 for oneof in self.oneofs: 

355 oneof.containing_type = self 

356 self.syntax = syntax or "proto2" 

357 self._is_map_entry = is_map_entry 

358 

359 @property 

360 def fields_by_camelcase_name(self): 

361 """Same FieldDescriptor objects as in :attr:`fields`, but indexed by 

362 :attr:`FieldDescriptor.camelcase_name`. 

363 """ 

364 if self._fields_by_camelcase_name is None: 

365 self._fields_by_camelcase_name = dict( 

366 (f.camelcase_name, f) for f in self.fields) 

367 return self._fields_by_camelcase_name 

368 

369 def EnumValueName(self, enum, value): 

370 """Returns the string name of an enum value. 

371 

372 This is just a small helper method to simplify a common operation. 

373 

374 Args: 

375 enum: string name of the Enum. 

376 value: int, value of the enum. 

377 

378 Returns: 

379 string name of the enum value. 

380 

381 Raises: 

382 KeyError if either the Enum doesn't exist or the value is not a valid 

383 value for the enum. 

384 """ 

385 return self.enum_types_by_name[enum].values_by_number[value].name 

386 

387 def CopyToProto(self, proto): 

388 """Copies this to a descriptor_pb2.DescriptorProto. 

389 

390 Args: 

391 proto: An empty descriptor_pb2.DescriptorProto. 

392 """ 

393 # This function is overridden to give a better doc comment. 

394 super(Descriptor, self).CopyToProto(proto) 

395 

396 

397# TODO: We should have aggressive checking here, 

398# for example: 

399# * If you specify a repeated field, you should not be allowed 

400# to specify a default value. 

401# * [Other examples here as needed]. 

402# 

403# TODO: for this and other *Descriptor classes, we 

404# might also want to lock things down aggressively (e.g., 

405# prevent clients from setting the attributes). Having 

406# stronger invariants here in general will reduce the number 

407# of runtime checks we must do in reflection.py... 

408class FieldDescriptor(DescriptorBase): 

409 

410 """Descriptor for a single field in a .proto file. 

411 

412 Attributes: 

413 name (str): Name of this field, exactly as it appears in .proto. 

414 full_name (str): Name of this field, including containing scope. This is 

415 particularly relevant for extensions. 

416 index (int): Dense, 0-indexed index giving the order that this 

417 field textually appears within its message in the .proto file. 

418 number (int): Tag number declared for this field in the .proto file. 

419 

420 type (int): (One of the TYPE_* constants below) Declared type. 

421 cpp_type (int): (One of the CPPTYPE_* constants below) C++ type used to 

422 represent this field. 

423 

424 label (int): (One of the LABEL_* constants below) Tells whether this 

425 field is optional, required, or repeated. 

426 has_default_value (bool): True if this field has a default value defined, 

427 otherwise false. 

428 default_value (Varies): Default value of this field. Only 

429 meaningful for non-repeated scalar fields. Repeated fields 

430 should always set this to [], and non-repeated composite 

431 fields should always set this to None. 

432 

433 containing_type (Descriptor): Descriptor of the protocol message 

434 type that contains this field. Set by the Descriptor constructor 

435 if we're passed into one. 

436 Somewhat confusingly, for extension fields, this is the 

437 descriptor of the EXTENDED message, not the descriptor 

438 of the message containing this field. (See is_extension and 

439 extension_scope below). 

440 message_type (Descriptor): If a composite field, a descriptor 

441 of the message type contained in this field. Otherwise, this is None. 

442 enum_type (EnumDescriptor): If this field contains an enum, a 

443 descriptor of that enum. Otherwise, this is None. 

444 

445 is_extension: True iff this describes an extension field. 

446 extension_scope (Descriptor): Only meaningful if is_extension is True. 

447 Gives the message that immediately contains this extension field. 

448 Will be None iff we're a top-level (file-level) extension field. 

449 

450 options (descriptor_pb2.FieldOptions): Protocol message field options or 

451 None to use default field options. 

452 

453 containing_oneof (OneofDescriptor): If the field is a member of a oneof 

454 union, contains its descriptor. Otherwise, None. 

455 

456 file (FileDescriptor): Reference to file descriptor. 

457 """ 

458 

459 # Must be consistent with C++ FieldDescriptor::Type enum in 

460 # descriptor.h. 

461 # 

462 # TODO: Find a way to eliminate this repetition. 

463 TYPE_DOUBLE = 1 

464 TYPE_FLOAT = 2 

465 TYPE_INT64 = 3 

466 TYPE_UINT64 = 4 

467 TYPE_INT32 = 5 

468 TYPE_FIXED64 = 6 

469 TYPE_FIXED32 = 7 

470 TYPE_BOOL = 8 

471 TYPE_STRING = 9 

472 TYPE_GROUP = 10 

473 TYPE_MESSAGE = 11 

474 TYPE_BYTES = 12 

475 TYPE_UINT32 = 13 

476 TYPE_ENUM = 14 

477 TYPE_SFIXED32 = 15 

478 TYPE_SFIXED64 = 16 

479 TYPE_SINT32 = 17 

480 TYPE_SINT64 = 18 

481 MAX_TYPE = 18 

482 

483 # Must be consistent with C++ FieldDescriptor::CppType enum in 

484 # descriptor.h. 

485 # 

486 # TODO: Find a way to eliminate this repetition. 

487 CPPTYPE_INT32 = 1 

488 CPPTYPE_INT64 = 2 

489 CPPTYPE_UINT32 = 3 

490 CPPTYPE_UINT64 = 4 

491 CPPTYPE_DOUBLE = 5 

492 CPPTYPE_FLOAT = 6 

493 CPPTYPE_BOOL = 7 

494 CPPTYPE_ENUM = 8 

495 CPPTYPE_STRING = 9 

496 CPPTYPE_MESSAGE = 10 

497 MAX_CPPTYPE = 10 

498 

499 _PYTHON_TO_CPP_PROTO_TYPE_MAP = { 

500 TYPE_DOUBLE: CPPTYPE_DOUBLE, 

501 TYPE_FLOAT: CPPTYPE_FLOAT, 

502 TYPE_ENUM: CPPTYPE_ENUM, 

503 TYPE_INT64: CPPTYPE_INT64, 

504 TYPE_SINT64: CPPTYPE_INT64, 

505 TYPE_SFIXED64: CPPTYPE_INT64, 

506 TYPE_UINT64: CPPTYPE_UINT64, 

507 TYPE_FIXED64: CPPTYPE_UINT64, 

508 TYPE_INT32: CPPTYPE_INT32, 

509 TYPE_SFIXED32: CPPTYPE_INT32, 

510 TYPE_SINT32: CPPTYPE_INT32, 

511 TYPE_UINT32: CPPTYPE_UINT32, 

512 TYPE_FIXED32: CPPTYPE_UINT32, 

513 TYPE_BYTES: CPPTYPE_STRING, 

514 TYPE_STRING: CPPTYPE_STRING, 

515 TYPE_BOOL: CPPTYPE_BOOL, 

516 TYPE_MESSAGE: CPPTYPE_MESSAGE, 

517 TYPE_GROUP: CPPTYPE_MESSAGE 

518 } 

519 

520 # Must be consistent with C++ FieldDescriptor::Label enum in 

521 # descriptor.h. 

522 # 

523 # TODO: Find a way to eliminate this repetition. 

524 LABEL_OPTIONAL = 1 

525 LABEL_REQUIRED = 2 

526 LABEL_REPEATED = 3 

527 MAX_LABEL = 3 

528 

529 # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber, 

530 # and kLastReservedNumber in descriptor.h 

531 MAX_FIELD_NUMBER = (1 << 29) - 1 

532 FIRST_RESERVED_FIELD_NUMBER = 19000 

533 LAST_RESERVED_FIELD_NUMBER = 19999 

534 

535 if _USE_C_DESCRIPTORS: 

536 _C_DESCRIPTOR_CLASS = _message.FieldDescriptor 

537 

538 def __new__(cls, name, full_name, index, number, type, cpp_type, label, 

539 default_value, message_type, enum_type, containing_type, 

540 is_extension, extension_scope, options=None, 

541 serialized_options=None, 

542 has_default_value=True, containing_oneof=None, json_name=None, 

543 file=None, create_key=None): # pylint: disable=redefined-builtin 

544 _message.Message._CheckCalledFromGeneratedFile() 

545 if is_extension: 

546 return _message.default_pool.FindExtensionByName(full_name) 

547 else: 

548 return _message.default_pool.FindFieldByName(full_name) 

549 

550 def __init__(self, name, full_name, index, number, type, cpp_type, label, 

551 default_value, message_type, enum_type, containing_type, 

552 is_extension, extension_scope, options=None, 

553 serialized_options=None, 

554 has_default_value=True, containing_oneof=None, json_name=None, 

555 file=None, create_key=None): # pylint: disable=redefined-builtin 

556 """The arguments are as described in the description of FieldDescriptor 

557 attributes above. 

558 

559 Note that containing_type may be None, and may be set later if necessary 

560 (to deal with circular references between message types, for example). 

561 Likewise for extension_scope. 

562 """ 

563 if create_key is not _internal_create_key: 

564 _Deprecated('FieldDescriptor') 

565 

566 super(FieldDescriptor, self).__init__( 

567 file, options, serialized_options, 'FieldOptions' 

568 ) 

569 self.name = name 

570 self.full_name = full_name 

571 self._camelcase_name = None 

572 if json_name is None: 

573 self.json_name = _ToJsonName(name) 

574 else: 

575 self.json_name = json_name 

576 self.index = index 

577 self.number = number 

578 self.type = type 

579 self.cpp_type = cpp_type 

580 self.label = label 

581 self.has_default_value = has_default_value 

582 self.default_value = default_value 

583 self.containing_type = containing_type 

584 self.message_type = message_type 

585 self.enum_type = enum_type 

586 self.is_extension = is_extension 

587 self.extension_scope = extension_scope 

588 self.containing_oneof = containing_oneof 

589 if api_implementation.Type() == 'python': 

590 self._cdescriptor = None 

591 else: 

592 if is_extension: 

593 self._cdescriptor = _message.default_pool.FindExtensionByName(full_name) 

594 else: 

595 self._cdescriptor = _message.default_pool.FindFieldByName(full_name) 

596 

597 @property 

598 def camelcase_name(self): 

599 """Camelcase name of this field. 

600 

601 Returns: 

602 str: the name in CamelCase. 

603 """ 

604 if self._camelcase_name is None: 

605 self._camelcase_name = _ToCamelCase(self.name) 

606 return self._camelcase_name 

607 

608 @property 

609 def has_presence(self): 

610 """Whether the field distinguishes between unpopulated and default values. 

611 

612 Raises: 

613 RuntimeError: singular field that is not linked with message nor file. 

614 """ 

615 if self.label == FieldDescriptor.LABEL_REPEATED: 

616 return False 

617 if (self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE or 

618 self.containing_oneof): 

619 return True 

620 # self.containing_type is used here instead of self.file for legacy 

621 # compatibility. FieldDescriptor.file was added in cl/153110619 

622 # Some old/generated code didn't link file to FieldDescriptor. 

623 # TODO: remove syntax usage b/240619313 

624 return self.containing_type.syntax == 'proto2' 

625 

626 @property 

627 def is_packed(self): 

628 """Returns if the field is packed.""" 

629 if self.label != FieldDescriptor.LABEL_REPEATED: 

630 return False 

631 field_type = self.type 

632 if (field_type == FieldDescriptor.TYPE_STRING or 

633 field_type == FieldDescriptor.TYPE_GROUP or 

634 field_type == FieldDescriptor.TYPE_MESSAGE or 

635 field_type == FieldDescriptor.TYPE_BYTES): 

636 return False 

637 if self.containing_type.syntax == 'proto2': 

638 return self.has_options and self.GetOptions().packed 

639 else: 

640 return (not self.has_options or 

641 not self.GetOptions().HasField('packed') or 

642 self.GetOptions().packed) 

643 

644 @staticmethod 

645 def ProtoTypeToCppProtoType(proto_type): 

646 """Converts from a Python proto type to a C++ Proto Type. 

647 

648 The Python ProtocolBuffer classes specify both the 'Python' datatype and the 

649 'C++' datatype - and they're not the same. This helper method should 

650 translate from one to another. 

651 

652 Args: 

653 proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*) 

654 Returns: 

655 int: descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. 

656 Raises: 

657 TypeTransformationError: when the Python proto type isn't known. 

658 """ 

659 try: 

660 return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] 

661 except KeyError: 

662 raise TypeTransformationError('Unknown proto_type: %s' % proto_type) 

663 

664 

665class EnumDescriptor(_NestedDescriptorBase): 

666 

667 """Descriptor for an enum defined in a .proto file. 

668 

669 Attributes: 

670 name (str): Name of the enum type. 

671 full_name (str): Full name of the type, including package name 

672 and any enclosing type(s). 

673 

674 values (list[EnumValueDescriptor]): List of the values 

675 in this enum. 

676 values_by_name (dict(str, EnumValueDescriptor)): Same as :attr:`values`, 

677 but indexed by the "name" field of each EnumValueDescriptor. 

678 values_by_number (dict(int, EnumValueDescriptor)): Same as :attr:`values`, 

679 but indexed by the "number" field of each EnumValueDescriptor. 

680 containing_type (Descriptor): Descriptor of the immediate containing 

681 type of this enum, or None if this is an enum defined at the 

682 top level in a .proto file. Set by Descriptor's constructor 

683 if we're passed into one. 

684 file (FileDescriptor): Reference to file descriptor. 

685 options (descriptor_pb2.EnumOptions): Enum options message or 

686 None to use default enum options. 

687 """ 

688 

689 if _USE_C_DESCRIPTORS: 

690 _C_DESCRIPTOR_CLASS = _message.EnumDescriptor 

691 

692 def __new__(cls, name, full_name, filename, values, 

693 containing_type=None, options=None, 

694 serialized_options=None, file=None, # pylint: disable=redefined-builtin 

695 serialized_start=None, serialized_end=None, create_key=None): 

696 _message.Message._CheckCalledFromGeneratedFile() 

697 return _message.default_pool.FindEnumTypeByName(full_name) 

698 

699 def __init__(self, name, full_name, filename, values, 

700 containing_type=None, options=None, 

701 serialized_options=None, file=None, # pylint: disable=redefined-builtin 

702 serialized_start=None, serialized_end=None, create_key=None): 

703 """Arguments are as described in the attribute description above. 

704 

705 Note that filename is an obsolete argument, that is not used anymore. 

706 Please use file.name to access this as an attribute. 

707 """ 

708 if create_key is not _internal_create_key: 

709 _Deprecated('EnumDescriptor') 

710 

711 super(EnumDescriptor, self).__init__( 

712 options, 'EnumOptions', name, full_name, file, 

713 containing_type, serialized_start=serialized_start, 

714 serialized_end=serialized_end, serialized_options=serialized_options) 

715 

716 self.values = values 

717 for value in self.values: 

718 value.file = file 

719 value.type = self 

720 self.values_by_name = dict((v.name, v) for v in values) 

721 # Values are reversed to ensure that the first alias is retained. 

722 self.values_by_number = dict((v.number, v) for v in reversed(values)) 

723 

724 @property 

725 def is_closed(self): 

726 """Returns true whether this is a "closed" enum. 

727 

728 This means that it: 

729 - Has a fixed set of values, rather than being equivalent to an int32. 

730 - Encountering values not in this set causes them to be treated as unknown 

731 fields. 

732 - The first value (i.e., the default) may be nonzero. 

733 

734 WARNING: Some runtimes currently have a quirk where non-closed enums are 

735 treated as closed when used as the type of fields defined in a 

736 `syntax = proto2;` file. This quirk is not present in all runtimes; as of 

737 writing, we know that: 

738 

739 - C++, Java, and C++-based Python share this quirk. 

740 - UPB and UPB-based Python do not. 

741 - PHP and Ruby treat all enums as open regardless of declaration. 

742 

743 Care should be taken when using this function to respect the target 

744 runtime's enum handling quirks. 

745 """ 

746 return self.file.syntax == 'proto2' 

747 

748 def CopyToProto(self, proto): 

749 """Copies this to a descriptor_pb2.EnumDescriptorProto. 

750 

751 Args: 

752 proto (descriptor_pb2.EnumDescriptorProto): An empty descriptor proto. 

753 """ 

754 # This function is overridden to give a better doc comment. 

755 super(EnumDescriptor, self).CopyToProto(proto) 

756 

757 

758class EnumValueDescriptor(DescriptorBase): 

759 

760 """Descriptor for a single value within an enum. 

761 

762 Attributes: 

763 name (str): Name of this value. 

764 index (int): Dense, 0-indexed index giving the order that this 

765 value appears textually within its enum in the .proto file. 

766 number (int): Actual number assigned to this enum value. 

767 type (EnumDescriptor): :class:`EnumDescriptor` to which this value 

768 belongs. Set by :class:`EnumDescriptor`'s constructor if we're 

769 passed into one. 

770 options (descriptor_pb2.EnumValueOptions): Enum value options message or 

771 None to use default enum value options options. 

772 """ 

773 

774 if _USE_C_DESCRIPTORS: 

775 _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor 

776 

777 def __new__(cls, name, index, number, 

778 type=None, # pylint: disable=redefined-builtin 

779 options=None, serialized_options=None, create_key=None): 

780 _message.Message._CheckCalledFromGeneratedFile() 

781 # There is no way we can build a complete EnumValueDescriptor with the 

782 # given parameters (the name of the Enum is not known, for example). 

783 # Fortunately generated files just pass it to the EnumDescriptor() 

784 # constructor, which will ignore it, so returning None is good enough. 

785 return None 

786 

787 def __init__(self, name, index, number, 

788 type=None, # pylint: disable=redefined-builtin 

789 options=None, serialized_options=None, create_key=None): 

790 """Arguments are as described in the attribute description above.""" 

791 if create_key is not _internal_create_key: 

792 _Deprecated('EnumValueDescriptor') 

793 

794 super(EnumValueDescriptor, self).__init__( 

795 type.file if type else None, 

796 options, 

797 serialized_options, 

798 'EnumValueOptions', 

799 ) 

800 self.name = name 

801 self.index = index 

802 self.number = number 

803 self.type = type 

804 

805 

806class OneofDescriptor(DescriptorBase): 

807 """Descriptor for a oneof field. 

808 

809 Attributes: 

810 name (str): Name of the oneof field. 

811 full_name (str): Full name of the oneof field, including package name. 

812 index (int): 0-based index giving the order of the oneof field inside 

813 its containing type. 

814 containing_type (Descriptor): :class:`Descriptor` of the protocol message 

815 type that contains this field. Set by the :class:`Descriptor` constructor 

816 if we're passed into one. 

817 fields (list[FieldDescriptor]): The list of field descriptors this 

818 oneof can contain. 

819 """ 

820 

821 if _USE_C_DESCRIPTORS: 

822 _C_DESCRIPTOR_CLASS = _message.OneofDescriptor 

823 

824 def __new__( 

825 cls, name, full_name, index, containing_type, fields, options=None, 

826 serialized_options=None, create_key=None): 

827 _message.Message._CheckCalledFromGeneratedFile() 

828 return _message.default_pool.FindOneofByName(full_name) 

829 

830 def __init__( 

831 self, name, full_name, index, containing_type, fields, options=None, 

832 serialized_options=None, create_key=None): 

833 """Arguments are as described in the attribute description above.""" 

834 if create_key is not _internal_create_key: 

835 _Deprecated('OneofDescriptor') 

836 

837 super(OneofDescriptor, self).__init__( 

838 containing_type.file if containing_type else None, 

839 options, 

840 serialized_options, 

841 'OneofOptions', 

842 ) 

843 self.name = name 

844 self.full_name = full_name 

845 self.index = index 

846 self.containing_type = containing_type 

847 self.fields = fields 

848 

849 

850class ServiceDescriptor(_NestedDescriptorBase): 

851 

852 """Descriptor for a service. 

853 

854 Attributes: 

855 name (str): Name of the service. 

856 full_name (str): Full name of the service, including package name. 

857 index (int): 0-indexed index giving the order that this services 

858 definition appears within the .proto file. 

859 methods (list[MethodDescriptor]): List of methods provided by this 

860 service. 

861 methods_by_name (dict(str, MethodDescriptor)): Same 

862 :class:`MethodDescriptor` objects as in :attr:`methods_by_name`, but 

863 indexed by "name" attribute in each :class:`MethodDescriptor`. 

864 options (descriptor_pb2.ServiceOptions): Service options message or 

865 None to use default service options. 

866 file (FileDescriptor): Reference to file info. 

867 """ 

868 

869 if _USE_C_DESCRIPTORS: 

870 _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor 

871 

872 def __new__( 

873 cls, 

874 name=None, 

875 full_name=None, 

876 index=None, 

877 methods=None, 

878 options=None, 

879 serialized_options=None, 

880 file=None, # pylint: disable=redefined-builtin 

881 serialized_start=None, 

882 serialized_end=None, 

883 create_key=None): 

884 _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access 

885 return _message.default_pool.FindServiceByName(full_name) 

886 

887 def __init__(self, name, full_name, index, methods, options=None, 

888 serialized_options=None, file=None, # pylint: disable=redefined-builtin 

889 serialized_start=None, serialized_end=None, create_key=None): 

890 if create_key is not _internal_create_key: 

891 _Deprecated('ServiceDescriptor') 

892 

893 super(ServiceDescriptor, self).__init__( 

894 options, 'ServiceOptions', name, full_name, file, 

895 None, serialized_start=serialized_start, 

896 serialized_end=serialized_end, serialized_options=serialized_options) 

897 self.index = index 

898 self.methods = methods 

899 self.methods_by_name = dict((m.name, m) for m in methods) 

900 # Set the containing service for each method in this service. 

901 for method in self.methods: 

902 method.file = self.file 

903 method.containing_service = self 

904 

905 def FindMethodByName(self, name): 

906 """Searches for the specified method, and returns its descriptor. 

907 

908 Args: 

909 name (str): Name of the method. 

910 

911 Returns: 

912 MethodDescriptor: The descriptor for the requested method. 

913 

914 Raises: 

915 KeyError: if the method cannot be found in the service. 

916 """ 

917 return self.methods_by_name[name] 

918 

919 def CopyToProto(self, proto): 

920 """Copies this to a descriptor_pb2.ServiceDescriptorProto. 

921 

922 Args: 

923 proto (descriptor_pb2.ServiceDescriptorProto): An empty descriptor proto. 

924 """ 

925 # This function is overridden to give a better doc comment. 

926 super(ServiceDescriptor, self).CopyToProto(proto) 

927 

928 

929class MethodDescriptor(DescriptorBase): 

930 

931 """Descriptor for a method in a service. 

932 

933 Attributes: 

934 name (str): Name of the method within the service. 

935 full_name (str): Full name of method. 

936 index (int): 0-indexed index of the method inside the service. 

937 containing_service (ServiceDescriptor): The service that contains this 

938 method. 

939 input_type (Descriptor): The descriptor of the message that this method 

940 accepts. 

941 output_type (Descriptor): The descriptor of the message that this method 

942 returns. 

943 client_streaming (bool): Whether this method uses client streaming. 

944 server_streaming (bool): Whether this method uses server streaming. 

945 options (descriptor_pb2.MethodOptions or None): Method options message, or 

946 None to use default method options. 

947 """ 

948 

949 if _USE_C_DESCRIPTORS: 

950 _C_DESCRIPTOR_CLASS = _message.MethodDescriptor 

951 

952 def __new__(cls, 

953 name, 

954 full_name, 

955 index, 

956 containing_service, 

957 input_type, 

958 output_type, 

959 client_streaming=False, 

960 server_streaming=False, 

961 options=None, 

962 serialized_options=None, 

963 create_key=None): 

964 _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access 

965 return _message.default_pool.FindMethodByName(full_name) 

966 

967 def __init__(self, 

968 name, 

969 full_name, 

970 index, 

971 containing_service, 

972 input_type, 

973 output_type, 

974 client_streaming=False, 

975 server_streaming=False, 

976 options=None, 

977 serialized_options=None, 

978 create_key=None): 

979 """The arguments are as described in the description of MethodDescriptor 

980 attributes above. 

981 

982 Note that containing_service may be None, and may be set later if necessary. 

983 """ 

984 if create_key is not _internal_create_key: 

985 _Deprecated('MethodDescriptor') 

986 

987 super(MethodDescriptor, self).__init__( 

988 containing_service.file if containing_service else None, 

989 options, 

990 serialized_options, 

991 'MethodOptions', 

992 ) 

993 self.name = name 

994 self.full_name = full_name 

995 self.index = index 

996 self.containing_service = containing_service 

997 self.input_type = input_type 

998 self.output_type = output_type 

999 self.client_streaming = client_streaming 

1000 self.server_streaming = server_streaming 

1001 

1002 def CopyToProto(self, proto): 

1003 """Copies this to a descriptor_pb2.MethodDescriptorProto. 

1004 

1005 Args: 

1006 proto (descriptor_pb2.MethodDescriptorProto): An empty descriptor proto. 

1007 

1008 Raises: 

1009 Error: If self couldn't be serialized, due to too few constructor 

1010 arguments. 

1011 """ 

1012 if self.containing_service is not None: 

1013 from google.protobuf import descriptor_pb2 

1014 service_proto = descriptor_pb2.ServiceDescriptorProto() 

1015 self.containing_service.CopyToProto(service_proto) 

1016 proto.CopyFrom(service_proto.method[self.index]) 

1017 else: 

1018 raise Error('Descriptor does not contain a service.') 

1019 

1020 

1021class FileDescriptor(DescriptorBase): 

1022 """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. 

1023 

1024 Note that :attr:`enum_types_by_name`, :attr:`extensions_by_name`, and 

1025 :attr:`dependencies` fields are only set by the 

1026 :py:mod:`google.protobuf.message_factory` module, and not by the generated 

1027 proto code. 

1028 

1029 Attributes: 

1030 name (str): Name of file, relative to root of source tree. 

1031 package (str): Name of the package 

1032 syntax (str): string indicating syntax of the file (can be "proto2" or 

1033 "proto3") 

1034 serialized_pb (bytes): Byte string of serialized 

1035 :class:`descriptor_pb2.FileDescriptorProto`. 

1036 dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor` 

1037 objects this :class:`FileDescriptor` depends on. 

1038 public_dependencies (list[FileDescriptor]): A subset of 

1039 :attr:`dependencies`, which were declared as "public". 

1040 message_types_by_name (dict(str, Descriptor)): Mapping from message names 

1041 to their :class:`Descriptor`. 

1042 enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to 

1043 their :class:`EnumDescriptor`. 

1044 extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension 

1045 names declared at file scope to their :class:`FieldDescriptor`. 

1046 services_by_name (dict(str, ServiceDescriptor)): Mapping from services' 

1047 names to their :class:`ServiceDescriptor`. 

1048 pool (DescriptorPool): The pool this descriptor belongs to. When not 

1049 passed to the constructor, the global default pool is used. 

1050 """ 

1051 

1052 if _USE_C_DESCRIPTORS: 

1053 _C_DESCRIPTOR_CLASS = _message.FileDescriptor 

1054 

1055 def __new__(cls, name, package, options=None, 

1056 serialized_options=None, serialized_pb=None, 

1057 dependencies=None, public_dependencies=None, 

1058 syntax=None, pool=None, create_key=None): 

1059 # FileDescriptor() is called from various places, not only from generated 

1060 # files, to register dynamic proto files and messages. 

1061 # pylint: disable=g-explicit-bool-comparison 

1062 if serialized_pb: 

1063 return _message.default_pool.AddSerializedFile(serialized_pb) 

1064 else: 

1065 return super(FileDescriptor, cls).__new__(cls) 

1066 

1067 def __init__(self, name, package, options=None, 

1068 serialized_options=None, serialized_pb=None, 

1069 dependencies=None, public_dependencies=None, 

1070 syntax=None, pool=None, create_key=None): 

1071 """Constructor.""" 

1072 if create_key is not _internal_create_key: 

1073 _Deprecated('FileDescriptor') 

1074 

1075 super(FileDescriptor, self).__init__( 

1076 None, options, serialized_options, 'FileOptions' 

1077 ) 

1078 

1079 if pool is None: 

1080 from google.protobuf import descriptor_pool 

1081 pool = descriptor_pool.Default() 

1082 self.pool = pool 

1083 self.message_types_by_name = {} 

1084 self.name = name 

1085 self.package = package 

1086 self.syntax = syntax or "proto2" 

1087 self.serialized_pb = serialized_pb 

1088 

1089 self.enum_types_by_name = {} 

1090 self.extensions_by_name = {} 

1091 self.services_by_name = {} 

1092 self.dependencies = (dependencies or []) 

1093 self.public_dependencies = (public_dependencies or []) 

1094 

1095 def CopyToProto(self, proto): 

1096 """Copies this to a descriptor_pb2.FileDescriptorProto. 

1097 

1098 Args: 

1099 proto: An empty descriptor_pb2.FileDescriptorProto. 

1100 """ 

1101 proto.ParseFromString(self.serialized_pb) 

1102 

1103 

1104def _ParseOptions(message, string): 

1105 """Parses serialized options. 

1106 

1107 This helper function is used to parse serialized options in generated 

1108 proto2 files. It must not be used outside proto2. 

1109 """ 

1110 message.ParseFromString(string) 

1111 return message 

1112 

1113 

1114def _ToCamelCase(name): 

1115 """Converts name to camel-case and returns it.""" 

1116 capitalize_next = False 

1117 result = [] 

1118 

1119 for c in name: 

1120 if c == '_': 

1121 if result: 

1122 capitalize_next = True 

1123 elif capitalize_next: 

1124 result.append(c.upper()) 

1125 capitalize_next = False 

1126 else: 

1127 result += c 

1128 

1129 # Lower-case the first letter. 

1130 if result and result[0].isupper(): 

1131 result[0] = result[0].lower() 

1132 return ''.join(result) 

1133 

1134 

1135def _OptionsOrNone(descriptor_proto): 

1136 """Returns the value of the field `options`, or None if it is not set.""" 

1137 if descriptor_proto.HasField('options'): 

1138 return descriptor_proto.options 

1139 else: 

1140 return None 

1141 

1142 

1143def _ToJsonName(name): 

1144 """Converts name to Json name and returns it.""" 

1145 capitalize_next = False 

1146 result = [] 

1147 

1148 for c in name: 

1149 if c == '_': 

1150 capitalize_next = True 

1151 elif capitalize_next: 

1152 result.append(c.upper()) 

1153 capitalize_next = False 

1154 else: 

1155 result += c 

1156 

1157 return ''.join(result) 

1158 

1159 

1160def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, 

1161 syntax=None): 

1162 """Make a protobuf Descriptor given a DescriptorProto protobuf. 

1163 

1164 Handles nested descriptors. Note that this is limited to the scope of defining 

1165 a message inside of another message. Composite fields can currently only be 

1166 resolved if the message is defined in the same scope as the field. 

1167 

1168 Args: 

1169 desc_proto: The descriptor_pb2.DescriptorProto protobuf message. 

1170 package: Optional package name for the new message Descriptor (string). 

1171 build_file_if_cpp: Update the C++ descriptor pool if api matches. 

1172 Set to False on recursion, so no duplicates are created. 

1173 syntax: The syntax/semantics that should be used. Set to "proto3" to get 

1174 proto3 field presence semantics. 

1175 Returns: 

1176 A Descriptor for protobuf messages. 

1177 """ 

1178 if api_implementation.Type() != 'python' and build_file_if_cpp: 

1179 # The C++ implementation requires all descriptors to be backed by the same 

1180 # definition in the C++ descriptor pool. To do this, we build a 

1181 # FileDescriptorProto with the same definition as this descriptor and build 

1182 # it into the pool. 

1183 from google.protobuf import descriptor_pb2 

1184 file_descriptor_proto = descriptor_pb2.FileDescriptorProto() 

1185 file_descriptor_proto.message_type.add().MergeFrom(desc_proto) 

1186 

1187 # Generate a random name for this proto file to prevent conflicts with any 

1188 # imported ones. We need to specify a file name so the descriptor pool 

1189 # accepts our FileDescriptorProto, but it is not important what that file 

1190 # name is actually set to. 

1191 proto_name = binascii.hexlify(os.urandom(16)).decode('ascii') 

1192 

1193 if package: 

1194 file_descriptor_proto.name = os.path.join(package.replace('.', '/'), 

1195 proto_name + '.proto') 

1196 file_descriptor_proto.package = package 

1197 else: 

1198 file_descriptor_proto.name = proto_name + '.proto' 

1199 

1200 _message.default_pool.Add(file_descriptor_proto) 

1201 result = _message.default_pool.FindFileByName(file_descriptor_proto.name) 

1202 

1203 if _USE_C_DESCRIPTORS: 

1204 return result.message_types_by_name[desc_proto.name] 

1205 

1206 full_message_name = [desc_proto.name] 

1207 if package: full_message_name.insert(0, package) 

1208 

1209 # Create Descriptors for enum types 

1210 enum_types = {} 

1211 for enum_proto in desc_proto.enum_type: 

1212 full_name = '.'.join(full_message_name + [enum_proto.name]) 

1213 enum_desc = EnumDescriptor( 

1214 enum_proto.name, full_name, None, [ 

1215 EnumValueDescriptor(enum_val.name, ii, enum_val.number, 

1216 create_key=_internal_create_key) 

1217 for ii, enum_val in enumerate(enum_proto.value)], 

1218 create_key=_internal_create_key) 

1219 enum_types[full_name] = enum_desc 

1220 

1221 # Create Descriptors for nested types 

1222 nested_types = {} 

1223 for nested_proto in desc_proto.nested_type: 

1224 full_name = '.'.join(full_message_name + [nested_proto.name]) 

1225 # Nested types are just those defined inside of the message, not all types 

1226 # used by fields in the message, so no loops are possible here. 

1227 nested_desc = MakeDescriptor(nested_proto, 

1228 package='.'.join(full_message_name), 

1229 build_file_if_cpp=False, 

1230 syntax=syntax) 

1231 nested_types[full_name] = nested_desc 

1232 

1233 fields = [] 

1234 for field_proto in desc_proto.field: 

1235 full_name = '.'.join(full_message_name + [field_proto.name]) 

1236 enum_desc = None 

1237 nested_desc = None 

1238 if field_proto.json_name: 

1239 json_name = field_proto.json_name 

1240 else: 

1241 json_name = None 

1242 if field_proto.HasField('type_name'): 

1243 type_name = field_proto.type_name 

1244 full_type_name = '.'.join(full_message_name + 

1245 [type_name[type_name.rfind('.')+1:]]) 

1246 if full_type_name in nested_types: 

1247 nested_desc = nested_types[full_type_name] 

1248 elif full_type_name in enum_types: 

1249 enum_desc = enum_types[full_type_name] 

1250 # Else type_name references a non-local type, which isn't implemented 

1251 field = FieldDescriptor( 

1252 field_proto.name, full_name, field_proto.number - 1, 

1253 field_proto.number, field_proto.type, 

1254 FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), 

1255 field_proto.label, None, nested_desc, enum_desc, None, False, None, 

1256 options=_OptionsOrNone(field_proto), has_default_value=False, 

1257 json_name=json_name, create_key=_internal_create_key) 

1258 fields.append(field) 

1259 

1260 desc_name = '.'.join(full_message_name) 

1261 return Descriptor(desc_proto.name, desc_name, None, None, fields, 

1262 list(nested_types.values()), list(enum_types.values()), [], 

1263 options=_OptionsOrNone(desc_proto), 

1264 create_key=_internal_create_key)