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

423 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 07:30 +0000

1# Protocol Buffers - Google's data interchange format 

2# Copyright 2008 Google Inc. All rights reserved. 

3# https://developers.google.com/protocol-buffers/ 

4# 

5# Redistribution and use in source and binary forms, with or without 

6# modification, are permitted provided that the following conditions are 

7# met: 

8# 

9# * Redistributions of source code must retain the above copyright 

10# notice, this list of conditions and the following disclaimer. 

11# * Redistributions in binary form must reproduce the above 

12# copyright notice, this list of conditions and the following disclaimer 

13# in the documentation and/or other materials provided with the 

14# distribution. 

15# * Neither the name of Google Inc. nor the names of its 

16# contributors may be used to endorse or promote products derived from 

17# this software without specific prior written permission. 

18# 

19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 

20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 

21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 

22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 

23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 

24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 

25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 

26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 

27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 

28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 

29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 

30 

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

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

33""" 

34 

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

36 

37import threading 

38import warnings 

39 

40from google.protobuf.internal import api_implementation 

41 

42_USE_C_DESCRIPTORS = False 

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

44 # Used by MakeDescriptor in cpp mode 

45 import binascii 

46 import os 

47 # pylint: disable=protected-access 

48 _message = api_implementation._c_module 

49 # TODO(jieluo): Remove this import after fix api_implementation 

50 if _message is None: 

51 from google.protobuf.pyext import _message 

52 _USE_C_DESCRIPTORS = True 

53 

54 

55class Error(Exception): 

56 """Base error for this module.""" 

57 

58 

59class TypeTransformationError(Error): 

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

61 

62 

63if _USE_C_DESCRIPTORS: 

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

65 # isinstance(my_descriptor, FieldDescriptor) 

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

67 # type written in C++. 

68 class DescriptorMetaclass(type): 

69 

70 def __instancecheck__(cls, obj): 

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

72 return True 

73 if isinstance(obj, cls._C_DESCRIPTOR_CLASS): 

74 return True 

75 return False 

76else: 

77 # The standard metaclass; nothing changes. 

78 DescriptorMetaclass = type 

79 

80 

81class _Lock(object): 

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

83 

84 def __new__(cls): 

85 self = object.__new__(cls) 

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

87 return self 

88 

89 def __enter__(self): 

90 self._lock.acquire() 

91 

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

93 self._lock.release() 

94 

95 

96_lock = threading.Lock() 

97 

98 

99def _Deprecated(name): 

100 if _Deprecated.count > 0: 

101 _Deprecated.count -= 1 

102 warnings.warn( 

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

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

105 'generated code or query the descriptor_pool.' 

106 % name, 

107 category=DeprecationWarning, stacklevel=3) 

108 

109 

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

111# users to notice and do not cause timeout. 

112_Deprecated.count = 100 

113 

114 

115_internal_create_key = object() 

116 

117 

118class DescriptorBase(metaclass=DescriptorMetaclass): 

119 

120 """Descriptors base class. 

121 

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

123 related functionality. 

124 

125 Attributes: 

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

127 is not necessary to read this -- just call GetOptions() which will 

128 happily return the default instance. However, it's sometimes useful 

129 for efficiency, and also useful inside the protobuf implementation to 

130 avoid some bootstrapping issues. 

131 """ 

132 

133 if _USE_C_DESCRIPTORS: 

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

135 # subclasses" of this descriptor class. 

136 _C_DESCRIPTOR_CLASS = () 

137 

138 def __init__(self, options, serialized_options, options_class_name): 

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

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

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

142 """ 

143 self._options = options 

144 self._options_class_name = options_class_name 

145 self._serialized_options = serialized_options 

146 

147 # Does this descriptor have non-default options? 

148 self.has_options = (options is not None) or (serialized_options is not None) 

149 

150 def _SetOptions(self, options, options_class_name): 

151 """Sets the descriptor's options 

152 

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

154 options. It must not be used outside proto2. 

155 """ 

156 self._options = options 

157 self._options_class_name = options_class_name 

158 

159 # Does this descriptor have non-default options? 

160 self.has_options = options is not None 

161 

162 def GetOptions(self): 

163 """Retrieves descriptor options. 

164 

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

166 descriptor. 

167 """ 

168 if self._options: 

169 return self._options 

170 

171 from google.protobuf import descriptor_pb2 

172 try: 

173 options_class = getattr(descriptor_pb2, 

174 self._options_class_name) 

175 except AttributeError: 

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

177 (self._options_class_name)) 

178 

179 with _lock: 

180 if self._serialized_options is None: 

181 self._options = options_class() 

182 else: 

183 self._options = _ParseOptions(options_class(), 

184 self._serialized_options) 

185 

186 return self._options 

187 

188 

189class _NestedDescriptorBase(DescriptorBase): 

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

191 

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

193 file, containing_type, serialized_start=None, 

194 serialized_end=None, serialized_options=None): 

195 """Constructor. 

196 

197 Args: 

198 options: Protocol message options or None 

199 to use default message options. 

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

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

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

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

204 enclosing types. 

205 file (FileDescriptor): Reference to file info. 

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

207 descriptor as parent, otherwise None. 

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

209 file.serialized_pb that describes this descriptor. 

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

211 file.serialized_pb that describes this descriptor. 

212 serialized_options: Protocol message serialized options or None. 

213 """ 

214 super(_NestedDescriptorBase, self).__init__( 

215 options, serialized_options, options_class_name) 

216 

217 self.name = name 

218 # TODO(falk): Add function to calculate full_name instead of having it in 

219 # memory? 

220 self.full_name = full_name 

221 self.file = file 

222 self.containing_type = containing_type 

223 

224 self._serialized_start = serialized_start 

225 self._serialized_end = serialized_end 

226 

227 def CopyToProto(self, proto): 

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

229 

230 Args: 

231 proto: An empty proto instance from descriptor_pb2. 

232 

233 Raises: 

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

235 arguments. 

236 """ 

237 if (self.file is not None and 

238 self._serialized_start is not None and 

239 self._serialized_end is not None): 

240 proto.ParseFromString(self.file.serialized_pb[ 

241 self._serialized_start:self._serialized_end]) 

242 else: 

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

244 

245 

246class Descriptor(_NestedDescriptorBase): 

247 

248 """Descriptor for a protocol message type. 

249 

250 Attributes: 

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

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

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

254 enclosing types. 

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

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

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

258 this type. 

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

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

261 by "number" attribute in each FieldDescriptor. 

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

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

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

265 nested_types (list[Descriptor]): Descriptor references 

266 for all protocol message types nested within this one. 

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

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

269 in each Descriptor. 

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

271 for all enums contained within this type. 

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

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

274 indexed by "name" attribute in each EnumDescriptor. 

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

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

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

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

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

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

281 FieldDescriptor. 

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

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

284 in this message. 

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

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

287 file (FileDescriptor): Reference to file descriptor. 

288 

289 """ 

290 

291 if _USE_C_DESCRIPTORS: 

292 _C_DESCRIPTOR_CLASS = _message.Descriptor 

293 

294 def __new__( 

295 cls, 

296 name=None, 

297 full_name=None, 

298 filename=None, 

299 containing_type=None, 

300 fields=None, 

301 nested_types=None, 

302 enum_types=None, 

303 extensions=None, 

304 options=None, 

305 serialized_options=None, 

306 is_extendable=True, 

307 extension_ranges=None, 

308 oneofs=None, 

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

310 serialized_start=None, 

311 serialized_end=None, 

312 syntax=None, 

313 create_key=None): 

314 _message.Message._CheckCalledFromGeneratedFile() 

315 return _message.default_pool.FindMessageTypeByName(full_name) 

316 

317 # NOTE(tmarek): The file argument redefining a builtin is nothing we can 

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

319 # name of the argument. 

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

321 nested_types, enum_types, extensions, options=None, 

322 serialized_options=None, 

323 is_extendable=True, extension_ranges=None, oneofs=None, 

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

325 syntax=None, create_key=None): 

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

327 of Descriptor fields above. 

328 

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

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

331 """ 

332 if create_key is not _internal_create_key: 

333 _Deprecated('Descriptor') 

334 

335 super(Descriptor, self).__init__( 

336 options, 'MessageOptions', name, full_name, file, 

337 containing_type, serialized_start=serialized_start, 

338 serialized_end=serialized_end, serialized_options=serialized_options) 

339 

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

341 # so that: 

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

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

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

345 self.fields = fields 

346 for field in self.fields: 

347 field.containing_type = self 

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

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

350 self._fields_by_camelcase_name = None 

351 

352 self.nested_types = nested_types 

353 for nested_type in nested_types: 

354 nested_type.containing_type = self 

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

356 

357 self.enum_types = enum_types 

358 for enum_type in self.enum_types: 

359 enum_type.containing_type = self 

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

361 self.enum_values_by_name = dict( 

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

363 

364 self.extensions = extensions 

365 for extension in self.extensions: 

366 extension.extension_scope = self 

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

368 self.is_extendable = is_extendable 

369 self.extension_ranges = extension_ranges 

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

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

372 for oneof in self.oneofs: 

373 oneof.containing_type = self 

374 self.syntax = syntax or "proto2" 

375 

376 @property 

377 def fields_by_camelcase_name(self): 

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

379 :attr:`FieldDescriptor.camelcase_name`. 

380 """ 

381 if self._fields_by_camelcase_name is None: 

382 self._fields_by_camelcase_name = dict( 

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

384 return self._fields_by_camelcase_name 

385 

386 def EnumValueName(self, enum, value): 

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

388 

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

390 

391 Args: 

392 enum: string name of the Enum. 

393 value: int, value of the enum. 

394 

395 Returns: 

396 string name of the enum value. 

397 

398 Raises: 

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

400 value for the enum. 

401 """ 

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

403 

404 def CopyToProto(self, proto): 

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

406 

407 Args: 

408 proto: An empty descriptor_pb2.DescriptorProto. 

409 """ 

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

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

412 

413 

414# TODO(robinson): We should have aggressive checking here, 

415# for example: 

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

417# to specify a default value. 

418# * [Other examples here as needed]. 

419# 

420# TODO(robinson): for this and other *Descriptor classes, we 

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

422# prevent clients from setting the attributes). Having 

423# stronger invariants here in general will reduce the number 

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

425class FieldDescriptor(DescriptorBase): 

426 

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

428 

429 Attributes: 

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

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

432 particularly relevant for extensions. 

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

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

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

436 

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

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

439 represent this field. 

440 

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

442 field is optional, required, or repeated. 

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

444 otherwise false. 

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

446 meaningful for non-repeated scalar fields. Repeated fields 

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

448 fields should always set this to None. 

449 

450 containing_type (Descriptor): Descriptor of the protocol message 

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

452 if we're passed into one. 

453 Somewhat confusingly, for extension fields, this is the 

454 descriptor of the EXTENDED message, not the descriptor 

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

456 extension_scope below). 

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

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

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

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

461 

462 is_extension: True iff this describes an extension field. 

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

464 Gives the message that immediately contains this extension field. 

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

466 

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

468 None to use default field options. 

469 

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

471 union, contains its descriptor. Otherwise, None. 

472 

473 file (FileDescriptor): Reference to file descriptor. 

474 """ 

475 

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

477 # descriptor.h. 

478 # 

479 # TODO(robinson): Find a way to eliminate this repetition. 

480 TYPE_DOUBLE = 1 

481 TYPE_FLOAT = 2 

482 TYPE_INT64 = 3 

483 TYPE_UINT64 = 4 

484 TYPE_INT32 = 5 

485 TYPE_FIXED64 = 6 

486 TYPE_FIXED32 = 7 

487 TYPE_BOOL = 8 

488 TYPE_STRING = 9 

489 TYPE_GROUP = 10 

490 TYPE_MESSAGE = 11 

491 TYPE_BYTES = 12 

492 TYPE_UINT32 = 13 

493 TYPE_ENUM = 14 

494 TYPE_SFIXED32 = 15 

495 TYPE_SFIXED64 = 16 

496 TYPE_SINT32 = 17 

497 TYPE_SINT64 = 18 

498 MAX_TYPE = 18 

499 

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

501 # descriptor.h. 

502 # 

503 # TODO(robinson): Find a way to eliminate this repetition. 

504 CPPTYPE_INT32 = 1 

505 CPPTYPE_INT64 = 2 

506 CPPTYPE_UINT32 = 3 

507 CPPTYPE_UINT64 = 4 

508 CPPTYPE_DOUBLE = 5 

509 CPPTYPE_FLOAT = 6 

510 CPPTYPE_BOOL = 7 

511 CPPTYPE_ENUM = 8 

512 CPPTYPE_STRING = 9 

513 CPPTYPE_MESSAGE = 10 

514 MAX_CPPTYPE = 10 

515 

516 _PYTHON_TO_CPP_PROTO_TYPE_MAP = { 

517 TYPE_DOUBLE: CPPTYPE_DOUBLE, 

518 TYPE_FLOAT: CPPTYPE_FLOAT, 

519 TYPE_ENUM: CPPTYPE_ENUM, 

520 TYPE_INT64: CPPTYPE_INT64, 

521 TYPE_SINT64: CPPTYPE_INT64, 

522 TYPE_SFIXED64: CPPTYPE_INT64, 

523 TYPE_UINT64: CPPTYPE_UINT64, 

524 TYPE_FIXED64: CPPTYPE_UINT64, 

525 TYPE_INT32: CPPTYPE_INT32, 

526 TYPE_SFIXED32: CPPTYPE_INT32, 

527 TYPE_SINT32: CPPTYPE_INT32, 

528 TYPE_UINT32: CPPTYPE_UINT32, 

529 TYPE_FIXED32: CPPTYPE_UINT32, 

530 TYPE_BYTES: CPPTYPE_STRING, 

531 TYPE_STRING: CPPTYPE_STRING, 

532 TYPE_BOOL: CPPTYPE_BOOL, 

533 TYPE_MESSAGE: CPPTYPE_MESSAGE, 

534 TYPE_GROUP: CPPTYPE_MESSAGE 

535 } 

536 

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

538 # descriptor.h. 

539 # 

540 # TODO(robinson): Find a way to eliminate this repetition. 

541 LABEL_OPTIONAL = 1 

542 LABEL_REQUIRED = 2 

543 LABEL_REPEATED = 3 

544 MAX_LABEL = 3 

545 

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

547 # and kLastReservedNumber in descriptor.h 

548 MAX_FIELD_NUMBER = (1 << 29) - 1 

549 FIRST_RESERVED_FIELD_NUMBER = 19000 

550 LAST_RESERVED_FIELD_NUMBER = 19999 

551 

552 if _USE_C_DESCRIPTORS: 

553 _C_DESCRIPTOR_CLASS = _message.FieldDescriptor 

554 

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

556 default_value, message_type, enum_type, containing_type, 

557 is_extension, extension_scope, options=None, 

558 serialized_options=None, 

559 has_default_value=True, containing_oneof=None, json_name=None, 

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

561 _message.Message._CheckCalledFromGeneratedFile() 

562 if is_extension: 

563 return _message.default_pool.FindExtensionByName(full_name) 

564 else: 

565 return _message.default_pool.FindFieldByName(full_name) 

566 

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

568 default_value, message_type, enum_type, containing_type, 

569 is_extension, extension_scope, options=None, 

570 serialized_options=None, 

571 has_default_value=True, containing_oneof=None, json_name=None, 

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

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

574 attributes above. 

575 

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

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

578 Likewise for extension_scope. 

579 """ 

580 if create_key is not _internal_create_key: 

581 _Deprecated('FieldDescriptor') 

582 

583 super(FieldDescriptor, self).__init__( 

584 options, serialized_options, 'FieldOptions') 

585 self.name = name 

586 self.full_name = full_name 

587 self.file = file 

588 self._camelcase_name = None 

589 if json_name is None: 

590 self.json_name = _ToJsonName(name) 

591 else: 

592 self.json_name = json_name 

593 self.index = index 

594 self.number = number 

595 self.type = type 

596 self.cpp_type = cpp_type 

597 self.label = label 

598 self.has_default_value = has_default_value 

599 self.default_value = default_value 

600 self.containing_type = containing_type 

601 self.message_type = message_type 

602 self.enum_type = enum_type 

603 self.is_extension = is_extension 

604 self.extension_scope = extension_scope 

605 self.containing_oneof = containing_oneof 

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

607 self._cdescriptor = None 

608 else: 

609 if is_extension: 

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

611 else: 

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

613 

614 @property 

615 def camelcase_name(self): 

616 """Camelcase name of this field. 

617 

618 Returns: 

619 str: the name in CamelCase. 

620 """ 

621 if self._camelcase_name is None: 

622 self._camelcase_name = _ToCamelCase(self.name) 

623 return self._camelcase_name 

624 

625 @property 

626 def has_presence(self): 

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

628 

629 Raises: 

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

631 """ 

632 if self.label == FieldDescriptor.LABEL_REPEATED: 

633 return False 

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

635 self.containing_oneof): 

636 return True 

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

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

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

640 # TODO(jieluo): remove syntax usage b/240619313 

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

642 

643 @property 

644 def is_packed(self): 

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

646 if self.label != FieldDescriptor.LABEL_REPEATED: 

647 return False 

648 field_type = self.type 

649 if (field_type == FieldDescriptor.TYPE_STRING or 

650 field_type == FieldDescriptor.TYPE_GROUP or 

651 field_type == FieldDescriptor.TYPE_MESSAGE or 

652 field_type == FieldDescriptor.TYPE_BYTES): 

653 return False 

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

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

656 else: 

657 return (not self.has_options or 

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

659 self.GetOptions().packed) 

660 

661 @staticmethod 

662 def ProtoTypeToCppProtoType(proto_type): 

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

664 

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

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

667 translate from one to another. 

668 

669 Args: 

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

671 Returns: 

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

673 Raises: 

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

675 """ 

676 try: 

677 return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] 

678 except KeyError: 

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

680 

681 

682class EnumDescriptor(_NestedDescriptorBase): 

683 

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

685 

686 Attributes: 

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

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

689 and any enclosing type(s). 

690 

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

692 in this enum. 

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

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

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

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

697 containing_type (Descriptor): Descriptor of the immediate containing 

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

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

700 if we're passed into one. 

701 file (FileDescriptor): Reference to file descriptor. 

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

703 None to use default enum options. 

704 """ 

705 

706 if _USE_C_DESCRIPTORS: 

707 _C_DESCRIPTOR_CLASS = _message.EnumDescriptor 

708 

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

710 containing_type=None, options=None, 

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

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

713 _message.Message._CheckCalledFromGeneratedFile() 

714 return _message.default_pool.FindEnumTypeByName(full_name) 

715 

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

717 containing_type=None, options=None, 

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

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

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

721 

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

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

724 """ 

725 if create_key is not _internal_create_key: 

726 _Deprecated('EnumDescriptor') 

727 

728 super(EnumDescriptor, self).__init__( 

729 options, 'EnumOptions', name, full_name, file, 

730 containing_type, serialized_start=serialized_start, 

731 serialized_end=serialized_end, serialized_options=serialized_options) 

732 

733 self.values = values 

734 for value in self.values: 

735 value.type = self 

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

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

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

739 

740 @property 

741 def is_closed(self): 

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

743 

744 This means that it: 

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

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

747 fields. 

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

749 

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

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

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

753 writing, we know that: 

754 

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

756 - UPB and UPB-based Python do not. 

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

758 

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

760 runtime's enum handling quirks. 

761 """ 

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

763 

764 def CopyToProto(self, proto): 

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

766 

767 Args: 

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

769 """ 

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

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

772 

773 

774class EnumValueDescriptor(DescriptorBase): 

775 

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

777 

778 Attributes: 

779 name (str): Name of this value. 

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

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

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

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

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

785 passed into one. 

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

787 None to use default enum value options options. 

788 """ 

789 

790 if _USE_C_DESCRIPTORS: 

791 _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor 

792 

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

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

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

796 _message.Message._CheckCalledFromGeneratedFile() 

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

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

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

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

801 return None 

802 

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

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

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

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

807 if create_key is not _internal_create_key: 

808 _Deprecated('EnumValueDescriptor') 

809 

810 super(EnumValueDescriptor, self).__init__( 

811 options, serialized_options, 'EnumValueOptions') 

812 self.name = name 

813 self.index = index 

814 self.number = number 

815 self.type = type 

816 

817 

818class OneofDescriptor(DescriptorBase): 

819 """Descriptor for a oneof field. 

820 

821 Attributes: 

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

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

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

825 its containing type. 

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

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

828 if we're passed into one. 

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

830 oneof can contain. 

831 """ 

832 

833 if _USE_C_DESCRIPTORS: 

834 _C_DESCRIPTOR_CLASS = _message.OneofDescriptor 

835 

836 def __new__( 

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

838 serialized_options=None, create_key=None): 

839 _message.Message._CheckCalledFromGeneratedFile() 

840 return _message.default_pool.FindOneofByName(full_name) 

841 

842 def __init__( 

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

844 serialized_options=None, create_key=None): 

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

846 if create_key is not _internal_create_key: 

847 _Deprecated('OneofDescriptor') 

848 

849 super(OneofDescriptor, self).__init__( 

850 options, serialized_options, 'OneofOptions') 

851 self.name = name 

852 self.full_name = full_name 

853 self.index = index 

854 self.containing_type = containing_type 

855 self.fields = fields 

856 

857 

858class ServiceDescriptor(_NestedDescriptorBase): 

859 

860 """Descriptor for a service. 

861 

862 Attributes: 

863 name (str): Name of the service. 

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

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

866 definition appears within the .proto file. 

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

868 service. 

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

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

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

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

873 None to use default service options. 

874 file (FileDescriptor): Reference to file info. 

875 """ 

876 

877 if _USE_C_DESCRIPTORS: 

878 _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor 

879 

880 def __new__( 

881 cls, 

882 name=None, 

883 full_name=None, 

884 index=None, 

885 methods=None, 

886 options=None, 

887 serialized_options=None, 

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

889 serialized_start=None, 

890 serialized_end=None, 

891 create_key=None): 

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

893 return _message.default_pool.FindServiceByName(full_name) 

894 

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

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

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

898 if create_key is not _internal_create_key: 

899 _Deprecated('ServiceDescriptor') 

900 

901 super(ServiceDescriptor, self).__init__( 

902 options, 'ServiceOptions', name, full_name, file, 

903 None, serialized_start=serialized_start, 

904 serialized_end=serialized_end, serialized_options=serialized_options) 

905 self.index = index 

906 self.methods = methods 

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

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

909 for method in self.methods: 

910 method.containing_service = self 

911 

912 def FindMethodByName(self, name): 

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

914 

915 Args: 

916 name (str): Name of the method. 

917 

918 Returns: 

919 MethodDescriptor: The descriptor for the requested method. 

920 

921 Raises: 

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

923 """ 

924 return self.methods_by_name[name] 

925 

926 def CopyToProto(self, proto): 

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

928 

929 Args: 

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

931 """ 

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

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

934 

935 

936class MethodDescriptor(DescriptorBase): 

937 

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

939 

940 Attributes: 

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

942 full_name (str): Full name of method. 

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

944 containing_service (ServiceDescriptor): The service that contains this 

945 method. 

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

947 accepts. 

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

949 returns. 

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

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

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

953 None to use default method options. 

954 """ 

955 

956 if _USE_C_DESCRIPTORS: 

957 _C_DESCRIPTOR_CLASS = _message.MethodDescriptor 

958 

959 def __new__(cls, 

960 name, 

961 full_name, 

962 index, 

963 containing_service, 

964 input_type, 

965 output_type, 

966 client_streaming=False, 

967 server_streaming=False, 

968 options=None, 

969 serialized_options=None, 

970 create_key=None): 

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

972 return _message.default_pool.FindMethodByName(full_name) 

973 

974 def __init__(self, 

975 name, 

976 full_name, 

977 index, 

978 containing_service, 

979 input_type, 

980 output_type, 

981 client_streaming=False, 

982 server_streaming=False, 

983 options=None, 

984 serialized_options=None, 

985 create_key=None): 

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

987 attributes above. 

988 

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

990 """ 

991 if create_key is not _internal_create_key: 

992 _Deprecated('MethodDescriptor') 

993 

994 super(MethodDescriptor, self).__init__( 

995 options, serialized_options, 'MethodOptions') 

996 self.name = name 

997 self.full_name = full_name 

998 self.index = index 

999 self.containing_service = containing_service 

1000 self.input_type = input_type 

1001 self.output_type = output_type 

1002 self.client_streaming = client_streaming 

1003 self.server_streaming = server_streaming 

1004 

1005 def CopyToProto(self, proto): 

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

1007 

1008 Args: 

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

1010 

1011 Raises: 

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

1013 arguments. 

1014 """ 

1015 if self.containing_service is not None: 

1016 from google.protobuf import descriptor_pb2 

1017 service_proto = descriptor_pb2.ServiceDescriptorProto() 

1018 self.containing_service.CopyToProto(service_proto) 

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

1020 else: 

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

1022 

1023 

1024class FileDescriptor(DescriptorBase): 

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

1026 

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

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

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

1030 proto code. 

1031 

1032 Attributes: 

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

1034 package (str): Name of the package 

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

1036 "proto3") 

1037 serialized_pb (bytes): Byte string of serialized 

1038 :class:`descriptor_pb2.FileDescriptorProto`. 

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

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

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

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

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

1044 to their :class:`Descriptor`. 

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

1046 their :class:`EnumDescriptor`. 

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

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

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

1050 names to their :class:`ServiceDescriptor`. 

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

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

1053 """ 

1054 

1055 if _USE_C_DESCRIPTORS: 

1056 _C_DESCRIPTOR_CLASS = _message.FileDescriptor 

1057 

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

1059 serialized_options=None, serialized_pb=None, 

1060 dependencies=None, public_dependencies=None, 

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

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

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

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

1065 if serialized_pb: 

1066 return _message.default_pool.AddSerializedFile(serialized_pb) 

1067 else: 

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

1069 

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

1071 serialized_options=None, serialized_pb=None, 

1072 dependencies=None, public_dependencies=None, 

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

1074 """Constructor.""" 

1075 if create_key is not _internal_create_key: 

1076 _Deprecated('FileDescriptor') 

1077 

1078 super(FileDescriptor, self).__init__( 

1079 options, serialized_options, 'FileOptions') 

1080 

1081 if pool is None: 

1082 from google.protobuf import descriptor_pool 

1083 pool = descriptor_pool.Default() 

1084 self.pool = pool 

1085 self.message_types_by_name = {} 

1086 self.name = name 

1087 self.package = package 

1088 self.syntax = syntax or "proto2" 

1089 self.serialized_pb = serialized_pb 

1090 

1091 self.enum_types_by_name = {} 

1092 self.extensions_by_name = {} 

1093 self.services_by_name = {} 

1094 self.dependencies = (dependencies or []) 

1095 self.public_dependencies = (public_dependencies or []) 

1096 

1097 def CopyToProto(self, proto): 

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

1099 

1100 Args: 

1101 proto: An empty descriptor_pb2.FileDescriptorProto. 

1102 """ 

1103 proto.ParseFromString(self.serialized_pb) 

1104 

1105 

1106def _ParseOptions(message, string): 

1107 """Parses serialized options. 

1108 

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

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

1111 """ 

1112 message.ParseFromString(string) 

1113 return message 

1114 

1115 

1116def _ToCamelCase(name): 

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

1118 capitalize_next = False 

1119 result = [] 

1120 

1121 for c in name: 

1122 if c == '_': 

1123 if result: 

1124 capitalize_next = True 

1125 elif capitalize_next: 

1126 result.append(c.upper()) 

1127 capitalize_next = False 

1128 else: 

1129 result += c 

1130 

1131 # Lower-case the first letter. 

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

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

1134 return ''.join(result) 

1135 

1136 

1137def _OptionsOrNone(descriptor_proto): 

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

1139 if descriptor_proto.HasField('options'): 

1140 return descriptor_proto.options 

1141 else: 

1142 return None 

1143 

1144 

1145def _ToJsonName(name): 

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

1147 capitalize_next = False 

1148 result = [] 

1149 

1150 for c in name: 

1151 if c == '_': 

1152 capitalize_next = True 

1153 elif capitalize_next: 

1154 result.append(c.upper()) 

1155 capitalize_next = False 

1156 else: 

1157 result += c 

1158 

1159 return ''.join(result) 

1160 

1161 

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

1163 syntax=None): 

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

1165 

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

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

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

1169 

1170 Args: 

1171 desc_proto: The descriptor_pb2.DescriptorProto protobuf message. 

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

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

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

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

1176 proto3 field presence semantics. 

1177 Returns: 

1178 A Descriptor for protobuf messages. 

1179 """ 

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

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

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

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

1184 # it into the pool. 

1185 from google.protobuf import descriptor_pb2 

1186 file_descriptor_proto = descriptor_pb2.FileDescriptorProto() 

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

1188 

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

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

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

1192 # name is actually set to. 

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

1194 

1195 if package: 

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

1197 proto_name + '.proto') 

1198 file_descriptor_proto.package = package 

1199 else: 

1200 file_descriptor_proto.name = proto_name + '.proto' 

1201 

1202 _message.default_pool.Add(file_descriptor_proto) 

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

1204 

1205 if _USE_C_DESCRIPTORS: 

1206 return result.message_types_by_name[desc_proto.name] 

1207 

1208 full_message_name = [desc_proto.name] 

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

1210 

1211 # Create Descriptors for enum types 

1212 enum_types = {} 

1213 for enum_proto in desc_proto.enum_type: 

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

1215 enum_desc = EnumDescriptor( 

1216 enum_proto.name, full_name, None, [ 

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

1218 create_key=_internal_create_key) 

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

1220 create_key=_internal_create_key) 

1221 enum_types[full_name] = enum_desc 

1222 

1223 # Create Descriptors for nested types 

1224 nested_types = {} 

1225 for nested_proto in desc_proto.nested_type: 

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

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

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

1229 nested_desc = MakeDescriptor(nested_proto, 

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

1231 build_file_if_cpp=False, 

1232 syntax=syntax) 

1233 nested_types[full_name] = nested_desc 

1234 

1235 fields = [] 

1236 for field_proto in desc_proto.field: 

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

1238 enum_desc = None 

1239 nested_desc = None 

1240 if field_proto.json_name: 

1241 json_name = field_proto.json_name 

1242 else: 

1243 json_name = None 

1244 if field_proto.HasField('type_name'): 

1245 type_name = field_proto.type_name 

1246 full_type_name = '.'.join(full_message_name + 

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

1248 if full_type_name in nested_types: 

1249 nested_desc = nested_types[full_type_name] 

1250 elif full_type_name in enum_types: 

1251 enum_desc = enum_types[full_type_name] 

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

1253 field = FieldDescriptor( 

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

1255 field_proto.number, field_proto.type, 

1256 FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), 

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

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

1259 json_name=json_name, create_key=_internal_create_key) 

1260 fields.append(field) 

1261 

1262 desc_name = '.'.join(full_message_name) 

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

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

1265 options=_OptionsOrNone(desc_proto), 

1266 create_key=_internal_create_key)