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, ))
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, ))