Revert "ctf: Remove the callsite support"
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / event / metadata / IOStructGen.java
CommitLineData
866e5b51 1/*******************************************************************************
3ba65808 2 * Copyright (c) 2011, 2015 Ericsson, Ecole Polytechnique de Montreal and others
866e5b51
FC
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
4311ac8b
MAL
9 * Contributors:
10 * Matthew Khouzam - Initial Design and Grammar
11 * Francis Giraldeau - Initial API and implementation
12 * Simon Marchi - Initial API and implementation
866e5b51
FC
13 *******************************************************************************/
14
f357bcd4 15package org.eclipse.tracecompass.internal.ctf.core.event.metadata;
866e5b51 16
866e5b51 17import java.util.ArrayList;
d45d05a1 18import java.util.Collection;
866e5b51 19import java.util.List;
d45d05a1 20import java.util.stream.Collectors;
866e5b51
FC
21
22import org.antlr.runtime.tree.CommonTree;
a4fa4e36 23import org.eclipse.jdt.annotation.NonNull;
b1ea73b5 24import org.eclipse.tracecompass.common.core.NonNullUtils;
d45d05a1 25import org.eclipse.tracecompass.ctf.core.event.CTFCallsite;
f357bcd4 26import org.eclipse.tracecompass.ctf.core.event.CTFClock;
c8891db9 27import org.eclipse.tracecompass.ctf.core.event.metadata.DeclarationScope;
f357bcd4
AM
28import org.eclipse.tracecompass.ctf.core.trace.CTFTrace;
29import org.eclipse.tracecompass.ctf.parser.CTFParser;
d45d05a1 30import org.eclipse.tracecompass.internal.ctf.core.event.EventDeclaration;
b1ea73b5
MK
31import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.ClockParser;
32import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.TypeAliasParser;
33import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.TypeSpecifierListParser;
34import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.TypedefParser;
d45d05a1 35import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.callsite.CallSiteParser;
b1ea73b5
MK
36import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.environment.EnvironmentParser;
37import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.event.EventParser;
38import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.stream.StreamParser;
39import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.trace.TraceDeclarationParser;
8aa463e0 40import org.eclipse.tracecompass.internal.ctf.core.trace.CTFStream;
866e5b51 41
52f81ef7
MK
42import com.google.common.collect.Iterables;
43
866e5b51 44/**
251274dd 45 * IOStructGen
866e5b51 46 */
866e5b51
FC
47public class IOStructGen {
48
49 // ------------------------------------------------------------------------
50 // Attributes
51 // ------------------------------------------------------------------------
52
866e5b51
FC
53 /**
54 * The trace
55 */
b1ea73b5 56 private final @NonNull CTFTrace fTrace;
9226cfc5 57 private CommonTree fTree;
866e5b51
FC
58
59 /**
60 * The current declaration scope.
61 */
b1ea73b5 62 private final @NonNull DeclarationScope fRoot;
866e5b51 63
58129ff7
MK
64 /**
65 * Data helpers needed for streaming
66 */
67
68 private boolean fHasBeenParsed = false;
69
866e5b51
FC
70 // ------------------------------------------------------------------------
71 // Constructor
72 // ------------------------------------------------------------------------
73
9ac2eb62 74 /**
ecb12461 75 * Constructor
be6df2d8
AM
76 *
77 * @param tree
78 * the tree (ANTLR generated) with the parsed TSDL data.
79 * @param trace
80 * the trace containing the places to put all the read metadata
9ac2eb62 81 */
b1ea73b5 82 public IOStructGen(CommonTree tree, @NonNull CTFTrace trace) {
9226cfc5
MK
83 fTrace = trace;
84 fTree = tree;
b1ea73b5 85 fRoot = NonNullUtils.checkNotNull(trace.getScope());
866e5b51
FC
86 }
87
9ac2eb62
MK
88 /**
89 * Parse the tree and populate the trace defined in the constructor.
be6df2d8 90 *
9ac2eb62 91 * @throws ParseException
be6df2d8 92 * If there was a problem parsing the metadata
9ac2eb62 93 */
866e5b51 94 public void generate() throws ParseException {
9226cfc5 95 parseRoot(fTree);
866e5b51
FC
96 }
97
58129ff7
MK
98 /**
99 * Parse a partial tree and populate the trace defined in the constructor.
100 * Does not check for a "trace" block as there is only one in the trace and
101 * thus
102 *
103 * @throws ParseException
104 * If there was a problem parsing the metadata
105 */
106 public void generateFragment() throws ParseException {
9226cfc5 107 parseIncompleteRoot(fTree);
58129ff7
MK
108 }
109
866e5b51
FC
110 // ------------------------------------------------------------------------
111 // Operations
112 // ------------------------------------------------------------------------
113
58129ff7
MK
114 /**
115 * Sets a new tree to parse
116 *
117 * @param newTree
118 * the new tree to parse
119 */
120 public void setTree(CommonTree newTree) {
9226cfc5 121 fTree = newTree;
58129ff7
MK
122 }
123
866e5b51
FC
124 /**
125 * Parse the root node.
126 *
127 * @param root
128 * A ROOT node.
129 * @throws ParseException
130 */
131 private void parseRoot(CommonTree root) throws ParseException {
866e5b51
FC
132
133 List<CommonTree> children = root.getChildren();
866e5b51
FC
134
135 CommonTree traceNode = null;
52f81ef7 136 boolean hasStreams = false;
3de23137 137 List<CommonTree> events = new ArrayList<>();
d45d05a1 138 Collection<CTFCallsite> callsites = new ArrayList<>();
466f6d95
MK
139 for (CommonTree child : children) {
140 final int type = child.getType();
141 switch (type) {
142 case CTFParser.DECLARATION:
52f81ef7 143 parseRootDeclaration(child);
466f6d95
MK
144 break;
145 case CTFParser.TRACE:
146 if (traceNode != null) {
147 throw new ParseException("Only one trace block is allowed"); //$NON-NLS-1$
866e5b51 148 }
466f6d95 149 traceNode = child;
52f81ef7 150 parseTrace(traceNode);
466f6d95
MK
151 break;
152 case CTFParser.STREAM:
b1ea73b5 153 StreamParser.INSTANCE.parse(child, new StreamParser.Param(fTrace, fRoot));
52f81ef7 154 hasStreams = true;
466f6d95
MK
155 break;
156 case CTFParser.EVENT:
157 events.add(child);
158 break;
159 case CTFParser.CLOCK:
b1ea73b5
MK
160 CTFClock ctfClock = ClockParser.INSTANCE.parse(child, null);
161 String nameValue = ctfClock.getName();
162 fTrace.addClock(nameValue, ctfClock);
466f6d95
MK
163 break;
164 case CTFParser.ENV:
b1ea73b5 165 fTrace.setEnvironment(EnvironmentParser.INSTANCE.parse(child, null));
466f6d95 166 break;
d45d05a1
MK
167 case CTFParser.CALLSITE:
168 callsites.add(CallSiteParser.INSTANCE.parse(child, null));
169 break;
466f6d95 170 default:
4ed7d9c1 171 throw childTypeError(child);
866e5b51 172 }
466f6d95 173 }
466f6d95
MK
174 if (traceNode == null) {
175 throw new ParseException("Missing trace block"); //$NON-NLS-1$
176 }
d45d05a1 177 parseEvents(events, callsites, hasStreams);
52f81ef7
MK
178 fHasBeenParsed = true;
179 }
866e5b51 180
d45d05a1 181 private void parseEvents(List<CommonTree> events, Collection<CTFCallsite> staticCallsites, boolean hasStreams) throws ParseException {
52f81ef7 182 if (!hasStreams && !events.isEmpty()) {
466f6d95
MK
183 /* Add an empty stream that will have a null id */
184 fTrace.addStream(new CTFStream(fTrace));
185 }
466f6d95 186 for (CommonTree event : events) {
d45d05a1
MK
187 EventDeclaration ev = EventParser.INSTANCE.parse(event, new EventParser.Param(fTrace, fRoot));
188 List<CTFCallsite> callsites = staticCallsites.stream().filter(cs -> ev.getName().equals(cs.getEventName())).collect(Collectors.toList());
189 ev.addCallsites(callsites);
190
866e5b51 191 }
58129ff7
MK
192 }
193
194 private void parseIncompleteRoot(CommonTree root) throws ParseException {
466f6d95 195 if (!fHasBeenParsed) {
58129ff7
MK
196 throw new ParseException("You need to run generate first"); //$NON-NLS-1$
197 }
52f81ef7 198 List<CommonTree> children = root.getChildren();
58129ff7 199 List<CommonTree> events = new ArrayList<>();
d45d05a1 200 Collection<CTFCallsite> callsites = new ArrayList<>();
58129ff7
MK
201 for (CommonTree child : children) {
202 final int type = child.getType();
203 switch (type) {
204 case CTFParser.DECLARATION:
52f81ef7 205 parseRootDeclaration(child);
58129ff7
MK
206 break;
207 case CTFParser.TRACE:
208 throw new ParseException("Trace block defined here, please use generate and not generateFragment to parse this fragment"); //$NON-NLS-1$
209 case CTFParser.STREAM:
b1ea73b5 210 StreamParser.INSTANCE.parse(child, new StreamParser.Param(fTrace, fRoot));
58129ff7
MK
211 break;
212 case CTFParser.EVENT:
213 events.add(child);
214 break;
215 case CTFParser.CLOCK:
b1ea73b5
MK
216 CTFClock ctfClock = ClockParser.INSTANCE.parse(child, null);
217 String nameValue = ctfClock.getName();
218 fTrace.addClock(nameValue, ctfClock);
58129ff7
MK
219 break;
220 case CTFParser.ENV:
b1ea73b5 221 fTrace.setEnvironment(EnvironmentParser.INSTANCE.parse(child, null));
58129ff7 222 break;
d45d05a1
MK
223 case CTFParser.CALLSITE:
224 callsites.add(CallSiteParser.INSTANCE.parse(child, null));
225 break;
58129ff7 226 default:
4ed7d9c1 227 throw childTypeError(child);
58129ff7
MK
228 }
229 }
d45d05a1 230 parseEvents(events, callsites, !Iterables.isEmpty(fTrace.getStreams()));
866e5b51
FC
231 }
232
233 private void parseTrace(CommonTree traceNode) throws ParseException {
866e5b51 234
b1ea73b5 235 CTFTrace trace = fTrace;
866e5b51
FC
236 List<CommonTree> children = traceNode.getChildren();
237 if (children == null) {
238 throw new ParseException("Trace block is empty"); //$NON-NLS-1$
239 }
240
866e5b51
FC
241 for (CommonTree child : children) {
242 switch (child.getType()) {
243 case CTFParser.TYPEALIAS:
b1ea73b5 244 TypeAliasParser.INSTANCE.parse(child, new TypeAliasParser.Param(trace, fRoot));
866e5b51
FC
245 break;
246 case CTFParser.TYPEDEF:
b1ea73b5 247 TypedefParser.INSTANCE.parse(child, new TypedefParser.Param(trace, fRoot));
866e5b51
FC
248 break;
249 case CTFParser.CTF_EXPRESSION_TYPE:
250 case CTFParser.CTF_EXPRESSION_VAL:
b1ea73b5 251 TraceDeclarationParser.INSTANCE.parse(child, new TraceDeclarationParser.Param(fTrace, fRoot));
866e5b51
FC
252 break;
253 default:
4ed7d9c1 254 throw childTypeError(child);
866e5b51
FC
255 }
256 }
257
258 /*
259 * If trace byte order was not specified and not using packet based
260 * metadata
261 */
9226cfc5 262 if (fTrace.getByteOrder() == null) {
866e5b51
FC
263 throw new ParseException("Trace byte order not set"); //$NON-NLS-1$
264 }
866e5b51
FC
265 }
266
866e5b51
FC
267 /**
268 * Parses a declaration at the root level.
269 *
270 * @param declaration
271 * The declaration subtree.
272 * @throws ParseException
273 */
274 private void parseRootDeclaration(CommonTree declaration)
275 throws ParseException {
866e5b51
FC
276
277 List<CommonTree> children = declaration.getChildren();
866e5b51
FC
278
279 for (CommonTree child : children) {
280 switch (child.getType()) {
281 case CTFParser.TYPEDEF:
b1ea73b5 282 TypedefParser.INSTANCE.parse(child, new TypedefParser.Param(fTrace, fRoot));
866e5b51
FC
283 break;
284 case CTFParser.TYPEALIAS:
b1ea73b5 285 TypeAliasParser.INSTANCE.parse(child, new TypeAliasParser.Param(fTrace, fRoot));
866e5b51
FC
286 break;
287 case CTFParser.TYPE_SPECIFIER_LIST:
b1ea73b5 288 TypeSpecifierListParser.INSTANCE.parse(child, new TypeSpecifierListParser.Param(fTrace, null, null, fRoot));
866e5b51
FC
289 break;
290 default:
4ed7d9c1 291 throw childTypeError(child);
866e5b51
FC
292 }
293 }
294 }
295
296 /**
b1ea73b5
MK
297 * Throws a ParseException stating that the parent-child relation between
298 * the given node and its parent is not valid. It means that the shape of
299 * the AST is unexpected.
866e5b51 300 *
b1ea73b5
MK
301 * @param child
302 * The invalid child node.
303 * @return ParseException with details
866e5b51 304 */
b1ea73b5
MK
305 private static ParseException childTypeError(CommonTree child) {
306 CommonTree parent = (CommonTree) child.getParent();
307 String error = "Parent " + CTFParser.tokenNames[parent.getType()] //$NON-NLS-1$
308 + " can't have a child of type " //$NON-NLS-1$
309 + CTFParser.tokenNames[child.getType()] + "."; //$NON-NLS-1$
866e5b51 310
4ed7d9c1 311 return new ParseException(error);
866e5b51
FC
312 }
313
866e5b51 314}
This page took 0.119752 seconds and 5 git commands to generate.