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

435 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:45 +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._deprecated_syntax = syntax or "proto2" 

357 self._is_map_entry = is_map_entry 

358 

359 @property 

360 def syntax(self): 

361 warnings.warn( 

362 'descriptor.syntax is deprecated. It will be removed' 

363 ' soon. Most usages are checking field descriptors. Consider to use' 

364 ' has_presence, is_packed on field descriptors.' 

365 ) 

366 return self._deprecated_syntax 

367 

368 @property 

369 def fields_by_camelcase_name(self): 

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

371 :attr:`FieldDescriptor.camelcase_name`. 

372 """ 

373 if self._fields_by_camelcase_name is None: 

374 self._fields_by_camelcase_name = dict( 

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

376 return self._fields_by_camelcase_name 

377 

378 def EnumValueName(self, enum, value): 

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

380 

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

382 

383 Args: 

384 enum: string name of the Enum. 

385 value: int, value of the enum. 

386 

387 Returns: 

388 string name of the enum value. 

389 

390 Raises: 

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

392 value for the enum. 

393 """ 

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

395 

396 def CopyToProto(self, proto): 

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

398 

399 Args: 

400 proto: An empty descriptor_pb2.DescriptorProto. 

401 """ 

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

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

404 

405 

406# TODO: We should have aggressive checking here, 

407# for example: 

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

409# to specify a default value. 

410# * [Other examples here as needed]. 

411# 

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

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

414# prevent clients from setting the attributes). Having 

415# stronger invariants here in general will reduce the number 

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

417class FieldDescriptor(DescriptorBase): 

418 

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

420 

421 Attributes: 

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

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

424 particularly relevant for extensions. 

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

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

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

428 

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

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

431 represent this field. 

432 

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

434 field is optional, required, or repeated. 

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

436 otherwise false. 

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

438 meaningful for non-repeated scalar fields. Repeated fields 

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

440 fields should always set this to None. 

441 

442 containing_type (Descriptor): Descriptor of the protocol message 

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

444 if we're passed into one. 

445 Somewhat confusingly, for extension fields, this is the 

446 descriptor of the EXTENDED message, not the descriptor 

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

448 extension_scope below). 

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

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

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

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

453 

454 is_extension: True iff this describes an extension field. 

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

456 Gives the message that immediately contains this extension field. 

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

458 

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

460 None to use default field options. 

461 

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

463 union, contains its descriptor. Otherwise, None. 

464 

465 file (FileDescriptor): Reference to file descriptor. 

466 """ 

467 

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

469 # descriptor.h. 

470 # 

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

472 TYPE_DOUBLE = 1 

473 TYPE_FLOAT = 2 

474 TYPE_INT64 = 3 

475 TYPE_UINT64 = 4 

476 TYPE_INT32 = 5 

477 TYPE_FIXED64 = 6 

478 TYPE_FIXED32 = 7 

479 TYPE_BOOL = 8 

480 TYPE_STRING = 9 

481 TYPE_GROUP = 10 

482 TYPE_MESSAGE = 11 

483 TYPE_BYTES = 12 

484 TYPE_UINT32 = 13 

485 TYPE_ENUM = 14 

486 TYPE_SFIXED32 = 15 

487 TYPE_SFIXED64 = 16 

488 TYPE_SINT32 = 17 

489 TYPE_SINT64 = 18 

490 MAX_TYPE = 18 

491 

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

493 # descriptor.h. 

494 # 

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

496 CPPTYPE_INT32 = 1 

497 CPPTYPE_INT64 = 2 

498 CPPTYPE_UINT32 = 3 

499 CPPTYPE_UINT64 = 4 

500 CPPTYPE_DOUBLE = 5 

501 CPPTYPE_FLOAT = 6 

502 CPPTYPE_BOOL = 7 

503 CPPTYPE_ENUM = 8 

504 CPPTYPE_STRING = 9 

505 CPPTYPE_MESSAGE = 10 

506 MAX_CPPTYPE = 10 

507 

508 _PYTHON_TO_CPP_PROTO_TYPE_MAP = { 

509 TYPE_DOUBLE: CPPTYPE_DOUBLE, 

510 TYPE_FLOAT: CPPTYPE_FLOAT, 

511 TYPE_ENUM: CPPTYPE_ENUM, 

512 TYPE_INT64: CPPTYPE_INT64, 

513 TYPE_SINT64: CPPTYPE_INT64, 

514 TYPE_SFIXED64: CPPTYPE_INT64, 

515 TYPE_UINT64: CPPTYPE_UINT64, 

516 TYPE_FIXED64: CPPTYPE_UINT64, 

517 TYPE_INT32: CPPTYPE_INT32, 

518 TYPE_SFIXED32: CPPTYPE_INT32, 

519 TYPE_SINT32: CPPTYPE_INT32, 

520 TYPE_UINT32: CPPTYPE_UINT32, 

521 TYPE_FIXED32: CPPTYPE_UINT32, 

522 TYPE_BYTES: CPPTYPE_STRING, 

523 TYPE_STRING: CPPTYPE_STRING, 

524 TYPE_BOOL: CPPTYPE_BOOL, 

525 TYPE_MESSAGE: CPPTYPE_MESSAGE, 

526 TYPE_GROUP: CPPTYPE_MESSAGE 

527 } 

528 

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

530 # descriptor.h. 

531 # 

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

533 LABEL_OPTIONAL = 1 

534 LABEL_REQUIRED = 2 

535 LABEL_REPEATED = 3 

536 MAX_LABEL = 3 

537 

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

539 # and kLastReservedNumber in descriptor.h 

540 MAX_FIELD_NUMBER = (1 << 29) - 1 

541 FIRST_RESERVED_FIELD_NUMBER = 19000 

542 LAST_RESERVED_FIELD_NUMBER = 19999 

543 

544 if _USE_C_DESCRIPTORS: 

545 _C_DESCRIPTOR_CLASS = _message.FieldDescriptor 

546 

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

548 default_value, message_type, enum_type, containing_type, 

549 is_extension, extension_scope, options=None, 

550 serialized_options=None, 

551 has_default_value=True, containing_oneof=None, json_name=None, 

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

553 _message.Message._CheckCalledFromGeneratedFile() 

554 if is_extension: 

555 return _message.default_pool.FindExtensionByName(full_name) 

556 else: 

557 return _message.default_pool.FindFieldByName(full_name) 

558 

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

560 default_value, message_type, enum_type, containing_type, 

561 is_extension, extension_scope, options=None, 

562 serialized_options=None, 

563 has_default_value=True, containing_oneof=None, json_name=None, 

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

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

566 attributes above. 

567 

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

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

570 Likewise for extension_scope. 

571 """ 

572 if create_key is not _internal_create_key: 

573 _Deprecated('FieldDescriptor') 

574 

575 super(FieldDescriptor, self).__init__( 

576 file, options, serialized_options, 'FieldOptions' 

577 ) 

578 self.name = name 

579 self.full_name = full_name 

580 self._camelcase_name = None 

581 if json_name is None: 

582 self.json_name = _ToJsonName(name) 

583 else: 

584 self.json_name = json_name 

585 self.index = index 

586 self.number = number 

587 self.type = type 

588 self.cpp_type = cpp_type 

589 self.label = label 

590 self.has_default_value = has_default_value 

591 self.default_value = default_value 

592 self.containing_type = containing_type 

593 self.message_type = message_type 

594 self.enum_type = enum_type 

595 self.is_extension = is_extension 

596 self.extension_scope = extension_scope 

597 self.containing_oneof = containing_oneof 

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

599 self._cdescriptor = None 

600 else: 

601 if is_extension: 

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

603 else: 

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

605 

606 @property 

607 def camelcase_name(self): 

608 """Camelcase name of this field. 

609 

610 Returns: 

611 str: the name in CamelCase. 

612 """ 

613 if self._camelcase_name is None: 

614 self._camelcase_name = _ToCamelCase(self.name) 

615 return self._camelcase_name 

616 

617 @property 

618 def has_presence(self): 

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

620 

621 Raises: 

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

623 """ 

624 if self.label == FieldDescriptor.LABEL_REPEATED: 

625 return False 

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

627 self.containing_oneof): 

628 return True 

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

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

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

632 # TODO: remove syntax usage b/240619313 

633 return self.containing_type._deprecated_syntax == 'proto2' 

634 

635 @property 

636 def is_packed(self): 

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

638 if self.label != FieldDescriptor.LABEL_REPEATED: 

639 return False 

640 field_type = self.type 

641 if (field_type == FieldDescriptor.TYPE_STRING or 

642 field_type == FieldDescriptor.TYPE_GROUP or 

643 field_type == FieldDescriptor.TYPE_MESSAGE or 

644 field_type == FieldDescriptor.TYPE_BYTES): 

645 return False 

646 if self.containing_type._deprecated_syntax == 'proto2': 

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

648 else: 

649 return (not self.has_options or 

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

651 self.GetOptions().packed) 

652 

653 @staticmethod 

654 def ProtoTypeToCppProtoType(proto_type): 

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

656 

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

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

659 translate from one to another. 

660 

661 Args: 

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

663 Returns: 

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

665 Raises: 

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

667 """ 

668 try: 

669 return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] 

670 except KeyError: 

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

672 

673 

674class EnumDescriptor(_NestedDescriptorBase): 

675 

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

677 

678 Attributes: 

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

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

681 and any enclosing type(s). 

682 

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

684 in this enum. 

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

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

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

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

689 containing_type (Descriptor): Descriptor of the immediate containing 

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

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

692 if we're passed into one. 

693 file (FileDescriptor): Reference to file descriptor. 

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

695 None to use default enum options. 

696 """ 

697 

698 if _USE_C_DESCRIPTORS: 

699 _C_DESCRIPTOR_CLASS = _message.EnumDescriptor 

700 

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

702 containing_type=None, options=None, 

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

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

705 _message.Message._CheckCalledFromGeneratedFile() 

706 return _message.default_pool.FindEnumTypeByName(full_name) 

707 

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

709 containing_type=None, options=None, 

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

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

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

713 

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

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

716 """ 

717 if create_key is not _internal_create_key: 

718 _Deprecated('EnumDescriptor') 

719 

720 super(EnumDescriptor, self).__init__( 

721 options, 'EnumOptions', name, full_name, file, 

722 containing_type, serialized_start=serialized_start, 

723 serialized_end=serialized_end, serialized_options=serialized_options) 

724 

725 self.values = values 

726 for value in self.values: 

727 value.file = file 

728 value.type = self 

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

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

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

732 

733 @property 

734 def is_closed(self): 

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

736 

737 This means that it: 

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

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

740 fields. 

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

742 

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

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

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

746 writing, we know that: 

747 

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

749 - UPB and UPB-based Python do not. 

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

751 

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

753 runtime's enum handling quirks. 

754 """ 

755 return self.file._deprecated_syntax == 'proto2' 

756 

757 def CopyToProto(self, proto): 

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

759 

760 Args: 

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

762 """ 

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

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

765 

766 

767class EnumValueDescriptor(DescriptorBase): 

768 

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

770 

771 Attributes: 

772 name (str): Name of this value. 

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

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

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

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

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

778 passed into one. 

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

780 None to use default enum value options options. 

781 """ 

782 

783 if _USE_C_DESCRIPTORS: 

784 _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor 

785 

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

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

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

789 _message.Message._CheckCalledFromGeneratedFile() 

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

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

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

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

794 return None 

795 

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

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

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

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

800 if create_key is not _internal_create_key: 

801 _Deprecated('EnumValueDescriptor') 

802 

803 super(EnumValueDescriptor, self).__init__( 

804 type.file if type else None, 

805 options, 

806 serialized_options, 

807 'EnumValueOptions', 

808 ) 

809 self.name = name 

810 self.index = index 

811 self.number = number 

812 self.type = type 

813 

814 

815class OneofDescriptor(DescriptorBase): 

816 """Descriptor for a oneof field. 

817 

818 Attributes: 

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

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

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

822 its containing type. 

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

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

825 if we're passed into one. 

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

827 oneof can contain. 

828 """ 

829 

830 if _USE_C_DESCRIPTORS: 

831 _C_DESCRIPTOR_CLASS = _message.OneofDescriptor 

832 

833 def __new__( 

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

835 serialized_options=None, create_key=None): 

836 _message.Message._CheckCalledFromGeneratedFile() 

837 return _message.default_pool.FindOneofByName(full_name) 

838 

839 def __init__( 

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

841 serialized_options=None, create_key=None): 

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

843 if create_key is not _internal_create_key: 

844 _Deprecated('OneofDescriptor') 

845 

846 super(OneofDescriptor, self).__init__( 

847 containing_type.file if containing_type else None, 

848 options, 

849 serialized_options, 

850 'OneofOptions', 

851 ) 

852 self.name = name 

853 self.full_name = full_name 

854 self.index = index 

855 self.containing_type = containing_type 

856 self.fields = fields 

857 

858 

859class ServiceDescriptor(_NestedDescriptorBase): 

860 

861 """Descriptor for a service. 

862 

863 Attributes: 

864 name (str): Name of the service. 

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

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

867 definition appears within the .proto file. 

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

869 service. 

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

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

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

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

874 None to use default service options. 

875 file (FileDescriptor): Reference to file info. 

876 """ 

877 

878 if _USE_C_DESCRIPTORS: 

879 _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor 

880 

881 def __new__( 

882 cls, 

883 name=None, 

884 full_name=None, 

885 index=None, 

886 methods=None, 

887 options=None, 

888 serialized_options=None, 

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

890 serialized_start=None, 

891 serialized_end=None, 

892 create_key=None): 

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

894 return _message.default_pool.FindServiceByName(full_name) 

895 

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

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

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

899 if create_key is not _internal_create_key: 

900 _Deprecated('ServiceDescriptor') 

901 

902 super(ServiceDescriptor, self).__init__( 

903 options, 'ServiceOptions', name, full_name, file, 

904 None, serialized_start=serialized_start, 

905 serialized_end=serialized_end, serialized_options=serialized_options) 

906 self.index = index 

907 self.methods = methods 

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

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

910 for method in self.methods: 

911 method.file = self.file 

912 method.containing_service = self 

913 

914 def FindMethodByName(self, name): 

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

916 

917 Args: 

918 name (str): Name of the method. 

919 

920 Returns: 

921 MethodDescriptor: The descriptor for the requested method. 

922 

923 Raises: 

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

925 """ 

926 return self.methods_by_name[name] 

927 

928 def CopyToProto(self, proto): 

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

930 

931 Args: 

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

933 """ 

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

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

936 

937 

938class MethodDescriptor(DescriptorBase): 

939 

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

941 

942 Attributes: 

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

944 full_name (str): Full name of method. 

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

946 containing_service (ServiceDescriptor): The service that contains this 

947 method. 

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

949 accepts. 

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

951 returns. 

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

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

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

955 None to use default method options. 

956 """ 

957 

958 if _USE_C_DESCRIPTORS: 

959 _C_DESCRIPTOR_CLASS = _message.MethodDescriptor 

960 

961 def __new__(cls, 

962 name, 

963 full_name, 

964 index, 

965 containing_service, 

966 input_type, 

967 output_type, 

968 client_streaming=False, 

969 server_streaming=False, 

970 options=None, 

971 serialized_options=None, 

972 create_key=None): 

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

974 return _message.default_pool.FindMethodByName(full_name) 

975 

976 def __init__(self, 

977 name, 

978 full_name, 

979 index, 

980 containing_service, 

981 input_type, 

982 output_type, 

983 client_streaming=False, 

984 server_streaming=False, 

985 options=None, 

986 serialized_options=None, 

987 create_key=None): 

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

989 attributes above. 

990 

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

992 """ 

993 if create_key is not _internal_create_key: 

994 _Deprecated('MethodDescriptor') 

995 

996 super(MethodDescriptor, self).__init__( 

997 containing_service.file if containing_service else None, 

998 options, 

999 serialized_options, 

1000 'MethodOptions', 

1001 ) 

1002 self.name = name 

1003 self.full_name = full_name 

1004 self.index = index 

1005 self.containing_service = containing_service 

1006 self.input_type = input_type 

1007 self.output_type = output_type 

1008 self.client_streaming = client_streaming 

1009 self.server_streaming = server_streaming 

1010 

1011 def CopyToProto(self, proto): 

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

1013 

1014 Args: 

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

1016 

1017 Raises: 

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

1019 arguments. 

1020 """ 

1021 if self.containing_service is not None: 

1022 from google.protobuf import descriptor_pb2 

1023 service_proto = descriptor_pb2.ServiceDescriptorProto() 

1024 self.containing_service.CopyToProto(service_proto) 

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

1026 else: 

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

1028 

1029 

1030class FileDescriptor(DescriptorBase): 

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

1032 

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

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

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

1036 proto code. 

1037 

1038 Attributes: 

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

1040 package (str): Name of the package 

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

1042 "proto3") 

1043 serialized_pb (bytes): Byte string of serialized 

1044 :class:`descriptor_pb2.FileDescriptorProto`. 

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

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

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

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

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

1050 to their :class:`Descriptor`. 

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

1052 their :class:`EnumDescriptor`. 

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

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

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

1056 names to their :class:`ServiceDescriptor`. 

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

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

1059 """ 

1060 

1061 if _USE_C_DESCRIPTORS: 

1062 _C_DESCRIPTOR_CLASS = _message.FileDescriptor 

1063 

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

1065 serialized_options=None, serialized_pb=None, 

1066 dependencies=None, public_dependencies=None, 

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

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

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

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

1071 if serialized_pb: 

1072 return _message.default_pool.AddSerializedFile(serialized_pb) 

1073 else: 

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

1075 

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

1077 serialized_options=None, serialized_pb=None, 

1078 dependencies=None, public_dependencies=None, 

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

1080 """Constructor.""" 

1081 if create_key is not _internal_create_key: 

1082 _Deprecated('FileDescriptor') 

1083 

1084 super(FileDescriptor, self).__init__( 

1085 None, options, serialized_options, 'FileOptions' 

1086 ) 

1087 

1088 if pool is None: 

1089 from google.protobuf import descriptor_pool 

1090 pool = descriptor_pool.Default() 

1091 self.pool = pool 

1092 self.message_types_by_name = {} 

1093 self.name = name 

1094 self.package = package 

1095 self._deprecated_syntax = syntax or "proto2" 

1096 self.serialized_pb = serialized_pb 

1097 

1098 self.enum_types_by_name = {} 

1099 self.extensions_by_name = {} 

1100 self.services_by_name = {} 

1101 self.dependencies = (dependencies or []) 

1102 self.public_dependencies = (public_dependencies or []) 

1103 

1104 @property 

1105 def syntax(self): 

1106 warnings.warn( 

1107 'descriptor.syntax is deprecated. It will be removed' 

1108 ' soon. Most usages are checking field descriptors. Consider to use' 

1109 ' has_presence, is_packed on field descriptors.' 

1110 ) 

1111 return self._deprecated_syntax 

1112 

1113 def CopyToProto(self, proto): 

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

1115 

1116 Args: 

1117 proto: An empty descriptor_pb2.FileDescriptorProto. 

1118 """ 

1119 proto.ParseFromString(self.serialized_pb) 

1120 

1121 

1122def _ParseOptions(message, string): 

1123 """Parses serialized options. 

1124 

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

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

1127 """ 

1128 message.ParseFromString(string) 

1129 return message 

1130 

1131 

1132def _ToCamelCase(name): 

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

1134 capitalize_next = False 

1135 result = [] 

1136 

1137 for c in name: 

1138 if c == '_': 

1139 if result: 

1140 capitalize_next = True 

1141 elif capitalize_next: 

1142 result.append(c.upper()) 

1143 capitalize_next = False 

1144 else: 

1145 result += c 

1146 

1147 # Lower-case the first letter. 

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

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

1150 return ''.join(result) 

1151 

1152 

1153def _OptionsOrNone(descriptor_proto): 

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

1155 if descriptor_proto.HasField('options'): 

1156 return descriptor_proto.options 

1157 else: 

1158 return None 

1159 

1160 

1161def _ToJsonName(name): 

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

1163 capitalize_next = False 

1164 result = [] 

1165 

1166 for c in name: 

1167 if c == '_': 

1168 capitalize_next = True 

1169 elif capitalize_next: 

1170 result.append(c.upper()) 

1171 capitalize_next = False 

1172 else: 

1173 result += c 

1174 

1175 return ''.join(result) 

1176 

1177 

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

1179 syntax=None): 

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

1181 

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

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

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

1185 

1186 Args: 

1187 desc_proto: The descriptor_pb2.DescriptorProto protobuf message. 

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

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

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

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

1192 proto3 field presence semantics. 

1193 Returns: 

1194 A Descriptor for protobuf messages. 

1195 """ 

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

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

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

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

1200 # it into the pool. 

1201 from google.protobuf import descriptor_pb2 

1202 file_descriptor_proto = descriptor_pb2.FileDescriptorProto() 

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

1204 

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

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

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

1208 # name is actually set to. 

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

1210 

1211 if package: 

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

1213 proto_name + '.proto') 

1214 file_descriptor_proto.package = package 

1215 else: 

1216 file_descriptor_proto.name = proto_name + '.proto' 

1217 

1218 _message.default_pool.Add(file_descriptor_proto) 

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

1220 

1221 if _USE_C_DESCRIPTORS: 

1222 return result.message_types_by_name[desc_proto.name] 

1223 

1224 full_message_name = [desc_proto.name] 

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

1226 

1227 # Create Descriptors for enum types 

1228 enum_types = {} 

1229 for enum_proto in desc_proto.enum_type: 

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

1231 enum_desc = EnumDescriptor( 

1232 enum_proto.name, full_name, None, [ 

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

1234 create_key=_internal_create_key) 

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

1236 create_key=_internal_create_key) 

1237 enum_types[full_name] = enum_desc 

1238 

1239 # Create Descriptors for nested types 

1240 nested_types = {} 

1241 for nested_proto in desc_proto.nested_type: 

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

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

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

1245 nested_desc = MakeDescriptor(nested_proto, 

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

1247 build_file_if_cpp=False, 

1248 syntax=syntax) 

1249 nested_types[full_name] = nested_desc 

1250 

1251 fields = [] 

1252 for field_proto in desc_proto.field: 

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

1254 enum_desc = None 

1255 nested_desc = None 

1256 if field_proto.json_name: 

1257 json_name = field_proto.json_name 

1258 else: 

1259 json_name = None 

1260 if field_proto.HasField('type_name'): 

1261 type_name = field_proto.type_name 

1262 full_type_name = '.'.join(full_message_name + 

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

1264 if full_type_name in nested_types: 

1265 nested_desc = nested_types[full_type_name] 

1266 elif full_type_name in enum_types: 

1267 enum_desc = enum_types[full_type_name] 

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

1269 field = FieldDescriptor( 

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

1271 field_proto.number, field_proto.type, 

1272 FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), 

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

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

1275 json_name=json_name, create_key=_internal_create_key) 

1276 fields.append(field) 

1277 

1278 desc_name = '.'.join(full_message_name) 

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

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

1281 options=_OptionsOrNone(desc_proto), 

1282 create_key=_internal_create_key)