1 /*
   2  * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.graphio;
  24 
  25 import java.util.Collection;
  26 import java.util.Map;
  27 
  28 /**
  29  * Interface that defines structure of a compiler graph. The structure of a graph is composed from
  30  * nodes with properties, the classes of individual nodes, and ports associated with each node that
  31  * may contain edges to other nodes. The structure of a graph is assumed to be immutable for the
  32  * time of {@link GraphOutput operations} on it.
  33  *
  34  * @param <G> the type of the (root node of a) graph
  35  * @param <N> the type of nodes
  36  * @param <C> the type of node classes
  37  * @param <P> the type of node ports
  38  */
  39 public interface GraphStructure<G, N, C, P> {
  40     /**
  41      * Casts the provided object to graph, if possible. If the given object <code>obj</code> can be
  42      * seen as a graph or sub-graph of a graph, then return the properly typed instance. Otherwise
  43      * return <code>null</code>
  44      *
  45      * @param currentGraph the currently processed graph
  46      * @param obj an object to check and view as a graph
  47      * @return appropriate graph object or <code>null</code> if the object doesn't represent a graph
  48      */
  49     G graph(G currentGraph, Object obj);
  50 
  51     /**
  52      * Nodes of a graph. Each graph is composed from a fixed set of nodes. This method returns an
  53      * iterable which provides access to all of them - the number of nodes provided by the iterable
  54      * must match the number returned by {@link #nodesCount(java.lang.Object)} method.
  55      *
  56      * @see #nodesCount(java.lang.Object)
  57      * @param graph the graph to query for nodes
  58      * @return iterable with all the graph's nodes
  59      */
  60     Iterable<? extends N> nodes(G graph);
  61 
  62     /**
  63      * Number of nodes in a graph. The number must match the content returned by
  64      * {@link #nodes(java.lang.Object)} method.
  65      *
  66      * @param graph the graph to query
  67      * @return the number of nodes that will be returned by {@link #nodes(java.lang.Object)}
  68      */
  69     int nodesCount(G graph);
  70 
  71     /**
  72      * Id of a node. Each node in the graph is uniquely identified by a integer value. If two nodes
  73      * have the same id, then they shall be <code>==</code> to each other.
  74      *
  75      * @param node the node to query for an id
  76      * @return the id of the node
  77      */
  78     int nodeId(N node);
  79 
  80     /**
  81      * Checks if there is a predecessor for a node.
  82      *
  83      * @param node the node to check
  84      * @return <code>true</code> if it has a predecessor, <code>false</code> otherwise
  85      */
  86     boolean nodeHasPredecessor(N node);
  87 
  88     /**
  89      * Collects node properties. Each node can be associated with additional properties identified
  90      * by their name. This method shall copy them into the provided map.
  91      *
  92      * @param graph the current graph
  93      * @param node the node to collect properties for
  94      * @param properties the map to put the properties to
  95      */
  96     void nodeProperties(G graph, N node, Map<String, ? super Object> properties);
  97 
  98     /**
  99      * Finds the node class for the provided object, if possible. If the given object
 100      * <code>obj</code> can be seen as an instance of node class or it is a node in this graph,
 101      * return the properly typed instance of the node class. Otherwise return <code>null</code>
 102      *
 103      * @param obj an object to find node class for
 104      * @return appropriate graph object or <code>null</code> if the object doesn't represent a graph
 105      */
 106     C nodeClass(Object obj);
 107 
 108     /**
 109      * The template used to build the name of nodes of this class. The template may use references
 110      * to inputs ({i#inputName}) and its properties ({p#propertyName}).
 111      *
 112      * @param nodeClass the node class to find name template for
 113      * @return the string representing the template
 114      */
 115     String nameTemplate(C nodeClass);
 116 
 117     /**
 118      * Java class for a node class.
 119      *
 120      * @param nodeClass the node class
 121      * @return the {@link Class} or other type representation of the node class
 122      */
 123     Object nodeClassType(C nodeClass);
 124 
 125     /**
 126      * Input ports of a node class. Each node class has a fixed set of ports where individual edges
 127      * can attach to.
 128      *
 129      * @param nodeClass the node class
 130      * @return input ports for the node class
 131      */
 132     P portInputs(C nodeClass);
 133 
 134     /**
 135      * Output ports of a node class. Each node class has a fixed set of ports from where individual
 136      * edges can point to other nodes.
 137      *
 138      * @param nodeClass the node class
 139      * @return output ports for the node class
 140      */
 141     P portOutputs(C nodeClass);
 142 
 143     /**
 144      * The number of edges in a port. The protocol will then call methods
 145      * {@link #edgeDirect(java.lang.Object, int)}, {@link #edgeName(java.lang.Object, int)},
 146      * {@link #edgeType(java.lang.Object, int)} and
 147      * {@link #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int)} for indexes
 148      * from <code>0</code> to <code>portSize - 1</code>
 149      *
 150      * @param port the port
 151      * @return number of edges in this port
 152      */
 153     int portSize(P port);
 154 
 155     /**
 156      * Checks whether an edge is direct. Direct edge shall have exactly one
 157      * {@linkplain #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int) node} - it
 158      * is an error to return more than one for such an edge from the
 159      * {@linkplain #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int) method}.
 160      *
 161      * @param port the port
 162      * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus
 163      *            <code>1</code>
 164      * @return <code>true</code> if only one node can be returned from
 165      *         {@link #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int)} method
 166      */
 167     boolean edgeDirect(P port, int index);
 168 
 169     /**
 170      * The name of an edge.
 171      *
 172      * @param port the port
 173      * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus
 174      *            <code>1</code>
 175      * @return the name of the edge
 176      */
 177     String edgeName(P port, int index);
 178 
 179     /**
 180      * Type of an edge. The type must be a graph
 181      * <q>enum</q> - e.g. either real instance of {@link Enum} subclass, or something that the
 182      * {@link GraphOutput.Builder} can recognize as
 183      * <q>enum</q>.
 184      *
 185      * @param port
 186      * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus
 187      *            <code>1</code>
 188      * @return any {@link Enum} representing type of the edge
 189      */
 190     Object edgeType(P port, int index);
 191 
 192     /**
 193      * Nodes where the edges for a port lead to/from. This method is called for both
 194      * {@link #edgeDirect(java.lang.Object, int) direct/non-direct edges}. In case of a direct edge
 195      * the returned collection must have exactly one element.
 196      *
 197      * @param graph the graph
 198      * @param node the node in the graph
 199      * @param port port of the node class
 200      * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus
 201      *            <code>1</code>
 202      * @return <code>null</code> if there are no edges associated with given port or collection of
 203      *         nodes where to/from the edges lead to
 204      */
 205     Collection<? extends N> edgeNodes(G graph, N node, P port, int index);
 206 }