def __init__(self, name, package, options=None, serialized_pb=None, dependencies=None): """Constructor.""" super(FileDescriptor, self).__init__(options, 'FileOptions') self.message_types_by_name = {} self.name = name self.package = package self.serialized_pb = serialized_pb self.enum_types_by_name = {} self.extensions_by_name = {} self.dependencies = (dependencies or []) if (api_implementation.Type() == 'cpp' and self.serialized_pb is not None): if api_implementation.Version() == 2: # pylint: disable=protected-access _message.Message._BuildFile(self.serialized_pb) # pylint: enable=protected-access else: cpp_message.BuildFile(self.serialized_pb)
def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True): """Make a protobuf Descriptor given a DescriptorProto protobuf. Handles nested descriptors. Note that this is limited to the scope of defining a message inside of another message. Composite fields can currently only be resolved if the message is defined in the same scope as the field. Args: desc_proto: The descriptor_pb2.DescriptorProto protobuf message. package: Optional package name for the new message Descriptor (string). build_file_if_cpp: Update the C++ descriptor pool if api matches. Set to False on recursion, so no duplicates are created. Returns: A Descriptor for protobuf messages. """ if api_implementation.Type() == 'cpp' and build_file_if_cpp: # The C++ implementation requires all descriptors to be backed by the same # definition in the C++ descriptor pool. To do this, we build a # FileDescriptorProto with the same definition as this descriptor and build # it into the pool. from protobuf26 import descriptor_pb2 file_descriptor_proto = descriptor_pb2.FileDescriptorProto() file_descriptor_proto.message_type.add().MergeFrom(desc_proto) # Generate a random name for this proto file to prevent conflicts with # any imported ones. We need to specify a file name so BuildFile accepts # our FileDescriptorProto, but it is not important what that file name # is actually set to. proto_name = str(uuid.uuid4()) if package: file_descriptor_proto.name = os.path.join( package.replace('.', '/'), proto_name + '.proto') file_descriptor_proto.package = package else: file_descriptor_proto.name = proto_name + '.proto' if api_implementation.Version() == 2: # pylint: disable=protected-access _message.Message._BuildFile( file_descriptor_proto.SerializeToString()) # pylint: enable=protected-access else: cpp_message.BuildFile(file_descriptor_proto.SerializeToString()) full_message_name = [desc_proto.name] if package: full_message_name.insert(0, package) # Create Descriptors for enum types enum_types = {} for enum_proto in desc_proto.enum_type: full_name = '.'.join(full_message_name + [enum_proto.name]) enum_desc = EnumDescriptor(enum_proto.name, full_name, None, [ EnumValueDescriptor(enum_val.name, ii, enum_val.number) for ii, enum_val in enumerate(enum_proto.value) ]) enum_types[full_name] = enum_desc # Create Descriptors for nested types nested_types = {} for nested_proto in desc_proto.nested_type: full_name = '.'.join(full_message_name + [nested_proto.name]) # Nested types are just those defined inside of the message, not all types # used by fields in the message, so no loops are possible here. nested_desc = MakeDescriptor(nested_proto, package='.'.join(full_message_name), build_file_if_cpp=False) nested_types[full_name] = nested_desc fields = [] for field_proto in desc_proto.field: full_name = '.'.join(full_message_name + [field_proto.name]) enum_desc = None nested_desc = None if field_proto.HasField('type_name'): type_name = field_proto.type_name full_type_name = '.'.join(full_message_name + [type_name[type_name.rfind('.') + 1:]]) if full_type_name in nested_types: nested_desc = nested_types[full_type_name] elif full_type_name in enum_types: enum_desc = enum_types[full_type_name] # Else type_name references a non-local type, which isn't implemented field = FieldDescriptor(field_proto.name, full_name, field_proto.number - 1, field_proto.number, field_proto.type, FieldDescriptor.ProtoTypeToCppProtoType( field_proto.type), field_proto.label, None, nested_desc, enum_desc, None, False, None, has_default_value=False) fields.append(field) desc_name = '.'.join(full_message_name) return Descriptor(desc_proto.name, desc_name, None, None, fields, nested_types.values(), enum_types.values(), [])
def __init__(self, name, full_name, index, number, type, cpp_type, label, default_value, message_type, enum_type, containing_type, is_extension, extension_scope, options=None, has_default_value=True, containing_oneof=None): """The arguments are as described in the description of FieldDescriptor attributes above. Note that containing_type may be None, and may be set later if necessary (to deal with circular references between message types, for example). Likewise for extension_scope. """ super(FieldDescriptor, self).__init__(options, 'FieldOptions') self.name = name self.full_name = full_name self.index = index self.number = number self.type = type self.cpp_type = cpp_type self.label = label self.has_default_value = has_default_value self.default_value = default_value self.containing_type = containing_type self.message_type = message_type self.enum_type = enum_type self.is_extension = is_extension self.extension_scope = extension_scope self.containing_oneof = containing_oneof if api_implementation.Type() == 'cpp': if is_extension: if api_implementation.Version() == 2: # pylint: disable=protected-access self._cdescriptor = ( _message.Message._GetExtensionDescriptor(full_name)) # pylint: enable=protected-access else: self._cdescriptor = cpp_message.GetExtensionDescriptor( full_name) else: if api_implementation.Version() == 2: # pylint: disable=protected-access self._cdescriptor = _message.Message._GetFieldDescriptor( full_name) # pylint: enable=protected-access else: self._cdescriptor = cpp_message.GetFieldDescriptor( full_name) else: self._cdescriptor = None
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Needs to stay compatible with Python 2.5 due to GAE. # # Copyright 2007 Google Inc. All Rights Reserved. """Descriptors essentially contain exactly the information found in a .proto file, in types that make this information accessible in Python. """ __author__ = '[email protected] (Will Robinson)' from protobuf26.internal import api_implementation if api_implementation.Type() == 'cpp': # Used by MakeDescriptor in cpp mode import os import uuid if api_implementation.Version() == 2: from protobuf26.pyext import _message else: from protobuf26.internal import cpp_message class Error(Exception): """Base error for this module.""" class TypeTransformationError(Error):