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

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

532 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 

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

9 

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

11""" 

12 

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

14 

15import abc 

16import binascii 

17import os 

18import threading 

19import warnings 

20 

21from google.protobuf.internal import api_implementation 

22 

23_USE_C_DESCRIPTORS = False 

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

25 # pylint: disable=protected-access 

26 _message = api_implementation._c_module 

27 # TODO: Remove this import after fix api_implementation 

28 if _message is None: 

29 from google.protobuf.pyext import _message 

30 _USE_C_DESCRIPTORS = True 

31 

32 

33class Error(Exception): 

34 """Base error for this module.""" 

35 

36 

37class TypeTransformationError(Error): 

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

39 

40 

41if _USE_C_DESCRIPTORS: 

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

43 # isinstance(my_descriptor, FieldDescriptor) 

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

45 # type written in C++. 

46 class DescriptorMetaclass(type): 

47 

48 def __instancecheck__(cls, obj): 

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

50 return True 

51 if isinstance(obj, cls._C_DESCRIPTOR_CLASS): 

52 return True 

53 return False 

54 

55else: 

56 # The standard metaclass; nothing changes. 

57 DescriptorMetaclass = abc.ABCMeta 

58 

59 

60class _Lock(object): 

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

62 

63 def __new__(cls): 

64 self = object.__new__(cls) 

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

66 return self 

67 

68 def __enter__(self): 

69 self._lock.acquire() 

70 

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

72 self._lock.release() 

73 

74 

75_lock = threading.Lock() 

76 

77 

78def _Deprecated( 

79 name, 

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

81): 

82 if _Deprecated.count > 0: 

83 _Deprecated.count -= 1 

84 warnings.warn( 

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

86 category=DeprecationWarning, 

87 stacklevel=3, 

88 ) 

89 

90 

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

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

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

94_FEATURESET_MESSAGE_ENCODING_DELIMITED = 2 

95_FEATURESET_FIELD_PRESENCE_IMPLICIT = 2 

96_FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED = 3 

97_FEATURESET_REPEATED_FIELD_ENCODING_PACKED = 1 

98_FEATURESET_ENUM_TYPE_CLOSED = 2 

99 

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

101# users to notice and do not cause timeout. 

102_Deprecated.count = 100 

103 

104 

105_internal_create_key = object() 

106 

107 

108class DescriptorBase(metaclass=DescriptorMetaclass): 

109 """Descriptors base class. 

110 

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

112 related functionality. 

113 

114 Attributes: 

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

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

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

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

119 some bootstrapping issues. 

120 file (FileDescriptor): Reference to file info. 

121 """ 

122 

123 if _USE_C_DESCRIPTORS: 

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

125 # subclasses" of this descriptor class. 

126 _C_DESCRIPTOR_CLASS = () 

127 

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

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

130 

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

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

133 """ 

134 self._features = None 

135 self.file = file 

136 self._original_options = options 

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

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

139 # _loaded_options breaking backwards compatibility. 

140 self._options = self._loaded_options = None 

141 self._options_class_name = options_class_name 

142 self._serialized_options = serialized_options 

143 

144 # Does this descriptor have non-default options? 

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

146 self._serialized_options is not None 

147 ) 

148 

149 @property 

150 @abc.abstractmethod 

151 def _parent(self): 

152 pass 

153 

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

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

156 

157 Args: 

158 edition: The edition to infer features for. 

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

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

161 """ 

162 pass 

163 

164 def _GetFeatures(self): 

165 if not self._features: 

166 self._LazyLoadOptions() 

167 return self._features 

168 

169 def _ResolveFeatures(self, edition, raw_options): 

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

171 

172 Args: 

173 edition: The edition to use for feature defaults. 

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

175 

176 Returns: 

177 A fully resolved feature set for making runtime decisions. 

178 """ 

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

180 from google.protobuf import descriptor_pb2 

181 

182 if self._parent: 

183 features = descriptor_pb2.FeatureSet() 

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

185 else: 

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

187 unresolved = descriptor_pb2.FeatureSet() 

188 unresolved.CopyFrom(raw_options.features) 

189 self._InferLegacyFeatures(edition, raw_options, unresolved) 

190 features.MergeFrom(unresolved) 

191 

192 # Use the feature cache to reduce memory bloat. 

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

194 

195 def _LazyLoadOptions(self): 

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

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

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

199 return 

200 

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

202 from google.protobuf import descriptor_pb2 

203 

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

205 raise RuntimeError( 

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

207 ) 

208 options_class = getattr(descriptor_pb2, self._options_class_name) 

209 features = None 

210 edition = self.file._edition 

211 

212 if not self.has_options: 

213 if not self._features: 

214 features = self._ResolveFeatures( 

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

216 ) 

217 with _lock: 

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

219 if not self._features: 

220 self._features = features 

221 else: 

222 if not self._serialized_options: 

223 options = self._original_options 

224 else: 

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

226 

227 if not self._features: 

228 features = self._ResolveFeatures( 

229 descriptor_pb2.Edition.Value(edition), options 

230 ) 

231 with _lock: 

232 self._options = self._loaded_options = options 

233 if not self._features: 

234 self._features = features 

235 if options.HasField('features'): 

236 options.ClearField('features') 

237 if not options.SerializeToString(): 

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

239 self.has_options = False 

240 

241 def GetOptions(self): 

242 """Retrieves descriptor options. 

243 

244 Returns: 

245 The options set on this descriptor. 

246 """ 

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

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

249 self._LazyLoadOptions() 

250 return self._options 

251 

252 

253class _NestedDescriptorBase(DescriptorBase): 

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

255 

256 def __init__( 

257 self, 

258 options, 

259 options_class_name, 

260 name, 

261 full_name, 

262 file, 

263 containing_type, 

264 serialized_start=None, 

265 serialized_end=None, 

266 serialized_options=None, 

267 ): 

268 """Constructor. 

269 

270 Args: 

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

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

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

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

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

276 types. 

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

278 descriptor as parent, otherwise None. 

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

280 file.serialized_pb that describes this descriptor. 

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

282 file.serialized_pb that describes this descriptor. 

283 serialized_options: Protocol message serialized options or None. 

284 """ 

285 super(_NestedDescriptorBase, self).__init__( 

286 file, options, serialized_options, options_class_name 

287 ) 

288 

289 self.name = name 

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

291 # memory? 

292 self.full_name = full_name 

293 self.containing_type = containing_type 

294 

295 self._serialized_start = serialized_start 

296 self._serialized_end = serialized_end 

297 

298 def CopyToProto(self, proto): 

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

300 

301 Args: 

302 proto: An empty proto instance from descriptor_pb2. 

303 

304 Raises: 

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

306 arguments. 

307 """ 

308 if ( 

309 self.file is not None 

310 and self._serialized_start is not None 

311 and self._serialized_end is not None 

312 ): 

313 proto.ParseFromString( 

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

315 ) 

316 else: 

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

318 

319 

320class Descriptor(_NestedDescriptorBase): 

321 """Descriptor for a protocol message type. 

322 

323 Attributes: 

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

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

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

327 types. 

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

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

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

331 type. 

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

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

334 "number" attribute in each FieldDescriptor. 

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

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

337 :class:`FieldDescriptor`. 

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

339 message types nested within this one. 

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

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

342 Descriptor. 

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

344 all enums contained within this type. 

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

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

347 "name" attribute in each EnumDescriptor. 

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

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

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

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

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

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

354 FieldDescriptor. 

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

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

357 in this message. 

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

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

360 file (FileDescriptor): Reference to file descriptor. 

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

362 """ 

363 

364 if _USE_C_DESCRIPTORS: 

365 _C_DESCRIPTOR_CLASS = _message.Descriptor 

366 

367 def __new__( 

368 cls, 

369 name=None, 

370 full_name=None, 

371 filename=None, 

372 containing_type=None, 

373 fields=None, 

374 nested_types=None, 

375 enum_types=None, 

376 extensions=None, 

377 options=None, 

378 serialized_options=None, 

379 is_extendable=True, 

380 extension_ranges=None, 

381 oneofs=None, 

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

383 serialized_start=None, 

384 serialized_end=None, 

385 syntax=None, 

386 is_map_entry=False, 

387 create_key=None, 

388 ): 

389 _message.Message._CheckCalledFromGeneratedFile() 

390 return _message.default_pool.FindMessageTypeByName(full_name) 

391 

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

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

394 # name of the argument. 

395 def __init__( 

396 self, 

397 name, 

398 full_name, 

399 filename, 

400 containing_type, 

401 fields, 

402 nested_types, 

403 enum_types, 

404 extensions, 

405 options=None, 

406 serialized_options=None, 

407 is_extendable=True, 

408 extension_ranges=None, 

409 oneofs=None, 

410 file=None, 

411 serialized_start=None, 

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

413 syntax=None, 

414 is_map_entry=False, 

415 create_key=None, 

416 ): 

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

418 

419 of Descriptor fields above. 

420 

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

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

423 """ 

424 if create_key is not _internal_create_key: 

425 _Deprecated('create function Descriptor()') 

426 

427 super(Descriptor, self).__init__( 

428 options, 

429 'MessageOptions', 

430 name, 

431 full_name, 

432 file, 

433 containing_type, 

434 serialized_start=serialized_start, 

435 serialized_end=serialized_end, 

436 serialized_options=serialized_options, 

437 ) 

438 

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

440 # so that: 

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

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

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

444 self.fields = fields 

445 for field in self.fields: 

446 field.containing_type = self 

447 field.file = file 

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

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

450 self._fields_by_camelcase_name = None 

451 

452 self.nested_types = nested_types 

453 for nested_type in nested_types: 

454 nested_type.containing_type = self 

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

456 

457 self.enum_types = enum_types 

458 for enum_type in self.enum_types: 

459 enum_type.containing_type = self 

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

461 self.enum_values_by_name = dict( 

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

463 ) 

464 

465 self.extensions = extensions 

466 for extension in self.extensions: 

467 extension.extension_scope = self 

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

469 self.is_extendable = is_extendable 

470 self.extension_ranges = extension_ranges 

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

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

473 for oneof in self.oneofs: 

474 oneof.containing_type = self 

475 oneof.file = file 

476 self._is_map_entry = is_map_entry 

477 

478 @property 

479 def _parent(self): 

480 return self.containing_type or self.file 

481 

482 @property 

483 def fields_by_camelcase_name(self): 

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

485 

486 :attr:`FieldDescriptor.camelcase_name`. 

487 """ 

488 if self._fields_by_camelcase_name is None: 

489 self._fields_by_camelcase_name = dict( 

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

491 ) 

492 return self._fields_by_camelcase_name 

493 

494 def EnumValueName(self, enum, value): 

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

496 

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

498 

499 Args: 

500 enum: string name of the Enum. 

501 value: int, value of the enum. 

502 

503 Returns: 

504 string name of the enum value. 

505 

506 Raises: 

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

508 value for the enum. 

509 """ 

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

511 

512 def CopyToProto(self, proto): 

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

514 

515 Args: 

516 proto: An empty descriptor_pb2.DescriptorProto. 

517 """ 

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

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

520 

521 

522# TODO: We should have aggressive checking here, 

523# for example: 

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

525# to specify a default value. 

526# * [Other examples here as needed]. 

527# 

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

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

530# prevent clients from setting the attributes). Having 

531# stronger invariants here in general will reduce the number 

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

533class FieldDescriptor(DescriptorBase): 

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

535 

536 Attributes: 

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

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

539 particularly relevant for extensions. 

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

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

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

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

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

545 represent this field. 

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

547 is optional, required, or repeated. 

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

549 otherwise false. 

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

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

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

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

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

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

556 descriptor of the EXTENDED message, not the descriptor of the message 

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

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

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

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

561 that enum. Otherwise, this is None. 

562 is_extension: True iff this describes an extension field. 

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

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

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

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

567 None to use default field options. 

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

569 union, contains its descriptor. Otherwise, None. 

570 file (FileDescriptor): Reference to file descriptor. 

571 """ 

572 

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

574 # descriptor.h. 

575 # 

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

577 TYPE_DOUBLE = 1 

578 TYPE_FLOAT = 2 

579 TYPE_INT64 = 3 

580 TYPE_UINT64 = 4 

581 TYPE_INT32 = 5 

582 TYPE_FIXED64 = 6 

583 TYPE_FIXED32 = 7 

584 TYPE_BOOL = 8 

585 TYPE_STRING = 9 

586 TYPE_GROUP = 10 

587 TYPE_MESSAGE = 11 

588 TYPE_BYTES = 12 

589 TYPE_UINT32 = 13 

590 TYPE_ENUM = 14 

591 TYPE_SFIXED32 = 15 

592 TYPE_SFIXED64 = 16 

593 TYPE_SINT32 = 17 

594 TYPE_SINT64 = 18 

595 MAX_TYPE = 18 

596 

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

598 # descriptor.h. 

599 # 

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

601 CPPTYPE_INT32 = 1 

602 CPPTYPE_INT64 = 2 

603 CPPTYPE_UINT32 = 3 

604 CPPTYPE_UINT64 = 4 

605 CPPTYPE_DOUBLE = 5 

606 CPPTYPE_FLOAT = 6 

607 CPPTYPE_BOOL = 7 

608 CPPTYPE_ENUM = 8 

609 CPPTYPE_STRING = 9 

610 CPPTYPE_MESSAGE = 10 

611 MAX_CPPTYPE = 10 

612 

613 _PYTHON_TO_CPP_PROTO_TYPE_MAP = { 

614 TYPE_DOUBLE: CPPTYPE_DOUBLE, 

615 TYPE_FLOAT: CPPTYPE_FLOAT, 

616 TYPE_ENUM: CPPTYPE_ENUM, 

617 TYPE_INT64: CPPTYPE_INT64, 

618 TYPE_SINT64: CPPTYPE_INT64, 

619 TYPE_SFIXED64: CPPTYPE_INT64, 

620 TYPE_UINT64: CPPTYPE_UINT64, 

621 TYPE_FIXED64: CPPTYPE_UINT64, 

622 TYPE_INT32: CPPTYPE_INT32, 

623 TYPE_SFIXED32: CPPTYPE_INT32, 

624 TYPE_SINT32: CPPTYPE_INT32, 

625 TYPE_UINT32: CPPTYPE_UINT32, 

626 TYPE_FIXED32: CPPTYPE_UINT32, 

627 TYPE_BYTES: CPPTYPE_STRING, 

628 TYPE_STRING: CPPTYPE_STRING, 

629 TYPE_BOOL: CPPTYPE_BOOL, 

630 TYPE_MESSAGE: CPPTYPE_MESSAGE, 

631 TYPE_GROUP: CPPTYPE_MESSAGE, 

632 } 

633 

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

635 # descriptor.h. 

636 # 

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

638 LABEL_OPTIONAL = 1 

639 LABEL_REQUIRED = 2 

640 LABEL_REPEATED = 3 

641 MAX_LABEL = 3 

642 

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

644 # and kLastReservedNumber in descriptor.h 

645 MAX_FIELD_NUMBER = (1 << 29) - 1 

646 FIRST_RESERVED_FIELD_NUMBER = 19000 

647 LAST_RESERVED_FIELD_NUMBER = 19999 

648 

649 if _USE_C_DESCRIPTORS: 

650 _C_DESCRIPTOR_CLASS = _message.FieldDescriptor 

651 

652 def __new__( 

653 cls, 

654 name, 

655 full_name, 

656 index, 

657 number, 

658 type, 

659 cpp_type, 

660 label, 

661 default_value, 

662 message_type, 

663 enum_type, 

664 containing_type, 

665 is_extension, 

666 extension_scope, 

667 options=None, 

668 serialized_options=None, 

669 has_default_value=True, 

670 containing_oneof=None, 

671 json_name=None, 

672 file=None, 

673 create_key=None, 

674 ): # pylint: disable=redefined-builtin 

675 _message.Message._CheckCalledFromGeneratedFile() 

676 if is_extension: 

677 return _message.default_pool.FindExtensionByName(full_name) 

678 else: 

679 return _message.default_pool.FindFieldByName(full_name) 

680 

681 def __init__( 

682 self, 

683 name, 

684 full_name, 

685 index, 

686 number, 

687 type, 

688 cpp_type, 

689 label, 

690 default_value, 

691 message_type, 

692 enum_type, 

693 containing_type, 

694 is_extension, 

695 extension_scope, 

696 options=None, 

697 serialized_options=None, 

698 has_default_value=True, 

699 containing_oneof=None, 

700 json_name=None, 

701 file=None, 

702 create_key=None, 

703 ): # pylint: disable=redefined-builtin 

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

705 

706 attributes above. 

707 

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

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

710 Likewise for extension_scope. 

711 """ 

712 if create_key is not _internal_create_key: 

713 _Deprecated('create function FieldDescriptor()') 

714 

715 super(FieldDescriptor, self).__init__( 

716 file, options, serialized_options, 'FieldOptions' 

717 ) 

718 self.name = name 

719 self.full_name = full_name 

720 self._camelcase_name = None 

721 if json_name is None: 

722 self.json_name = _ToJsonName(name) 

723 else: 

724 self.json_name = json_name 

725 self.index = index 

726 self.number = number 

727 self._type = type 

728 self.cpp_type = cpp_type 

729 self._label = label 

730 self.has_default_value = has_default_value 

731 self.default_value = default_value 

732 self.containing_type = containing_type 

733 self.message_type = message_type 

734 self.enum_type = enum_type 

735 self.is_extension = is_extension 

736 self.extension_scope = extension_scope 

737 self.containing_oneof = containing_oneof 

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

739 self._cdescriptor = None 

740 else: 

741 if is_extension: 

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

743 else: 

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

745 

746 @property 

747 def _parent(self): 

748 if self.containing_oneof: 

749 return self.containing_oneof 

750 if self.is_extension: 

751 return self.extension_scope or self.file 

752 return self.containing_type 

753 

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

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

756 from google.protobuf import descriptor_pb2 

757 

758 if edition >= descriptor_pb2.Edition.EDITION_2023: 

759 return 

760 

761 if self._label == FieldDescriptor.LABEL_REQUIRED: 

762 features.field_presence = ( 

763 descriptor_pb2.FeatureSet.FieldPresence.LEGACY_REQUIRED 

764 ) 

765 

766 if self._type == FieldDescriptor.TYPE_GROUP: 

767 features.message_encoding = ( 

768 descriptor_pb2.FeatureSet.MessageEncoding.DELIMITED 

769 ) 

770 

771 if options.HasField('packed'): 

772 features.repeated_field_encoding = ( 

773 descriptor_pb2.FeatureSet.RepeatedFieldEncoding.PACKED 

774 if options.packed 

775 else descriptor_pb2.FeatureSet.RepeatedFieldEncoding.EXPANDED 

776 ) 

777 

778 @property 

779 def type(self): 

780 if ( 

781 self._GetFeatures().message_encoding 

782 == _FEATURESET_MESSAGE_ENCODING_DELIMITED 

783 and self.message_type 

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

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

786 ): 

787 return FieldDescriptor.TYPE_GROUP 

788 return self._type 

789 

790 @type.setter 

791 def type(self, val): 

792 self._type = val 

793 

794 @property 

795 def is_required(self): 

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

797 return ( 

798 self._GetFeatures().field_presence 

799 == _FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED 

800 ) 

801 

802 @property 

803 def is_repeated(self): 

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

805 return self._label == FieldDescriptor.LABEL_REPEATED 

806 

807 @property 

808 def camelcase_name(self): 

809 """Camelcase name of this field. 

810 

811 Returns: 

812 str: the name in CamelCase. 

813 """ 

814 if self._camelcase_name is None: 

815 self._camelcase_name = _ToCamelCase(self.name) 

816 return self._camelcase_name 

817 

818 @property 

819 def has_presence(self): 

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

821 

822 Raises: 

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

824 """ 

825 if self.is_repeated: 

826 return False 

827 if ( 

828 self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE 

829 or self.is_extension 

830 or self.containing_oneof 

831 ): 

832 return True 

833 

834 return ( 

835 self._GetFeatures().field_presence 

836 != _FEATURESET_FIELD_PRESENCE_IMPLICIT 

837 ) 

838 

839 @property 

840 def is_packed(self): 

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

842 if not self.is_repeated: 

843 return False 

844 field_type = self.type 

845 if ( 

846 field_type == FieldDescriptor.TYPE_STRING 

847 or field_type == FieldDescriptor.TYPE_GROUP 

848 or field_type == FieldDescriptor.TYPE_MESSAGE 

849 or field_type == FieldDescriptor.TYPE_BYTES 

850 ): 

851 return False 

852 

853 return ( 

854 self._GetFeatures().repeated_field_encoding 

855 == _FEATURESET_REPEATED_FIELD_ENCODING_PACKED 

856 ) 

857 

858 @staticmethod 

859 def ProtoTypeToCppProtoType(proto_type): 

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

861 

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

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

864 translate from one to another. 

865 

866 Args: 

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

868 

869 Returns: 

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

871 Raises: 

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

873 """ 

874 try: 

875 return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] 

876 except KeyError: 

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

878 

879 

880class EnumDescriptor(_NestedDescriptorBase): 

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

882 

883 Attributes: 

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

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

886 enclosing type(s). 

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

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

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

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

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

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

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

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

895 file (FileDescriptor): Reference to file descriptor. 

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

897 default enum options. 

898 """ 

899 

900 if _USE_C_DESCRIPTORS: 

901 _C_DESCRIPTOR_CLASS = _message.EnumDescriptor 

902 

903 def __new__( 

904 cls, 

905 name, 

906 full_name, 

907 filename, 

908 values, 

909 containing_type=None, 

910 options=None, 

911 serialized_options=None, 

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

913 serialized_start=None, 

914 serialized_end=None, 

915 create_key=None, 

916 ): 

917 _message.Message._CheckCalledFromGeneratedFile() 

918 return _message.default_pool.FindEnumTypeByName(full_name) 

919 

920 def __init__( 

921 self, 

922 name, 

923 full_name, 

924 filename, 

925 values, 

926 containing_type=None, 

927 options=None, 

928 serialized_options=None, 

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

930 serialized_start=None, 

931 serialized_end=None, 

932 create_key=None, 

933 ): 

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

935 

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

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

938 """ 

939 if create_key is not _internal_create_key: 

940 _Deprecated('create function EnumDescriptor()') 

941 

942 super(EnumDescriptor, self).__init__( 

943 options, 

944 'EnumOptions', 

945 name, 

946 full_name, 

947 file, 

948 containing_type, 

949 serialized_start=serialized_start, 

950 serialized_end=serialized_end, 

951 serialized_options=serialized_options, 

952 ) 

953 

954 self.values = values 

955 for value in self.values: 

956 value.file = file 

957 value.type = self 

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

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

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

961 

962 @property 

963 def _parent(self): 

964 return self.containing_type or self.file 

965 

966 @property 

967 def is_closed(self): 

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

969 

970 This means that it: 

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

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

973 fields. 

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

975 

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

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

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

979 writing, we know that: 

980 

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

982 - UPB and UPB-based Python do not. 

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

984 

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

986 runtime's enum handling quirks. 

987 """ 

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

989 

990 def CopyToProto(self, proto): 

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

992 

993 Args: 

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

995 """ 

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

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

998 

999 

1000class EnumValueDescriptor(DescriptorBase): 

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

1002 

1003 Attributes: 

1004 name (str): Name of this value. 

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

1006 textually within its enum in the .proto file. 

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

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

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

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

1011 None to use default enum value options options. 

1012 """ 

1013 

1014 if _USE_C_DESCRIPTORS: 

1015 _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor 

1016 

1017 def __new__( 

1018 cls, 

1019 name, 

1020 index, 

1021 number, 

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

1023 options=None, 

1024 serialized_options=None, 

1025 create_key=None, 

1026 ): 

1027 _message.Message._CheckCalledFromGeneratedFile() 

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

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

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

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

1032 return None 

1033 

1034 def __init__( 

1035 self, 

1036 name, 

1037 index, 

1038 number, 

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

1040 options=None, 

1041 serialized_options=None, 

1042 create_key=None, 

1043 ): 

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

1045 if create_key is not _internal_create_key: 

1046 _Deprecated('create function EnumValueDescriptor()') 

1047 

1048 super(EnumValueDescriptor, self).__init__( 

1049 type.file if type else None, 

1050 options, 

1051 serialized_options, 

1052 'EnumValueOptions', 

1053 ) 

1054 self.name = name 

1055 self.index = index 

1056 self.number = number 

1057 self.type = type 

1058 

1059 @property 

1060 def _parent(self): 

1061 return self.type 

1062 

1063 

1064class OneofDescriptor(DescriptorBase): 

1065 """Descriptor for a oneof field. 

1066 

1067 Attributes: 

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

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

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

1071 containing type. 

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

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

1074 if we're passed into one. 

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

1076 contain. 

1077 """ 

1078 

1079 if _USE_C_DESCRIPTORS: 

1080 _C_DESCRIPTOR_CLASS = _message.OneofDescriptor 

1081 

1082 def __new__( 

1083 cls, 

1084 name, 

1085 full_name, 

1086 index, 

1087 containing_type, 

1088 fields, 

1089 options=None, 

1090 serialized_options=None, 

1091 create_key=None, 

1092 ): 

1093 _message.Message._CheckCalledFromGeneratedFile() 

1094 return _message.default_pool.FindOneofByName(full_name) 

1095 

1096 def __init__( 

1097 self, 

1098 name, 

1099 full_name, 

1100 index, 

1101 containing_type, 

1102 fields, 

1103 options=None, 

1104 serialized_options=None, 

1105 create_key=None, 

1106 ): 

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

1108 if create_key is not _internal_create_key: 

1109 _Deprecated('create function OneofDescriptor()') 

1110 

1111 super(OneofDescriptor, self).__init__( 

1112 containing_type.file if containing_type else None, 

1113 options, 

1114 serialized_options, 

1115 'OneofOptions', 

1116 ) 

1117 self.name = name 

1118 self.full_name = full_name 

1119 self.index = index 

1120 self.containing_type = containing_type 

1121 self.fields = fields 

1122 

1123 @property 

1124 def _parent(self): 

1125 return self.containing_type 

1126 

1127 

1128class ServiceDescriptor(_NestedDescriptorBase): 

1129 """Descriptor for a service. 

1130 

1131 Attributes: 

1132 name (str): Name of the service. 

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

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

1135 appears within the .proto file. 

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

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

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

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

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

1141 use default service options. 

1142 file (FileDescriptor): Reference to file info. 

1143 """ 

1144 

1145 if _USE_C_DESCRIPTORS: 

1146 _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor 

1147 

1148 def __new__( 

1149 cls, 

1150 name=None, 

1151 full_name=None, 

1152 index=None, 

1153 methods=None, 

1154 options=None, 

1155 serialized_options=None, 

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

1157 serialized_start=None, 

1158 serialized_end=None, 

1159 create_key=None, 

1160 ): 

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

1162 return _message.default_pool.FindServiceByName(full_name) 

1163 

1164 def __init__( 

1165 self, 

1166 name, 

1167 full_name, 

1168 index, 

1169 methods, 

1170 options=None, 

1171 serialized_options=None, 

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

1173 serialized_start=None, 

1174 serialized_end=None, 

1175 create_key=None, 

1176 ): 

1177 if create_key is not _internal_create_key: 

1178 _Deprecated('create function ServiceDescriptor()') 

1179 

1180 super(ServiceDescriptor, self).__init__( 

1181 options, 

1182 'ServiceOptions', 

1183 name, 

1184 full_name, 

1185 file, 

1186 None, 

1187 serialized_start=serialized_start, 

1188 serialized_end=serialized_end, 

1189 serialized_options=serialized_options, 

1190 ) 

1191 self.index = index 

1192 self.methods = methods 

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

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

1195 for method in self.methods: 

1196 method.file = self.file 

1197 method.containing_service = self 

1198 

1199 @property 

1200 def _parent(self): 

1201 return self.file 

1202 

1203 def FindMethodByName(self, name): 

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

1205 

1206 Args: 

1207 name (str): Name of the method. 

1208 

1209 Returns: 

1210 MethodDescriptor: The descriptor for the requested method. 

1211 

1212 Raises: 

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

1214 """ 

1215 return self.methods_by_name[name] 

1216 

1217 def CopyToProto(self, proto): 

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

1219 

1220 Args: 

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

1222 """ 

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

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

1225 

1226 

1227class MethodDescriptor(DescriptorBase): 

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

1229 

1230 Attributes: 

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

1232 full_name (str): Full name of method. 

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

1234 containing_service (ServiceDescriptor): The service that contains this 

1235 method. 

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

1237 accepts. 

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

1239 returns. 

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

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

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

1243 None to use default method options. 

1244 """ 

1245 

1246 if _USE_C_DESCRIPTORS: 

1247 _C_DESCRIPTOR_CLASS = _message.MethodDescriptor 

1248 

1249 def __new__( 

1250 cls, 

1251 name, 

1252 full_name, 

1253 index, 

1254 containing_service, 

1255 input_type, 

1256 output_type, 

1257 client_streaming=False, 

1258 server_streaming=False, 

1259 options=None, 

1260 serialized_options=None, 

1261 create_key=None, 

1262 ): 

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

1264 return _message.default_pool.FindMethodByName(full_name) 

1265 

1266 def __init__( 

1267 self, 

1268 name, 

1269 full_name, 

1270 index, 

1271 containing_service, 

1272 input_type, 

1273 output_type, 

1274 client_streaming=False, 

1275 server_streaming=False, 

1276 options=None, 

1277 serialized_options=None, 

1278 create_key=None, 

1279 ): 

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

1281 

1282 attributes above. 

1283 

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

1285 """ 

1286 if create_key is not _internal_create_key: 

1287 _Deprecated('create function MethodDescriptor()') 

1288 

1289 super(MethodDescriptor, self).__init__( 

1290 containing_service.file if containing_service else None, 

1291 options, 

1292 serialized_options, 

1293 'MethodOptions', 

1294 ) 

1295 self.name = name 

1296 self.full_name = full_name 

1297 self.index = index 

1298 self.containing_service = containing_service 

1299 self.input_type = input_type 

1300 self.output_type = output_type 

1301 self.client_streaming = client_streaming 

1302 self.server_streaming = server_streaming 

1303 

1304 @property 

1305 def _parent(self): 

1306 return self.containing_service 

1307 

1308 def CopyToProto(self, proto): 

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

1310 

1311 Args: 

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

1313 

1314 Raises: 

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

1316 arguments. 

1317 """ 

1318 if self.containing_service is not None: 

1319 from google.protobuf import descriptor_pb2 

1320 

1321 service_proto = descriptor_pb2.ServiceDescriptorProto() 

1322 self.containing_service.CopyToProto(service_proto) 

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

1324 else: 

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

1326 

1327 

1328class FileDescriptor(DescriptorBase): 

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

1330 

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

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

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

1334 proto code. 

1335 

1336 Attributes: 

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

1338 package (str): Name of the package 

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

1340 serialized_pb (bytes): Byte string of serialized 

1341 :class:`descriptor_pb2.FileDescriptorProto`. 

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

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

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

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

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

1347 their :class:`Descriptor`. 

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

1349 their :class:`EnumDescriptor`. 

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

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

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

1353 names to their :class:`ServiceDescriptor`. 

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

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

1356 """ 

1357 

1358 if _USE_C_DESCRIPTORS: 

1359 _C_DESCRIPTOR_CLASS = _message.FileDescriptor 

1360 

1361 def __new__( 

1362 cls, 

1363 name, 

1364 package, 

1365 options=None, 

1366 serialized_options=None, 

1367 serialized_pb=None, 

1368 dependencies=None, 

1369 public_dependencies=None, 

1370 syntax=None, 

1371 edition=None, 

1372 pool=None, 

1373 create_key=None, 

1374 ): 

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

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

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

1378 if serialized_pb: 

1379 return _message.default_pool.AddSerializedFile(serialized_pb) 

1380 else: 

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

1382 

1383 def __init__( 

1384 self, 

1385 name, 

1386 package, 

1387 options=None, 

1388 serialized_options=None, 

1389 serialized_pb=None, 

1390 dependencies=None, 

1391 public_dependencies=None, 

1392 syntax=None, 

1393 edition=None, 

1394 pool=None, 

1395 create_key=None, 

1396 ): 

1397 """Constructor.""" 

1398 if create_key is not _internal_create_key: 

1399 _Deprecated('create function FileDescriptor()') 

1400 

1401 super(FileDescriptor, self).__init__( 

1402 self, options, serialized_options, 'FileOptions' 

1403 ) 

1404 

1405 if edition and edition != 'EDITION_UNKNOWN': 

1406 self._edition = edition 

1407 elif syntax == 'proto3': 

1408 self._edition = 'EDITION_PROTO3' 

1409 else: 

1410 self._edition = 'EDITION_PROTO2' 

1411 

1412 if pool is None: 

1413 from google.protobuf import descriptor_pool 

1414 

1415 pool = descriptor_pool.Default() 

1416 self.pool = pool 

1417 self.message_types_by_name = {} 

1418 self.name = name 

1419 self.package = package 

1420 self.serialized_pb = serialized_pb 

1421 

1422 self.enum_types_by_name = {} 

1423 self.extensions_by_name = {} 

1424 self.services_by_name = {} 

1425 self.dependencies = dependencies or [] 

1426 self.public_dependencies = public_dependencies or [] 

1427 

1428 def CopyToProto(self, proto): 

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

1430 

1431 Args: 

1432 proto: An empty descriptor_pb2.FileDescriptorProto. 

1433 """ 

1434 proto.ParseFromString(self.serialized_pb) 

1435 

1436 @property 

1437 def _parent(self): 

1438 return None 

1439 

1440 

1441def _ParseOptions(message, string): 

1442 """Parses serialized options. 

1443 

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

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

1446 """ 

1447 message.ParseFromString(string) 

1448 return message 

1449 

1450 

1451def _ToCamelCase(name): 

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

1453 capitalize_next = False 

1454 result = [] 

1455 

1456 for c in name: 

1457 if c == '_': 

1458 if result: 

1459 capitalize_next = True 

1460 elif capitalize_next: 

1461 result.append(c.upper()) 

1462 capitalize_next = False 

1463 else: 

1464 result += c 

1465 

1466 # Lower-case the first letter. 

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

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

1469 return ''.join(result) 

1470 

1471 

1472def _OptionsOrNone(descriptor_proto): 

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

1474 if descriptor_proto.HasField('options'): 

1475 return descriptor_proto.options 

1476 else: 

1477 return None 

1478 

1479 

1480def _ToJsonName(name): 

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

1482 capitalize_next = False 

1483 result = [] 

1484 

1485 for c in name: 

1486 if c == '_': 

1487 capitalize_next = True 

1488 elif capitalize_next: 

1489 result.append(c.upper()) 

1490 capitalize_next = False 

1491 else: 

1492 result += c 

1493 

1494 return ''.join(result) 

1495 

1496 

1497def MakeDescriptor( 

1498 desc_proto, 

1499 package='', 

1500 build_file_if_cpp=True, 

1501 syntax=None, 

1502 edition=None, 

1503 file_desc=None, 

1504): 

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

1506 

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

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

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

1510 

1511 Args: 

1512 desc_proto: The descriptor_pb2.DescriptorProto protobuf message. 

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

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

1515 False on recursion, so no duplicates are created. 

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

1517 proto3 field presence semantics. 

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

1519 file_desc: A FileDescriptor to place this descriptor into. 

1520 

1521 Returns: 

1522 A Descriptor for protobuf messages. 

1523 """ 

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

1525 from google.protobuf import descriptor_pb2 

1526 

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

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

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

1530 # name is actually set to. 

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

1532 

1533 if package: 

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

1535 else: 

1536 file_name = proto_name + '.proto' 

1537 

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

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

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

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

1542 # it into the pool. 

1543 file_descriptor_proto = descriptor_pb2.FileDescriptorProto() 

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

1545 

1546 if package: 

1547 file_descriptor_proto.package = package 

1548 file_descriptor_proto.name = file_name 

1549 

1550 _message.default_pool.Add(file_descriptor_proto) 

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

1552 

1553 if _USE_C_DESCRIPTORS: 

1554 return result.message_types_by_name[desc_proto.name] 

1555 

1556 if file_desc is None: 

1557 file_desc = FileDescriptor( 

1558 pool=None, 

1559 name=file_name, 

1560 package=package, 

1561 syntax=syntax, 

1562 edition=edition, 

1563 options=None, 

1564 serialized_pb='', 

1565 dependencies=[], 

1566 public_dependencies=[], 

1567 create_key=_internal_create_key, 

1568 ) 

1569 full_message_name = [desc_proto.name] 

1570 if package: 

1571 full_message_name.insert(0, package) 

1572 

1573 # Create Descriptors for enum types 

1574 enum_types = {} 

1575 for enum_proto in desc_proto.enum_type: 

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

1577 enum_desc = EnumDescriptor( 

1578 enum_proto.name, 

1579 full_name, 

1580 None, 

1581 [ 

1582 EnumValueDescriptor( 

1583 enum_val.name, 

1584 ii, 

1585 enum_val.number, 

1586 create_key=_internal_create_key, 

1587 ) 

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

1589 ], 

1590 file=file_desc, 

1591 create_key=_internal_create_key, 

1592 ) 

1593 enum_types[full_name] = enum_desc 

1594 

1595 # Create Descriptors for nested types 

1596 nested_types = {} 

1597 for nested_proto in desc_proto.nested_type: 

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

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

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

1601 nested_desc = MakeDescriptor( 

1602 nested_proto, 

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

1604 build_file_if_cpp=False, 

1605 syntax=syntax, 

1606 edition=edition, 

1607 file_desc=file_desc, 

1608 ) 

1609 nested_types[full_name] = nested_desc 

1610 

1611 fields = [] 

1612 for field_proto in desc_proto.field: 

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

1614 enum_desc = None 

1615 nested_desc = None 

1616 if field_proto.json_name: 

1617 json_name = field_proto.json_name 

1618 else: 

1619 json_name = None 

1620 if field_proto.HasField('type_name'): 

1621 type_name = field_proto.type_name 

1622 full_type_name = '.'.join( 

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

1624 ) 

1625 if full_type_name in nested_types: 

1626 nested_desc = nested_types[full_type_name] 

1627 elif full_type_name in enum_types: 

1628 enum_desc = enum_types[full_type_name] 

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

1630 field = FieldDescriptor( 

1631 field_proto.name, 

1632 full_name, 

1633 field_proto.number - 1, 

1634 field_proto.number, 

1635 field_proto.type, 

1636 FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), 

1637 field_proto.label, 

1638 None, 

1639 nested_desc, 

1640 enum_desc, 

1641 None, 

1642 False, 

1643 None, 

1644 options=_OptionsOrNone(field_proto), 

1645 has_default_value=False, 

1646 json_name=json_name, 

1647 file=file_desc, 

1648 create_key=_internal_create_key, 

1649 ) 

1650 fields.append(field) 

1651 

1652 desc_name = '.'.join(full_message_name) 

1653 return Descriptor( 

1654 desc_proto.name, 

1655 desc_name, 

1656 None, 

1657 None, 

1658 fields, 

1659 list(nested_types.values()), 

1660 list(enum_types.values()), 

1661 [], 

1662 options=_OptionsOrNone(desc_proto), 

1663 file=file_desc, 

1664 create_key=_internal_create_key, 

1665 )