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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

534 statements  

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"""Descriptors essentially contain exactly the information found in a .proto 

8 

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

10""" 

11 

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

13 

14import abc 

15import binascii 

16import os 

17import threading 

18import warnings 

19 

20from google.protobuf.internal import api_implementation 

21 

22_USE_C_DESCRIPTORS = False 

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

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 

53 

54else: 

55 # The standard metaclass; nothing changes. 

56 DescriptorMetaclass = abc.ABCMeta 

57 

58 

59class _Lock(object): 

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

61 

62 def __new__(cls): 

63 self = object.__new__(cls) 

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

65 return self 

66 

67 def __enter__(self): 

68 self._lock.acquire() 

69 

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

71 self._lock.release() 

72 

73 

74_lock = threading.Lock() 

75 

76 

77def _Deprecated( 

78 name, 

79 alternative='get/find descriptors from generated code or query the descriptor_pool', 

80): 

81 if _Deprecated.count > 0: 

82 _Deprecated.count -= 1 

83 warnings.warn( 

84 'Call to deprecated %s, use %s instead.' % (name, alternative), 

85 category=DeprecationWarning, 

86 stacklevel=3, 

87 ) 

88 

89 

90# These must match the values in descriptor.proto, but we can't use them 

91# directly because we sometimes need to reference them in feature helpers 

92# below *during* the build of descriptor.proto. 

93_FEATURESET_MESSAGE_ENCODING_DELIMITED = 2 

94_FEATURESET_FIELD_PRESENCE_IMPLICIT = 2 

95_FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED = 3 

96_FEATURESET_REPEATED_FIELD_ENCODING_PACKED = 1 

97_FEATURESET_ENUM_TYPE_CLOSED = 2 

98 

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

100# users to notice and do not cause timeout. 

101_Deprecated.count = 100 

102 

103_internal_create_key = object() 

104 

105 

106class DescriptorBase(metaclass=DescriptorMetaclass): 

107 """Descriptors base class. 

108 

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

110 related functionality. 

111 

112 Attributes: 

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

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

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

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

117 some bootstrapping issues. 

118 file (FileDescriptor): Reference to file info. 

119 """ 

120 

121 if _USE_C_DESCRIPTORS: 

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

123 # subclasses" of this descriptor class. 

124 _C_DESCRIPTOR_CLASS = () 

125 

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

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

128 

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

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

131 """ 

132 self._features = None 

133 self.file = file 

134 self._original_options = options 

135 # These two fields are duplicated as a compatibility shim for old gencode 

136 # that resets them. In 26.x (cl/580304039) we renamed _options to, 

137 # _loaded_options breaking backwards compatibility. 

138 self._options = self._loaded_options = None 

139 self._options_class_name = options_class_name 

140 self._serialized_options = serialized_options 

141 

142 # Does this descriptor have non-default options? 

143 self.has_options = (self._original_options is not None) or ( 

144 self._serialized_options is not None 

145 ) 

146 

147 @property 

148 @abc.abstractmethod 

149 def _parent(self): 

150 pass 

151 

152 def _InferLegacyFeatures(self, edition, options, features): 

153 """Infers features from proto2/proto3 syntax so that editions logic can be used everywhere. 

154 

155 Args: 

156 edition: The edition to infer features for. 

157 options: The options for this descriptor that are being processed. 

158 features: The feature set object to modify with inferred features. 

159 """ 

160 pass 

161 

162 def _GetFeatures(self): 

163 if not self._features: 

164 self._LazyLoadOptions() 

165 return self._features 

166 

167 def _ResolveFeatures(self, edition, raw_options): 

168 """Resolves features from the raw options of this descriptor. 

169 

170 Args: 

171 edition: The edition to use for feature defaults. 

172 raw_options: The options for this descriptor that are being processed. 

173 

174 Returns: 

175 A fully resolved feature set for making runtime decisions. 

176 """ 

177 # pylint: disable=g-import-not-at-top 

178 from google.protobuf import descriptor_pb2 

179 

180 if self._parent: 

181 features = descriptor_pb2.FeatureSet() 

182 features.CopyFrom(self._parent._GetFeatures()) 

183 else: 

184 features = self.file.pool._CreateDefaultFeatures(edition) 

185 unresolved = descriptor_pb2.FeatureSet() 

186 unresolved.CopyFrom(raw_options.features) 

187 self._InferLegacyFeatures(edition, raw_options, unresolved) 

188 features.MergeFrom(unresolved) 

189 

190 # Use the feature cache to reduce memory bloat. 

191 return self.file.pool._InternFeatures(features) 

192 

193 def _LazyLoadOptions(self): 

194 """Lazily initializes descriptor options towards the end of the build.""" 

195 if self._options and self._loaded_options == self._options: 

196 # If neither has been reset by gencode, use the cache. 

197 return 

198 

199 # pylint: disable=g-import-not-at-top 

200 from google.protobuf import descriptor_pb2 

201 

202 if not hasattr(descriptor_pb2, self._options_class_name): 

203 raise RuntimeError( 

204 'Unknown options class name %s!' % self._options_class_name 

205 ) 

206 options_class = getattr(descriptor_pb2, self._options_class_name) 

207 features = None 

208 edition = self.file._edition 

209 

210 if not self.has_options: 

211 if not self._features: 

212 features = self._ResolveFeatures( 

213 descriptor_pb2.Edition.Value(edition), options_class() 

214 ) 

215 with _lock: 

216 self._options = self._loaded_options = options_class() 

217 if not self._features: 

218 self._features = features 

219 else: 

220 if not self._serialized_options: 

221 options = self._original_options 

222 else: 

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

224 

225 if not self._features: 

226 features = self._ResolveFeatures( 

227 descriptor_pb2.Edition.Value(edition), options 

228 ) 

229 with _lock: 

230 self._options = self._loaded_options = options 

231 if not self._features: 

232 self._features = features 

233 if options.HasField('features'): 

234 options.ClearField('features') 

235 if not options.SerializeToString(): 

236 self._options = self._loaded_options = options_class() 

237 self.has_options = False 

238 

239 def GetOptions(self): 

240 """Retrieves descriptor options. 

241 

242 Returns: 

243 The options set on this descriptor. 

244 """ 

245 # If either has been reset by gencode, reload options. 

246 if not self._options or not self._loaded_options: 

247 self._LazyLoadOptions() 

248 if ( 

249 self._options 

250 and hasattr(self._options, '_SetFrozen') 

251 and not getattr(self._options, '_frozen', False) 

252 ): 

253 self._options._SetFrozen() 

254 return self._options 

255 

256 

257class _NestedDescriptorBase(DescriptorBase): 

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

259 

260 def __init__( 

261 self, 

262 options, 

263 options_class_name, 

264 name, 

265 full_name, 

266 file, 

267 containing_type, 

268 serialized_start=None, 

269 serialized_end=None, 

270 serialized_options=None, 

271 ): 

272 """Constructor. 

273 

274 Args: 

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

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

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

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

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

280 types. 

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

282 descriptor as parent, otherwise None. 

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

284 file.serialized_pb that describes this descriptor. 

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

286 file.serialized_pb that describes this descriptor. 

287 serialized_options: Protocol message serialized options or None. 

288 """ 

289 super(_NestedDescriptorBase, self).__init__( 

290 file, options, serialized_options, options_class_name 

291 ) 

292 

293 self.name = name 

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

295 # memory? 

296 self.full_name = full_name 

297 self.containing_type = containing_type 

298 

299 self._serialized_start = serialized_start 

300 self._serialized_end = serialized_end 

301 

302 def CopyToProto(self, proto): 

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

304 

305 Args: 

306 proto: An empty proto instance from descriptor_pb2. 

307 

308 Raises: 

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

310 arguments. 

311 """ 

312 if ( 

313 self.file is not None 

314 and self._serialized_start is not None 

315 and self._serialized_end is not None 

316 ): 

317 proto.ParseFromString( 

318 self.file.serialized_pb[self._serialized_start : self._serialized_end] 

319 ) 

320 else: 

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

322 

323 

324class Descriptor(_NestedDescriptorBase): 

325 """Descriptor for a protocol message type. 

326 

327 Attributes: 

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

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

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

331 types. 

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

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

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

335 type. 

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

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

338 "number" attribute in each FieldDescriptor. 

339 fields_by_name (dict(str, FieldDescriptor)): Same :class:`FieldDescriptor` 

340 objects as in :attr:`fields`, but indexed by "name" attribute in each 

341 :class:`FieldDescriptor`. 

342 nested_types (list[Descriptor]): Descriptor references for all protocol 

343 message types nested within this one. 

344 nested_types_by_name (dict(str, Descriptor)): Same Descriptor objects as 

345 in :attr:`nested_types`, but indexed by "name" attribute in each 

346 Descriptor. 

347 enum_types (list[EnumDescriptor]): :class:`EnumDescriptor` references for 

348 all enums contained within this type. 

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

350 :class:`EnumDescriptor` objects as in :attr:`enum_types`, but indexed by 

351 "name" attribute in each EnumDescriptor. 

352 enum_values_by_name (dict(str, EnumValueDescriptor)): Dict mapping from 

353 enum value name to :class:`EnumValueDescriptor` for that value. 

354 extensions (list[FieldDescriptor]): All extensions defined directly within 

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

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

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

358 FieldDescriptor. 

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

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

361 in this message. 

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

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

364 file (FileDescriptor): Reference to file descriptor. 

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

366 """ 

367 

368 if _USE_C_DESCRIPTORS: 

369 _C_DESCRIPTOR_CLASS = _message.Descriptor 

370 

371 def __new__( 

372 cls, 

373 name=None, 

374 full_name=None, 

375 filename=None, 

376 containing_type=None, 

377 fields=None, 

378 nested_types=None, 

379 enum_types=None, 

380 extensions=None, 

381 options=None, 

382 serialized_options=None, 

383 is_extendable=True, 

384 extension_ranges=None, 

385 oneofs=None, 

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

387 serialized_start=None, 

388 serialized_end=None, 

389 syntax=None, 

390 is_map_entry=False, 

391 create_key=None, 

392 ): 

393 _message.Message._CheckCalledFromGeneratedFile() 

394 return _message.default_pool.FindMessageTypeByName(full_name) 

395 

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

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

398 # name of the argument. 

399 def __init__( 

400 self, 

401 name, 

402 full_name, 

403 filename, 

404 containing_type, 

405 fields, 

406 nested_types, 

407 enum_types, 

408 extensions, 

409 options=None, 

410 serialized_options=None, 

411 is_extendable=True, 

412 extension_ranges=None, 

413 oneofs=None, 

414 file=None, 

415 serialized_start=None, 

416 serialized_end=None, # pylint: disable=redefined-builtin 

417 syntax=None, 

418 is_map_entry=False, 

419 create_key=None, 

420 ): 

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

422 

423 of Descriptor fields above. 

424 

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

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

427 """ 

428 if create_key is not _internal_create_key: 

429 _Deprecated('create function Descriptor()') 

430 

431 super(Descriptor, self).__init__( 

432 options, 

433 'MessageOptions', 

434 name, 

435 full_name, 

436 file, 

437 containing_type, 

438 serialized_start=serialized_start, 

439 serialized_end=serialized_end, 

440 serialized_options=serialized_options, 

441 ) 

442 

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

444 # so that: 

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

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

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

448 self.fields = fields 

449 for field in self.fields: 

450 field.containing_type = self 

451 field.file = file 

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

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

454 self._fields_by_camelcase_name = None 

455 

456 self.nested_types = nested_types 

457 for nested_type in nested_types: 

458 nested_type.containing_type = self 

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

460 

461 self.enum_types = enum_types 

462 for enum_type in self.enum_types: 

463 enum_type.containing_type = self 

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

465 self.enum_values_by_name = dict( 

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

467 ) 

468 

469 self.extensions = extensions 

470 for extension in self.extensions: 

471 extension.extension_scope = self 

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

473 self.is_extendable = is_extendable 

474 self.extension_ranges = extension_ranges 

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

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

477 for oneof in self.oneofs: 

478 oneof.containing_type = self 

479 oneof.file = file 

480 self._is_map_entry = is_map_entry 

481 

482 @property 

483 def _parent(self): 

484 return self.containing_type or self.file 

485 

486 @property 

487 def fields_by_camelcase_name(self): 

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

489 

490 :attr:`FieldDescriptor.camelcase_name`. 

491 """ 

492 if self._fields_by_camelcase_name is None: 

493 self._fields_by_camelcase_name = dict( 

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

495 ) 

496 return self._fields_by_camelcase_name 

497 

498 def EnumValueName(self, enum, value): 

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

500 

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

502 

503 Args: 

504 enum: string name of the Enum. 

505 value: int, value of the enum. 

506 

507 Returns: 

508 string name of the enum value. 

509 

510 Raises: 

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

512 value for the enum. 

513 """ 

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

515 

516 def CopyToProto(self, proto): 

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

518 

519 Args: 

520 proto: An empty descriptor_pb2.DescriptorProto. 

521 """ 

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

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

524 

525 

526# TODO: We should have aggressive checking here, 

527# for example: 

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

529# to specify a default value. 

530# * [Other examples here as needed]. 

531# 

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

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

534# prevent clients from setting the attributes). Having 

535# stronger invariants here in general will reduce the number 

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

537class FieldDescriptor(DescriptorBase): 

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

539 

540 Attributes: 

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

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

543 particularly relevant for extensions. 

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

545 textually appears within its message in the .proto file. 

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

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

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

549 represent this field. 

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

551 is optional, required, or repeated. 

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

553 otherwise false. 

554 default_value (Varies): Default value of this field. Only meaningful for 

555 non-repeated scalar fields. Repeated fields should always set this to [], 

556 and non-repeated composite fields should always set this to None. 

557 containing_type (Descriptor): Descriptor of the protocol message type that 

558 contains this field. Set by the Descriptor constructor if we're passed 

559 into one. Somewhat confusingly, for extension fields, this is the 

560 descriptor of the EXTENDED message, not the descriptor of the message 

561 containing this field. (See is_extension and extension_scope below). 

562 message_type (Descriptor): If a composite field, a descriptor of the message 

563 type contained in this field. Otherwise, this is None. 

564 enum_type (EnumDescriptor): If this field contains an enum, a descriptor of 

565 that enum. Otherwise, this is None. 

566 is_extension: True iff this describes an extension field. 

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

568 the message that immediately contains this extension field. Will be None 

569 iff we're a top-level (file-level) extension field. 

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

571 None to use default field options. 

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

573 union, contains its descriptor. Otherwise, None. 

574 file (FileDescriptor): Reference to file descriptor. 

575 """ 

576 

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

578 # descriptor.h. 

579 # 

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

581 TYPE_DOUBLE = 1 

582 TYPE_FLOAT = 2 

583 TYPE_INT64 = 3 

584 TYPE_UINT64 = 4 

585 TYPE_INT32 = 5 

586 TYPE_FIXED64 = 6 

587 TYPE_FIXED32 = 7 

588 TYPE_BOOL = 8 

589 TYPE_STRING = 9 

590 TYPE_GROUP = 10 

591 TYPE_MESSAGE = 11 

592 TYPE_BYTES = 12 

593 TYPE_UINT32 = 13 

594 TYPE_ENUM = 14 

595 TYPE_SFIXED32 = 15 

596 TYPE_SFIXED64 = 16 

597 TYPE_SINT32 = 17 

598 TYPE_SINT64 = 18 

599 MAX_TYPE = 18 

600 

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

602 # descriptor.h. 

603 # 

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

605 CPPTYPE_INT32 = 1 

606 CPPTYPE_INT64 = 2 

607 CPPTYPE_UINT32 = 3 

608 CPPTYPE_UINT64 = 4 

609 CPPTYPE_DOUBLE = 5 

610 CPPTYPE_FLOAT = 6 

611 CPPTYPE_BOOL = 7 

612 CPPTYPE_ENUM = 8 

613 CPPTYPE_STRING = 9 

614 CPPTYPE_MESSAGE = 10 

615 MAX_CPPTYPE = 10 

616 

617 _PYTHON_TO_CPP_PROTO_TYPE_MAP = { 

618 TYPE_DOUBLE: CPPTYPE_DOUBLE, 

619 TYPE_FLOAT: CPPTYPE_FLOAT, 

620 TYPE_ENUM: CPPTYPE_ENUM, 

621 TYPE_INT64: CPPTYPE_INT64, 

622 TYPE_SINT64: CPPTYPE_INT64, 

623 TYPE_SFIXED64: CPPTYPE_INT64, 

624 TYPE_UINT64: CPPTYPE_UINT64, 

625 TYPE_FIXED64: CPPTYPE_UINT64, 

626 TYPE_INT32: CPPTYPE_INT32, 

627 TYPE_SFIXED32: CPPTYPE_INT32, 

628 TYPE_SINT32: CPPTYPE_INT32, 

629 TYPE_UINT32: CPPTYPE_UINT32, 

630 TYPE_FIXED32: CPPTYPE_UINT32, 

631 TYPE_BYTES: CPPTYPE_STRING, 

632 TYPE_STRING: CPPTYPE_STRING, 

633 TYPE_BOOL: CPPTYPE_BOOL, 

634 TYPE_MESSAGE: CPPTYPE_MESSAGE, 

635 TYPE_GROUP: CPPTYPE_MESSAGE, 

636 } 

637 

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

639 # descriptor.h. 

640 # 

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

642 LABEL_OPTIONAL = 1 

643 LABEL_REQUIRED = 2 

644 LABEL_REPEATED = 3 

645 MAX_LABEL = 3 

646 

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

648 # and kLastReservedNumber in descriptor.h 

649 MAX_FIELD_NUMBER = (1 << 29) - 1 

650 FIRST_RESERVED_FIELD_NUMBER = 19000 

651 LAST_RESERVED_FIELD_NUMBER = 19999 

652 

653 if _USE_C_DESCRIPTORS: 

654 _C_DESCRIPTOR_CLASS = _message.FieldDescriptor 

655 

656 def __new__( 

657 cls, 

658 name, 

659 full_name, 

660 index, 

661 number, 

662 type, 

663 cpp_type, 

664 label, 

665 default_value, 

666 message_type, 

667 enum_type, 

668 containing_type, 

669 is_extension, 

670 extension_scope, 

671 options=None, 

672 serialized_options=None, 

673 has_default_value=True, 

674 containing_oneof=None, 

675 json_name=None, 

676 file=None, 

677 create_key=None, 

678 ): # pylint: disable=redefined-builtin 

679 _message.Message._CheckCalledFromGeneratedFile() 

680 if is_extension: 

681 return _message.default_pool.FindExtensionByName(full_name) 

682 else: 

683 return _message.default_pool.FindFieldByName(full_name) 

684 

685 def __init__( 

686 self, 

687 name, 

688 full_name, 

689 index, 

690 number, 

691 type, 

692 cpp_type, 

693 label, 

694 default_value, 

695 message_type, 

696 enum_type, 

697 containing_type, 

698 is_extension, 

699 extension_scope, 

700 options=None, 

701 serialized_options=None, 

702 has_default_value=True, 

703 containing_oneof=None, 

704 json_name=None, 

705 file=None, 

706 create_key=None, 

707 ): # pylint: disable=redefined-builtin 

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

709 

710 attributes above. 

711 

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

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

714 Likewise for extension_scope. 

715 """ 

716 if create_key is not _internal_create_key: 

717 _Deprecated('create function FieldDescriptor()') 

718 

719 super(FieldDescriptor, self).__init__( 

720 file, options, serialized_options, 'FieldOptions' 

721 ) 

722 self.name = name 

723 self.full_name = full_name 

724 self._camelcase_name = None 

725 if json_name is None: 

726 self.json_name = _ToJsonName(name) 

727 else: 

728 self.json_name = json_name 

729 self.index = index 

730 self.number = number 

731 self._type = type 

732 self.cpp_type = cpp_type 

733 self._label = label 

734 self.has_default_value = has_default_value 

735 self.default_value = default_value 

736 self.containing_type = containing_type 

737 self.message_type = message_type 

738 self.enum_type = enum_type 

739 self.is_extension = is_extension 

740 self.extension_scope = extension_scope 

741 self.containing_oneof = containing_oneof 

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

743 self._cdescriptor = None 

744 else: 

745 if is_extension: 

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

747 else: 

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

749 

750 @property 

751 def _parent(self): 

752 if self.containing_oneof: 

753 return self.containing_oneof 

754 if self.is_extension: 

755 return self.extension_scope or self.file 

756 return self.containing_type 

757 

758 def _InferLegacyFeatures(self, edition, options, features): 

759 # pylint: disable=g-import-not-at-top 

760 from google.protobuf import descriptor_pb2 

761 

762 if edition >= descriptor_pb2.Edition.EDITION_2023: 

763 return 

764 

765 if self._label == FieldDescriptor.LABEL_REQUIRED: 

766 features.field_presence = ( 

767 descriptor_pb2.FeatureSet.FieldPresence.LEGACY_REQUIRED 

768 ) 

769 

770 if self._type == FieldDescriptor.TYPE_GROUP: 

771 features.message_encoding = ( 

772 descriptor_pb2.FeatureSet.MessageEncoding.DELIMITED 

773 ) 

774 

775 if options.HasField('packed'): 

776 features.repeated_field_encoding = ( 

777 descriptor_pb2.FeatureSet.RepeatedFieldEncoding.PACKED 

778 if options.packed 

779 else descriptor_pb2.FeatureSet.RepeatedFieldEncoding.EXPANDED 

780 ) 

781 

782 @property 

783 def type(self): 

784 if ( 

785 self._GetFeatures().message_encoding 

786 == _FEATURESET_MESSAGE_ENCODING_DELIMITED 

787 and self.message_type 

788 and not self.message_type.GetOptions().map_entry 

789 and not self.containing_type.GetOptions().map_entry 

790 ): 

791 return FieldDescriptor.TYPE_GROUP 

792 return self._type 

793 

794 @type.setter 

795 def type(self, val): 

796 self._type = val 

797 

798 @property 

799 def is_required(self): 

800 """Returns if the field is required.""" 

801 return ( 

802 self._GetFeatures().field_presence 

803 == _FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED 

804 ) 

805 

806 @property 

807 def is_repeated(self): 

808 """Returns if the field is repeated.""" 

809 return self._label == FieldDescriptor.LABEL_REPEATED 

810 

811 @property 

812 def camelcase_name(self): 

813 """Camelcase name of this field. 

814 

815 Returns: 

816 str: the name in CamelCase. 

817 """ 

818 if self._camelcase_name is None: 

819 self._camelcase_name = _ToCamelCase(self.name) 

820 return self._camelcase_name 

821 

822 @property 

823 def has_presence(self): 

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

825 

826 Raises: 

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

828 """ 

829 if self.is_repeated: 

830 return False 

831 if ( 

832 self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE 

833 or self.is_extension 

834 or self.containing_oneof 

835 ): 

836 return True 

837 

838 return ( 

839 self._GetFeatures().field_presence 

840 != _FEATURESET_FIELD_PRESENCE_IMPLICIT 

841 ) 

842 

843 @property 

844 def is_packed(self): 

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

846 if not self.is_repeated: 

847 return False 

848 field_type = self.type 

849 if ( 

850 field_type == FieldDescriptor.TYPE_STRING 

851 or field_type == FieldDescriptor.TYPE_GROUP 

852 or field_type == FieldDescriptor.TYPE_MESSAGE 

853 or field_type == FieldDescriptor.TYPE_BYTES 

854 ): 

855 return False 

856 

857 return ( 

858 self._GetFeatures().repeated_field_encoding 

859 == _FEATURESET_REPEATED_FIELD_ENCODING_PACKED 

860 ) 

861 

862 @staticmethod 

863 def ProtoTypeToCppProtoType(proto_type): 

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

865 

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

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

868 translate from one to another. 

869 

870 Args: 

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

872 

873 Returns: 

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

875 Raises: 

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

877 """ 

878 try: 

879 return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] 

880 except KeyError: 

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

882 

883 

884class EnumDescriptor(_NestedDescriptorBase): 

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

886 

887 Attributes: 

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

889 full_name (str): Full name of the type, including package name and any 

890 enclosing type(s). 

891 values (list[EnumValueDescriptor]): List of the values in this enum. 

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

893 indexed by the "name" field of each EnumValueDescriptor. 

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

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

896 containing_type (Descriptor): Descriptor of the immediate containing type of 

897 this enum, or None if this is an enum defined at the top level in a .proto 

898 file. Set by Descriptor's constructor if we're passed into one. 

899 file (FileDescriptor): Reference to file descriptor. 

900 options (descriptor_pb2.EnumOptions): Enum options message or None to use 

901 default enum options. 

902 """ 

903 

904 if _USE_C_DESCRIPTORS: 

905 _C_DESCRIPTOR_CLASS = _message.EnumDescriptor 

906 

907 def __new__( 

908 cls, 

909 name, 

910 full_name, 

911 filename, 

912 values, 

913 containing_type=None, 

914 options=None, 

915 serialized_options=None, 

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

917 serialized_start=None, 

918 serialized_end=None, 

919 create_key=None, 

920 ): 

921 _message.Message._CheckCalledFromGeneratedFile() 

922 return _message.default_pool.FindEnumTypeByName(full_name) 

923 

924 def __init__( 

925 self, 

926 name, 

927 full_name, 

928 filename, 

929 values, 

930 containing_type=None, 

931 options=None, 

932 serialized_options=None, 

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

934 serialized_start=None, 

935 serialized_end=None, 

936 create_key=None, 

937 ): 

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

939 

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

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

942 """ 

943 if create_key is not _internal_create_key: 

944 _Deprecated('create function EnumDescriptor()') 

945 

946 super(EnumDescriptor, self).__init__( 

947 options, 

948 'EnumOptions', 

949 name, 

950 full_name, 

951 file, 

952 containing_type, 

953 serialized_start=serialized_start, 

954 serialized_end=serialized_end, 

955 serialized_options=serialized_options, 

956 ) 

957 

958 self.values = values 

959 for value in self.values: 

960 value.file = file 

961 value.type = self 

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

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

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

965 

966 @property 

967 def _parent(self): 

968 return self.containing_type or self.file 

969 

970 @property 

971 def is_closed(self): 

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

973 

974 This means that it: 

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

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

977 fields. 

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

979 

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

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

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

983 writing, we know that: 

984 

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

986 - UPB and UPB-based Python do not. 

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

988 

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

990 runtime's enum handling quirks. 

991 """ 

992 return self._GetFeatures().enum_type == _FEATURESET_ENUM_TYPE_CLOSED 

993 

994 def CopyToProto(self, proto): 

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

996 

997 Args: 

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

999 """ 

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

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

1002 

1003 

1004class EnumValueDescriptor(DescriptorBase): 

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

1006 

1007 Attributes: 

1008 name (str): Name of this value. 

1009 index (int): Dense, 0-indexed index giving the order that this value appears 

1010 textually within its enum in the .proto file. 

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

1012 type (EnumDescriptor): :class:`EnumDescriptor` to which this value belongs. 

1013 Set by :class:`EnumDescriptor`'s constructor if we're passed into one. 

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

1015 None to use default enum value options options. 

1016 """ 

1017 

1018 if _USE_C_DESCRIPTORS: 

1019 _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor 

1020 

1021 def __new__( 

1022 cls, 

1023 name, 

1024 index, 

1025 number, 

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

1027 options=None, 

1028 serialized_options=None, 

1029 create_key=None, 

1030 ): 

1031 _message.Message._CheckCalledFromGeneratedFile() 

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

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

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

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

1036 return None 

1037 

1038 def __init__( 

1039 self, 

1040 name, 

1041 index, 

1042 number, 

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

1044 options=None, 

1045 serialized_options=None, 

1046 create_key=None, 

1047 ): 

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

1049 if create_key is not _internal_create_key: 

1050 _Deprecated('create function EnumValueDescriptor()') 

1051 

1052 super(EnumValueDescriptor, self).__init__( 

1053 type.file if type else None, 

1054 options, 

1055 serialized_options, 

1056 'EnumValueOptions', 

1057 ) 

1058 self.name = name 

1059 self.index = index 

1060 self.number = number 

1061 self.type = type 

1062 

1063 @property 

1064 def _parent(self): 

1065 return self.type 

1066 

1067 

1068class OneofDescriptor(DescriptorBase): 

1069 """Descriptor for a oneof field. 

1070 

1071 Attributes: 

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

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

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

1075 containing type. 

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

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

1078 if we're passed into one. 

1079 fields (list[FieldDescriptor]): The list of field descriptors this oneof can 

1080 contain. 

1081 """ 

1082 

1083 if _USE_C_DESCRIPTORS: 

1084 _C_DESCRIPTOR_CLASS = _message.OneofDescriptor 

1085 

1086 def __new__( 

1087 cls, 

1088 name, 

1089 full_name, 

1090 index, 

1091 containing_type, 

1092 fields, 

1093 options=None, 

1094 serialized_options=None, 

1095 create_key=None, 

1096 ): 

1097 _message.Message._CheckCalledFromGeneratedFile() 

1098 return _message.default_pool.FindOneofByName(full_name) 

1099 

1100 def __init__( 

1101 self, 

1102 name, 

1103 full_name, 

1104 index, 

1105 containing_type, 

1106 fields, 

1107 options=None, 

1108 serialized_options=None, 

1109 create_key=None, 

1110 ): 

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

1112 if create_key is not _internal_create_key: 

1113 _Deprecated('create function OneofDescriptor()') 

1114 

1115 super(OneofDescriptor, self).__init__( 

1116 containing_type.file if containing_type else None, 

1117 options, 

1118 serialized_options, 

1119 'OneofOptions', 

1120 ) 

1121 self.name = name 

1122 self.full_name = full_name 

1123 self.index = index 

1124 self.containing_type = containing_type 

1125 self.fields = fields 

1126 

1127 @property 

1128 def _parent(self): 

1129 return self.containing_type 

1130 

1131 

1132class ServiceDescriptor(_NestedDescriptorBase): 

1133 """Descriptor for a service. 

1134 

1135 Attributes: 

1136 name (str): Name of the service. 

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

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

1139 appears within the .proto file. 

1140 methods (list[MethodDescriptor]): List of methods provided by this service. 

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

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

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

1144 options (descriptor_pb2.ServiceOptions): Service options message or None to 

1145 use default service options. 

1146 file (FileDescriptor): Reference to file info. 

1147 """ 

1148 

1149 if _USE_C_DESCRIPTORS: 

1150 _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor 

1151 

1152 def __new__( 

1153 cls, 

1154 name=None, 

1155 full_name=None, 

1156 index=None, 

1157 methods=None, 

1158 options=None, 

1159 serialized_options=None, 

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

1161 serialized_start=None, 

1162 serialized_end=None, 

1163 create_key=None, 

1164 ): 

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

1166 return _message.default_pool.FindServiceByName(full_name) 

1167 

1168 def __init__( 

1169 self, 

1170 name, 

1171 full_name, 

1172 index, 

1173 methods, 

1174 options=None, 

1175 serialized_options=None, 

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

1177 serialized_start=None, 

1178 serialized_end=None, 

1179 create_key=None, 

1180 ): 

1181 if create_key is not _internal_create_key: 

1182 _Deprecated('create function ServiceDescriptor()') 

1183 

1184 super(ServiceDescriptor, self).__init__( 

1185 options, 

1186 'ServiceOptions', 

1187 name, 

1188 full_name, 

1189 file, 

1190 None, 

1191 serialized_start=serialized_start, 

1192 serialized_end=serialized_end, 

1193 serialized_options=serialized_options, 

1194 ) 

1195 self.index = index 

1196 self.methods = methods 

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

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

1199 for method in self.methods: 

1200 method.file = self.file 

1201 method.containing_service = self 

1202 

1203 @property 

1204 def _parent(self): 

1205 return self.file 

1206 

1207 def FindMethodByName(self, name): 

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

1209 

1210 Args: 

1211 name (str): Name of the method. 

1212 

1213 Returns: 

1214 MethodDescriptor: The descriptor for the requested method. 

1215 

1216 Raises: 

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

1218 """ 

1219 return self.methods_by_name[name] 

1220 

1221 def CopyToProto(self, proto): 

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

1223 

1224 Args: 

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

1226 """ 

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

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

1229 

1230 

1231class MethodDescriptor(DescriptorBase): 

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

1233 

1234 Attributes: 

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

1236 full_name (str): Full name of method. 

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

1238 containing_service (ServiceDescriptor): The service that contains this 

1239 method. 

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

1241 accepts. 

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

1243 returns. 

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

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

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

1247 None to use default method options. 

1248 """ 

1249 

1250 if _USE_C_DESCRIPTORS: 

1251 _C_DESCRIPTOR_CLASS = _message.MethodDescriptor 

1252 

1253 def __new__( 

1254 cls, 

1255 name, 

1256 full_name, 

1257 index, 

1258 containing_service, 

1259 input_type, 

1260 output_type, 

1261 client_streaming=False, 

1262 server_streaming=False, 

1263 options=None, 

1264 serialized_options=None, 

1265 create_key=None, 

1266 ): 

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

1268 return _message.default_pool.FindMethodByName(full_name) 

1269 

1270 def __init__( 

1271 self, 

1272 name, 

1273 full_name, 

1274 index, 

1275 containing_service, 

1276 input_type, 

1277 output_type, 

1278 client_streaming=False, 

1279 server_streaming=False, 

1280 options=None, 

1281 serialized_options=None, 

1282 create_key=None, 

1283 ): 

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

1285 

1286 attributes above. 

1287 

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

1289 """ 

1290 if create_key is not _internal_create_key: 

1291 _Deprecated('create function MethodDescriptor()') 

1292 

1293 super(MethodDescriptor, self).__init__( 

1294 containing_service.file if containing_service else None, 

1295 options, 

1296 serialized_options, 

1297 'MethodOptions', 

1298 ) 

1299 self.name = name 

1300 self.full_name = full_name 

1301 self.index = index 

1302 self.containing_service = containing_service 

1303 self.input_type = input_type 

1304 self.output_type = output_type 

1305 self.client_streaming = client_streaming 

1306 self.server_streaming = server_streaming 

1307 

1308 @property 

1309 def _parent(self): 

1310 return self.containing_service 

1311 

1312 def CopyToProto(self, proto): 

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

1314 

1315 Args: 

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

1317 

1318 Raises: 

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

1320 arguments. 

1321 """ 

1322 if self.containing_service is not None: 

1323 from google.protobuf import descriptor_pb2 

1324 

1325 service_proto = descriptor_pb2.ServiceDescriptorProto() 

1326 self.containing_service.CopyToProto(service_proto) 

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

1328 else: 

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

1330 

1331 

1332class FileDescriptor(DescriptorBase): 

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

1334 

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

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

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

1338 proto code. 

1339 

1340 Attributes: 

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

1342 package (str): Name of the package 

1343 edition (Edition): Enum value indicating edition of the file 

1344 serialized_pb (bytes): Byte string of serialized 

1345 :class:`descriptor_pb2.FileDescriptorProto`. 

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

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

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

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

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

1351 their :class:`Descriptor`. 

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

1353 their :class:`EnumDescriptor`. 

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

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

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

1357 names to their :class:`ServiceDescriptor`. 

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

1359 to the constructor, the global default pool is used. 

1360 """ 

1361 

1362 if _USE_C_DESCRIPTORS: 

1363 _C_DESCRIPTOR_CLASS = _message.FileDescriptor 

1364 

1365 def __new__( 

1366 cls, 

1367 name, 

1368 package, 

1369 options=None, 

1370 serialized_options=None, 

1371 serialized_pb=None, 

1372 dependencies=None, 

1373 public_dependencies=None, 

1374 syntax=None, 

1375 edition=None, 

1376 pool=None, 

1377 create_key=None, 

1378 ): 

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

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

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

1382 if serialized_pb: 

1383 return _message.default_pool.AddSerializedFile(serialized_pb) 

1384 else: 

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

1386 

1387 def __init__( 

1388 self, 

1389 name, 

1390 package, 

1391 options=None, 

1392 serialized_options=None, 

1393 serialized_pb=None, 

1394 dependencies=None, 

1395 public_dependencies=None, 

1396 syntax=None, 

1397 edition=None, 

1398 pool=None, 

1399 create_key=None, 

1400 ): 

1401 """Constructor.""" 

1402 if create_key is not _internal_create_key: 

1403 _Deprecated('create function FileDescriptor()') 

1404 

1405 super(FileDescriptor, self).__init__( 

1406 self, options, serialized_options, 'FileOptions' 

1407 ) 

1408 

1409 if edition and edition != 'EDITION_UNKNOWN': 

1410 self._edition = edition 

1411 elif syntax == 'proto3': 

1412 self._edition = 'EDITION_PROTO3' 

1413 else: 

1414 self._edition = 'EDITION_PROTO2' 

1415 

1416 if pool is None: 

1417 from google.protobuf import descriptor_pool 

1418 

1419 pool = descriptor_pool.Default() 

1420 self.pool = pool 

1421 self.message_types_by_name = {} 

1422 self.name = name 

1423 self.package = package 

1424 self.serialized_pb = serialized_pb 

1425 

1426 self.enum_types_by_name = {} 

1427 self.extensions_by_name = {} 

1428 self.services_by_name = {} 

1429 self.dependencies = dependencies or [] 

1430 self.public_dependencies = public_dependencies or [] 

1431 

1432 def CopyToProto(self, proto): 

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

1434 

1435 Args: 

1436 proto: An empty descriptor_pb2.FileDescriptorProto. 

1437 """ 

1438 proto.ParseFromString(self.serialized_pb) 

1439 

1440 @property 

1441 def _parent(self): 

1442 return None 

1443 

1444 

1445def _ParseOptions(message, string): 

1446 """Parses serialized options. 

1447 

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

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

1450 """ 

1451 message.ParseFromString(string) 

1452 return message 

1453 

1454 

1455def _ToCamelCase(name): 

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

1457 capitalize_next = False 

1458 result = [] 

1459 

1460 for c in name: 

1461 if c == '_': 

1462 if result: 

1463 capitalize_next = True 

1464 elif capitalize_next: 

1465 result.append(c.upper()) 

1466 capitalize_next = False 

1467 else: 

1468 result += c 

1469 

1470 # Lower-case the first letter. 

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

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

1473 return ''.join(result) 

1474 

1475 

1476def _OptionsOrNone(descriptor_proto): 

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

1478 if descriptor_proto.HasField('options'): 

1479 return descriptor_proto.options 

1480 else: 

1481 return None 

1482 

1483 

1484def _ToJsonName(name): 

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

1486 capitalize_next = False 

1487 result = [] 

1488 

1489 for c in name: 

1490 if c == '_': 

1491 capitalize_next = True 

1492 elif capitalize_next: 

1493 result.append(c.upper()) 

1494 capitalize_next = False 

1495 else: 

1496 result += c 

1497 

1498 return ''.join(result) 

1499 

1500 

1501def MakeDescriptor( 

1502 desc_proto, 

1503 package='', 

1504 build_file_if_cpp=True, 

1505 syntax=None, 

1506 edition=None, 

1507 file_desc=None, 

1508): 

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

1510 

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

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

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

1514 

1515 Args: 

1516 desc_proto: The descriptor_pb2.DescriptorProto protobuf message. 

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

1518 build_file_if_cpp: Update the C++ descriptor pool if api matches. Set to 

1519 False on recursion, so no duplicates are created. 

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

1521 proto3 field presence semantics. 

1522 edition: The edition that should be used if syntax is "edition". 

1523 file_desc: A FileDescriptor to place this descriptor into. 

1524 

1525 Returns: 

1526 A Descriptor for protobuf messages. 

1527 """ 

1528 # pylint: disable=g-import-not-at-top 

1529 from google.protobuf import descriptor_pb2 

1530 

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

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

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

1534 # name is actually set to. 

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

1536 

1537 if package: 

1538 file_name = os.path.join(package.replace('.', '/'), proto_name + '.proto') 

1539 else: 

1540 file_name = proto_name + '.proto' 

1541 

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

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

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

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

1546 # it into the pool. 

1547 file_descriptor_proto = descriptor_pb2.FileDescriptorProto() 

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

1549 

1550 if package: 

1551 file_descriptor_proto.package = package 

1552 file_descriptor_proto.name = file_name 

1553 

1554 _message.default_pool.Add(file_descriptor_proto) 

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

1556 

1557 if _USE_C_DESCRIPTORS: 

1558 return result.message_types_by_name[desc_proto.name] 

1559 

1560 if file_desc is None: 

1561 file_desc = FileDescriptor( 

1562 pool=None, 

1563 name=file_name, 

1564 package=package, 

1565 syntax=syntax, 

1566 edition=edition, 

1567 options=None, 

1568 serialized_pb='', 

1569 dependencies=[], 

1570 public_dependencies=[], 

1571 create_key=_internal_create_key, 

1572 ) 

1573 full_message_name = [desc_proto.name] 

1574 if package: 

1575 full_message_name.insert(0, package) 

1576 

1577 # Create Descriptors for enum types 

1578 enum_types = {} 

1579 for enum_proto in desc_proto.enum_type: 

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

1581 enum_desc = EnumDescriptor( 

1582 enum_proto.name, 

1583 full_name, 

1584 None, 

1585 [ 

1586 EnumValueDescriptor( 

1587 enum_val.name, 

1588 ii, 

1589 enum_val.number, 

1590 create_key=_internal_create_key, 

1591 ) 

1592 for ii, enum_val in enumerate(enum_proto.value) 

1593 ], 

1594 file=file_desc, 

1595 create_key=_internal_create_key, 

1596 ) 

1597 enum_types[full_name] = enum_desc 

1598 

1599 # Create Descriptors for nested types 

1600 nested_types = {} 

1601 for nested_proto in desc_proto.nested_type: 

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

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

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

1605 nested_desc = MakeDescriptor( 

1606 nested_proto, 

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

1608 build_file_if_cpp=False, 

1609 syntax=syntax, 

1610 edition=edition, 

1611 file_desc=file_desc, 

1612 ) 

1613 nested_types[full_name] = nested_desc 

1614 

1615 fields = [] 

1616 for field_proto in desc_proto.field: 

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

1618 enum_desc = None 

1619 nested_desc = None 

1620 if field_proto.json_name: 

1621 json_name = field_proto.json_name 

1622 else: 

1623 json_name = None 

1624 if field_proto.HasField('type_name'): 

1625 type_name = field_proto.type_name 

1626 full_type_name = '.'.join( 

1627 full_message_name + [type_name[type_name.rfind('.') + 1 :]] 

1628 ) 

1629 if full_type_name in nested_types: 

1630 nested_desc = nested_types[full_type_name] 

1631 elif full_type_name in enum_types: 

1632 enum_desc = enum_types[full_type_name] 

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

1634 field = FieldDescriptor( 

1635 field_proto.name, 

1636 full_name, 

1637 field_proto.number - 1, 

1638 field_proto.number, 

1639 field_proto.type, 

1640 FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), 

1641 field_proto.label, 

1642 None, 

1643 nested_desc, 

1644 enum_desc, 

1645 None, 

1646 False, 

1647 None, 

1648 options=_OptionsOrNone(field_proto), 

1649 has_default_value=False, 

1650 json_name=json_name, 

1651 file=file_desc, 

1652 create_key=_internal_create_key, 

1653 ) 

1654 fields.append(field) 

1655 

1656 desc_name = '.'.join(full_message_name) 

1657 return Descriptor( 

1658 desc_proto.name, 

1659 desc_name, 

1660 None, 

1661 None, 

1662 fields, 

1663 list(nested_types.values()), 

1664 list(enum_types.values()), 

1665 [], 

1666 options=_OptionsOrNone(desc_proto), 

1667 file=file_desc, 

1668 create_key=_internal_create_key, 

1669 )