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 {@code obj} to graph, if possible. If the given object <code>obj</code> can be seen as 42 * a graph or sub-graph of a graph, then return the properly typed instance. Otherwise return 43 * <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 {@code node}. Each node in the graph is uniquely identified by an integer value. If two 73 * nodes 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 a node for {@code obj}, if possible. If the given object <code>obj</code> can be seen 100 * as an instance of node return the properly typed instance of the node class. Otherwise return 101 * <code>null</code>. 102 * 103 * @param obj an object to find node for 104 * @return appropriate graph object or <code>null</code> if the object doesn't represent a node 105 */ 106 N node(Object obj); 107 108 /** 109 * Finds a node class for {@code obj}, if possible. If the given object <code>obj</code> can be 110 * seen as an instance of node class return the properly typed instance of the node class. 111 * Otherwise return <code>null</code>. 112 * 113 * @param obj an object to find node class for 114 * @return appropriate graph object or <code>null</code> if the object doesn't represent a node 115 * class 116 */ 117 C nodeClass(Object obj); 118 119 /** 120 * Finds a node class for {@code node}. 121 * 122 * @param node an instance of node in this graph 123 * @return the node's node class, never <code>null</code> 124 */ 125 C classForNode(N node); 126 127 /** 128 * The template used to build the name of nodes of this class. The template may use references 129 * to inputs ({i#inputName}) and its properties ({p#propertyName}). 130 * 131 * @param nodeClass the node class to find name template for 132 * @return the string representing the template 133 */ 134 String nameTemplate(C nodeClass); 135 136 /** 137 * Java class for a node class. 138 * 139 * @param nodeClass the node class 140 * @return the {@link Class} or other type representation of the node class 141 */ 142 Object nodeClassType(C nodeClass); 143 144 /** 145 * Input ports of a node class. Each node class has a fixed set of ports where individual edges 146 * can attach to. 147 * 148 * @param nodeClass the node class 149 * @return input ports for the node class 150 */ 151 P portInputs(C nodeClass); 152 153 /** 154 * Output ports of a node class. Each node class has a fixed set of ports from where individual 155 * edges can point to other nodes. 156 * 157 * @param nodeClass the node class 158 * @return output ports for the node class 159 */ 160 P portOutputs(C nodeClass); 161 162 /** 163 * The number of edges in a port. The protocol will then call methods 164 * {@link #edgeDirect(java.lang.Object, int)}, {@link #edgeName(java.lang.Object, int)}, 165 * {@link #edgeType(java.lang.Object, int)} and 166 * {@link #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int)} for indexes 167 * from <code>0</code> to <code>portSize - 1</code> 168 * 169 * @param port the port 170 * @return number of edges in this port 171 */ 172 int portSize(P port); 173 174 /** 175 * Checks whether an edge is direct. Direct edge shall have exactly one 176 * {@linkplain #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int) node} - it 177 * is an error to return more than one for such an edge from the 178 * {@linkplain #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int) method}. 179 * 180 * @param port the port 181 * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus 182 * <code>1</code> 183 * @return <code>true</code> if only one node can be returned from 184 * {@link #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int)} method 185 */ 186 boolean edgeDirect(P port, int index); 187 188 /** 189 * The name of an edge. 190 * 191 * @param port the port 192 * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus 193 * <code>1</code> 194 * @return the name of the edge 195 */ 196 String edgeName(P port, int index); 197 198 /** 199 * Type of an edge. The type must be a graph 200 * <q>enum</q> - e.g. either real instance of {@link Enum} subclass, or something that the 201 * {@link GraphOutput.Builder} can recognize as 202 * <q>enum</q>. 203 * 204 * @param port 205 * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus 206 * <code>1</code> 207 * @return any {@link Enum} representing type of the edge 208 */ 209 Object edgeType(P port, int index); 210 211 /** 212 * Nodes where the edges for a port lead to/from. This method is called for both 213 * {@link #edgeDirect(java.lang.Object, int) direct/non-direct edges}. In case of a direct edge 214 * the returned collection must have exactly one element. 215 * 216 * @param graph the graph 217 * @param node the node in the graph 218 * @param port port of the node class 219 * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus 220 * <code>1</code> 221 * @return <code>null</code> if there are no edges associated with given port or collection of 222 * nodes where to/from the edges lead to 223 */ 224 Collection<? extends N> edgeNodes(G graph, N node, P port, int index); 225 }