예제 #1
0
def add_message_fields(
    root: ProtoNode,
    message: ProtoNode,
    proto_message,
) -> None:
    """Adds fields from a protobuf message descriptor to a message node."""
    assert message.type() == ProtoNode.Type.MESSAGE

    for field in proto_message.field:
        if field.type_name:
            # The "type_name" member contains the global .proto path of the
            # field's type object, for example ".pw.protobuf.test.KeyValuePair".
            # Since only a single proto file is currently supported, the root
            # node has the value of the file's package ("pw.protobuf.test").
            # This must be stripped from the path to find the desired node
            # within the tree.
            #
            # TODO(frolv): Once multiple files are supported, the root node
            # should refer to the global namespace, and this should no longer
            # be needed.
            path = field.type_name
            if path[0] == '.':
                path = path[1:]

            if path.startswith(root.name()):
                relative_path = path[len(root.name()):].lstrip('.')
            else:
                relative_path = path

            type_node = root.find(relative_path)
        else:
            type_node = None

        repeated = \
            field.label == descriptor_pb2.FieldDescriptorProto.LABEL_REPEATED
        message.add_field(
            ProtoMessageField(
                field.name,
                field.number,
                field.type,
                type_node,
                repeated,
            ))
예제 #2
0
def add_message_fields(global_root: ProtoNode, package_root: ProtoNode,
                       message: ProtoNode, proto_message) -> None:
    """Adds fields from a protobuf message descriptor to a message node."""
    assert message.type() == ProtoNode.Type.MESSAGE

    for field in proto_message.field:
        if field.type_name:
            # The "type_name" member contains the global .proto path of the
            # field's type object, for example ".pw.protobuf.test.KeyValuePair".
            # Try to find the node for this object within the current context.

            if field.type_name[0] == '.':
                # Fully qualified path.
                root_relative_path = field.type_name[1:]
                search_root = global_root
            else:
                root_relative_path = field.type_name
                search_root = package_root

            type_node = search_root.find(root_relative_path)

            if type_node is None:
                # Create nodes for field types that don't exist within this
                # compilation context, such as those imported from other .proto
                # files.
                type_node = create_external_nodes(search_root,
                                                  root_relative_path)
        else:
            type_node = None

        repeated = \
            field.label == descriptor_pb2.FieldDescriptorProto.LABEL_REPEATED
        message.add_field(
            ProtoMessageField(
                field.name,
                field.number,
                field.type,
                type_node,
                repeated,
            ))