]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/GraphCompiler.java
Removed extra debug/timing prints from graph compiler
[simantics/platform.git] / bundles / org.simantics.graph.compiler / src / org / simantics / graph / compiler / GraphCompiler.java
1 package org.simantics.graph.compiler;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.DataInputStream;
6 import java.io.File;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.PrintStream;
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.Formatter;
13 import java.util.Locale;
14 import java.util.TreeMap;
15
16 import org.simantics.databoard.Bindings;
17 import org.simantics.databoard.Files;
18 import org.simantics.databoard.adapter.AdaptException;
19 import org.simantics.databoard.binding.Binding;
20 import org.simantics.databoard.binding.error.BindingException;
21 import org.simantics.databoard.binding.mutable.Variant;
22 import org.simantics.databoard.container.DataContainer;
23 import org.simantics.databoard.container.DataContainers;
24 import org.simantics.graph.compiler.internal.parsing.Parsing;
25 import org.simantics.graph.compiler.internal.procedures.AddConsistsOf;
26 import org.simantics.graph.compiler.internal.procedures.ApplyTemplates;
27 import org.simantics.graph.compiler.internal.procedures.Compactify;
28 import org.simantics.graph.compiler.internal.procedures.ConvertPreValues;
29 import org.simantics.graph.compiler.internal.procedures.CreateInverseRelations;
30 import org.simantics.graph.compiler.internal.procedures.CreateTemplates;
31 import org.simantics.graph.compiler.internal.procedures.DefaultValueTyping;
32 import org.simantics.graph.compiler.internal.procedures.MergeEqualResources;
33 import org.simantics.graph.compiler.internal.procedures.PropagateNewMarks;
34 import org.simantics.graph.compiler.internal.resourceFiles.ResourceFileGenerator;
35 import org.simantics.graph.compiler.internal.store.LocationStore;
36 import org.simantics.graph.compiler.internal.store.VariableStore;
37 import org.simantics.graph.compiler.internal.validation.ReportCollisions;
38 import org.simantics.graph.compiler.internal.validation.ValidateGraph;
39 import org.simantics.graph.query.CompositeGraph;
40 import org.simantics.graph.query.Paths;
41 import org.simantics.graph.query.TransferableGraphConversion;
42 import org.simantics.graph.representation.Extensions;
43 import org.simantics.graph.representation.TransferableGraph1;
44 import org.simantics.graph.store.GraphStore;
45 import org.simantics.ltk.FileSource;
46 import org.simantics.ltk.ISource;
47 import org.simantics.ltk.Location;
48 import org.simantics.ltk.Problem;
49
50 public class GraphCompiler {
51         
52         public static PrintStream out = System.out;
53         
54         public static TransferableGraph1 read(File file) throws Exception {
55                 DataContainer container = DataContainers.readFile(file);
56                 return (TransferableGraph1)container.content.getValue(TransferableGraph1.BINDING);
57         }
58         
59         public static TransferableGraph1 read(InputStream stream) throws AdaptException, IOException {
60                 try (InputStream in = stream) {
61                         DataContainer container = DataContainers.readFile(new DataInputStream(stream));
62                         return (TransferableGraph1)container.content.getValue(TransferableGraph1.BINDING);
63                 }
64         }
65         
66         public static InputStream write(TransferableGraph1 tg) throws BindingException, IOException {
67                 Binding binding = TransferableGraph1.BINDING;
68                 int hashCode = binding.hashValue(tg);
69                 TreeMap<String, Variant> metadata = new TreeMap<>();
70                 metadata.put(Extensions.CACHED_HASHCODE, new Variant(Bindings.INTEGER, hashCode));
71                 byte[] buffer = DataContainers.writeFile(
72                                 new DataContainer("graph", 1, metadata, new Variant(binding, tg))
73                                 );
74                 return new ByteArrayInputStream(buffer);
75         }
76         
77         public static void write(File file, TransferableGraph1 tg) throws BindingException, IOException {
78                 Binding binding = TransferableGraph1.BINDING;
79                 int hashCode = binding.hashValue(tg);
80                 TreeMap<String, Variant> metadata = new TreeMap<>();
81                 metadata.put(Extensions.CACHED_HASHCODE, new Variant(Bindings.INTEGER, hashCode));
82                 DataContainers.writeFile(file, new DataContainer("graph", 1, metadata, new Variant(binding, tg)));
83         }
84         
85         public static CompilationResult compile(
86                 String Layer0Version,
87                         Collection<ISource> sources, 
88                         Collection<TransferableGraph1> dependencies,
89                         ExternalFileLoader fileLoader,
90                         GraphCompilerPreferences preferences) {
91             //out.println(preferences);
92             
93                 Collection<Problem> errors = new ArrayList<Problem>();
94                 GraphStore store = new GraphStore();            
95                 
96                 CompilationResult compilationResult = new CompilationResult();
97                 compilationResult.errors = errors;
98                 compilationResult.warnings = new ArrayList<Problem>();
99                 
100                 Paths paths = new Paths(Layer0Version);
101                 
102                 try {                   
103                         run(new Parsing(paths, sources, errors, store));
104                         
105                         if(!errors.isEmpty())
106                                 return compilationResult;
107         
108                         // Create composite graph of the new statements and dependencies
109                         CompositeGraph graph;
110                         {
111                                 long beginTime = System.nanoTime();
112                                 graph = TransferableGraphConversion.convert(paths, dependencies);
113                                 graph.addFragment(store);               
114                                 long endTime = System.nanoTime();
115                                 reportTime("Composition", beginTime, endTime);
116                         }
117         
118                         // Procedures
119                         run(new MergeEqualResources(paths, store));
120                         {
121                             int[] unfoundedIdentitities = store.identities.getUnfoundedIdentities();
122                             if(unfoundedIdentitities.length > 0) {
123                                 LocationStore locations = store.getStore(LocationStore.class);
124                                 for(int id : unfoundedIdentitities) {
125                                     errors.add(new Problem(
126                                             locations.getLocation(id), 
127                                             "URIless resource used as a parent."));
128                                 }
129                                 return compilationResult;
130                             }
131                         }                           
132                         store.identities.createPathToId(paths.ConsistsOf);
133                         run(new CreateTemplates(graph, store, errors));
134                         run(new ApplyTemplates(graph, store, errors, fileLoader));
135                         run(new DefaultValueTyping(paths, store));              
136                         run(new Compactify(store));                        
137                         run(new PropagateNewMarks(store));                      
138                         run(new CreateInverseRelations(graph, store));
139                         run(new AddConsistsOf(paths, store));
140                         run(new ConvertPreValues(graph, store, errors));
141                         run(new ReportCollisions(preferences, errors, store));
142                         if(preferences.validate)
143                                 run(new ValidateGraph(graph, errors, store, preferences));
144                         
145                         // Create the result
146                         {
147                                 long beginTime = System.nanoTime();
148                                 compilationResult.graph = TransferableGraphConversion.convert(graph, store);                            
149                                 long endTime = System.nanoTime();
150                                 reportTime("Generate TG", beginTime, endTime);
151                         }
152                         
153                         // Create resource files        
154                         {
155                                 long beginTime = System.nanoTime();
156                                 compilationResult.resourceFiles = ResourceFileGenerator.generate(paths, store);         
157                                 long endTime = System.nanoTime();
158                                 reportTime("Generate resources", beginTime, endTime);
159                         }
160                         
161                         // Create source info
162                         {
163                                 VariableStore variableStore = store.getStore(VariableStore.class);
164                                 compilationResult.sourceInfo = variableStore.getSourceInfo();
165                         }
166                         
167                         // Fix source location of problems whose location is null at this point
168
169                         for(Problem problem : compilationResult.errors) {
170                                 if(problem.getLocation() == null)
171                                         for(ISource source : sources) {
172                                                 problem.setLocation(new Location(source));
173                                                 break;
174                                         }
175                                 else if(problem.getLocation().getSource() == null)
176                                         for(ISource source : sources) {
177                                                 problem.getLocation().setSource(source);
178                                                 break;
179                                         }
180                         }
181                         for(Problem problem : compilationResult.warnings) {
182                                 if(problem.getLocation() == null)
183                                         for(ISource source : sources) {
184                                                 problem.setLocation(new Location(source));
185                                                 break;
186                                         }
187                                 else if(problem.getLocation().getSource() == null)
188                                         for(ISource source : sources) {
189                                                 problem.getLocation().setSource(source);
190                                                 break;
191                                         }
192                         }
193                         
194                 } catch(Exception e) {
195                         e.printStackTrace();
196                         ByteArrayOutputStream stream = new ByteArrayOutputStream();
197                         e.printStackTrace(new PrintStream(stream));
198                         String description = "Internal error: " +
199                                 new String(stream.toByteArray());
200                         for(ISource source : sources)           
201                                 errors.add(new Problem(new Location(source), description));
202                 }
203                 
204                 return compilationResult;
205         }
206         
207         private static void run(Runnable runnable) {
208                 //long beginTime = System.nanoTime();
209                 runnable.run();
210                 //long endTime = System.nanoTime();
211                 
212                 //reportTime(runnable.getClass().getSimpleName(), beginTime, endTime);
213         }
214         
215         public static void reportTime(String taskName, long beginTime, long endTime) {
216                 StringBuilder sb = new StringBuilder();
217                 @SuppressWarnings("resource")
218                 Formatter formatter = new Formatter(sb, Locale.US);
219                 formatter.format("%-25s %8.4f ms", taskName, (endTime - beginTime)*1e-6);
220
221                 out.println(sb.toString());
222         }
223         
224         public static void reportTime(String taskName, long beginTime) {
225                 reportTime(taskName, beginTime, System.nanoTime());
226         }
227         
228         public static void main(String[] args) {
229                 Collection<ISource> sources = new ArrayList<ISource>();
230                 Collection<TransferableGraph1> dependencies = new ArrayList<TransferableGraph1>();
231                 String outputFile = null;
232                 
233                 for(int i=0;i<args.length;++i) {
234                         String arg = args[i];
235                         if(arg.equals("-o")) {
236                                 if(++i < args.length)
237                                         outputFile = args[i];
238                         }
239                         else {
240                                 if(arg.endsWith(".tg")) {
241                                         try {
242                                                 dependencies.add(read(new File(arg)));
243                                         } catch (Exception e) {
244                                                 e.printStackTrace();
245                                                 return;
246                                         }
247                                 }
248                                 else if(arg.endsWith(".graph") || arg.endsWith(".pgraph")) {
249                                         sources.add(new FileSource(arg));
250                                 }
251                                 else {
252                                         System.err.println("Invalid input file extension " + arg);
253                                         return;
254                                 }
255                         }
256                 }
257                 
258                 if(sources.isEmpty()) {
259                         System.err.println("No source files");
260                         return;
261                 }
262                 
263                 if(outputFile == null) {
264                         System.err.println("Name of the output file is not given (use -o flag).");
265                         return;
266                 }
267                 
268                 CompilationResult result = compile("1.0", sources, dependencies, null, new GraphCompilerPreferences());
269                 for(Problem problem : result.getErrors())
270                         out.println(problem.getLocation() + ": " + problem.getDescription());
271                 
272                 if(result.getGraph() != null)
273                         try {
274                                 Files.createFile(new File(outputFile), TransferableGraph1.BINDING, result.getGraph());
275                         } catch (Exception e) {
276                                 e.printStackTrace();
277                                 return;
278                         }
279         }
280         
281 }