| /******************************************************************************* |
| * Copyright (c) 2015 Ericsson |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| *******************************************************************************/ |
| package org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.event; |
| |
| import static org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.TsdlUtils.concatenateUnaryStrings; |
| |
| import java.util.List; |
| |
| import org.antlr.runtime.tree.CommonTree; |
| import org.eclipse.jdt.annotation.NonNullByDefault; |
| import org.eclipse.tracecompass.ctf.parser.CTFParser; |
| import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ICommonTreeParser; |
| import org.eclipse.tracecompass.internal.ctf.core.event.metadata.MetadataStrings; |
| import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ParseException; |
| |
| /** |
| * A local static scope consists in the scope generated by the declaration of |
| * fields within a compound type. A static scope is a local static scope |
| * augmented with the nested sub-static-scopes it contains. |
| * <p> |
| * A dynamic scope consists in the static scope augmented with the implicit |
| * event structure definition hierarchy. |
| * <p> |
| * Multiple declarations of the same field name within a local static scope is |
| * not valid. It is however valid to re-use the same field name in different |
| * local scopes. |
| * <p> |
| * Nested static and dynamic scopes form lookup paths. These are used for |
| * variant tag and sequence length references. They are used at the variant and |
| * sequence definition site to look up the location of the tag field associated |
| * with a variant, and to lookup up the location of the length field associated |
| * with a sequence. |
| * <p> |
| * Variants and sequences can refer to a tag field either using a relative path |
| * or an absolute path. The relative path is relative to the scope in which the |
| * variant or sequence performing the lookup is located. Relative paths are only |
| * allowed to lookup within the same static scope, which includes its nested |
| * static scopes. Lookups targeting parent static scopes need to be performed |
| * with an absolute path. |
| * <p> |
| * Absolute path lookups use the full path including the dynamic scope followed |
| * by a . and then the static scope. Therefore, variants (or sequences) in lower |
| * levels in the dynamic scope (e.g., event context) can refer to a tag (or |
| * length) field located in upper levels (e.g., in the event header) by |
| * specifying, in this case, the associated tag with |
| * <stream.event.header.field_name>. This allows, for instance, the event |
| * context to define a variant referring to the id field of the event header as |
| * selector. |
| * <p> |
| * The dynamic scope prefixes are thus: |
| * <ul> |
| * <li>Trace environment: <env. ></li> |
| * <li>Trace packet header: <trace.packet.header. ></li> |
| * <li>Stream packet context: <stream.packet.context. ></li> |
| * <li>Event header: <stream.event.header. ></li> |
| * <li>Stream event context: <stream.event.context. ></li> |
| * <li>Event context: <event.context. ></li> |
| * <li>Event payload: <event.fields. ></li> |
| * </ul> |
| * <p> |
| * The target dynamic scope must be specified explicitly when referring to a |
| * field outside of the static scope (absolute scope reference). No conflict can |
| * occur between relative and dynamic paths, because the keywords trace, stream, |
| * and event are reserved, and thus not permitted as field names. It is |
| * recommended that field names clashing with CTF and C99 reserved keywords use |
| * an underscore prefix to eliminate the risk of generating a description |
| * containing an invalid field name. Consequently, fields starting with an |
| * underscore should have their leading underscore removed by the CTF trace |
| * readers. |
| * <p> |
| * The information available in the dynamic scopes can be thought of as the |
| * current tracing context. At trace production, information about the current |
| * context is saved into the specified scope field levels. At trace consumption, |
| * for each event, the current trace context is therefore readable by accessing |
| * the upper dynamic scopes. |
| * |
| * @author Matthew Khouzam - Initial API and implementation |
| * @author Efficios - Description |
| * |
| */ |
| public final class EventScopeParser implements ICommonTreeParser { |
| |
| /** |
| * Parameter object containing a list of common trees |
| * |
| * @author Matthew Khouzam |
| * |
| */ |
| @NonNullByDefault |
| public static final class Param implements ICommonTreeParserParameter { |
| private final List<CommonTree> fList; |
| |
| /** |
| * Constructor |
| * |
| * @param list |
| * parameter list |
| */ |
| public Param(List<CommonTree> list) { |
| fList = list; |
| |
| } |
| |
| } |
| |
| /** |
| * Instance |
| */ |
| public static final EventScopeParser INSTANCE = new EventScopeParser(); |
| |
| private EventScopeParser() { |
| } |
| |
| /** |
| * Parses in a different way, the AST node is unused, and the event list |
| * contains data to read. This converts a scope from a set of strings to |
| * "event.subscope1.subscope2". |
| * |
| * @param unused |
| * unused AST node |
| * @param param |
| * a list of tree nodes that contain the scope description. |
| * @return a concatenated string of the scope |
| */ |
| @Override |
| public String parse(CommonTree unused, ICommonTreeParserParameter param) throws ParseException { |
| if (!(param instanceof Param)) { |
| throw new IllegalArgumentException("Param must be a " + Param.class.getCanonicalName()); //$NON-NLS-1$ |
| } |
| List<CommonTree> lengthChildren = ((Param) param).fList; |
| CommonTree nextElem = (CommonTree) lengthChildren.get(1).getChild(0); |
| String lengthName; |
| switch (nextElem.getType()) { |
| case CTFParser.UNARY_EXPRESSION_STRING: |
| case CTFParser.IDENTIFIER: |
| List<CommonTree> sublist = lengthChildren.subList(1, lengthChildren.size()); |
| lengthName = MetadataStrings.EVENT + '.' + concatenateUnaryStrings(sublist); |
| break; |
| default: |
| throw new ParseException("Unsupported scope event." + nextElem); //$NON-NLS-1$ |
| } |
| return lengthName; |
| } |
| |
| } |