Skip to content

Commit

Permalink
ctf.core: Support field class alias in CTF2 Metadata
Browse files Browse the repository at this point in the history
Allow field-class-alias fragments in root metadata node.

Add new class FieldClass to be used instead of JsonObject. Create and
register a FieldClassDeserializer that will accept a JSON Object as a
field class or a JSON String as a field class alias and lookup a
previously occurring field class alias with that name.

Support a string as a field class alias in TypeAliasParser and lookup a
previously occurring field class alias with that name in the Metadata
root.

[Added] Support field class alias in CTF2 Metadata

Change-Id: I7a7cf52a1ce36ba726ba2ab568ed6e9b9cfc4803
Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/c/tracecompass/org.eclipse.tracecompass/+/204823
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
  • Loading branch information
PatrickTasse committed Oct 10, 2023
1 parent 01c87e9 commit 32f3220
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 10 deletions.
Expand Up @@ -53,6 +53,8 @@
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.CTFAntlrMetadataNode;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.CTFJsonMetadataNode;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.CtfAntlrException;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.FieldClass;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.FieldClass.FieldClassDeserializer;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.IOStructGen;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.JsonClockMetadataNode;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.JsonDataStreamMetadataNode;
Expand Down Expand Up @@ -234,11 +236,12 @@ public void parseJsonFile() throws CTFException {
* @since 4.1
*/
private static ICTFMetadataNode parseJsonToTree(String json) throws CTFException {
String[] jsonBlocks = json.split("\u001e"); //$NON-NLS-1$
ICTFMetadataNode root = new CTFJsonMetadataNode(null, CTFParser.tokenNames[CTFParser.ROOT], null);
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(FieldClass.class, new FieldClassDeserializer(root));
Gson gson = builder.create();
ICTFMetadataNode root = new CTFJsonMetadataNode(null, CTFParser.tokenNames[CTFParser.ROOT], null);

String[] jsonBlocks = json.split("\u001e"); //$NON-NLS-1$
for (int i = 1; i < jsonBlocks.length; i++) {
ICTFMetadataNode fragment;
try {
Expand Down
@@ -0,0 +1,94 @@
/*******************************************************************************
* Copyright (c) 2023 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
*
* Contributors:
* Patrick Tasse - Initial implementation
*******************************************************************************/
package org.eclipse.tracecompass.internal.ctf.core.event.metadata;

import java.lang.reflect.Type;

import org.eclipse.tracecompass.internal.ctf.core.event.types.ICTFMetadataNode;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;

/**
* Class that stores a field class property, which can be a JSON object or a
* string referring to a field class alias.
*/
public class FieldClass {

private final JsonObject fFieldClass;

/**
* Field class deserializer
*/
public static class FieldClassDeserializer implements JsonDeserializer<FieldClass> {
private final ICTFMetadataNode fRoot;

/**
* Constructor
*
* @param root
* the CTF metadata root node
*/
public FieldClassDeserializer(ICTFMetadataNode root) {
fRoot = root;
}

@Override
public FieldClass deserialize(JsonElement jElement, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
if (jElement.isJsonPrimitive()) {
JsonPrimitive jPrimitive = jElement.getAsJsonPrimitive();
if (jPrimitive.isString()) {
String fieldClassAlias = jPrimitive.getAsString();
for (ICTFMetadataNode node : fRoot.getChildren()) {
if (node instanceof JsonFieldClassAliasMetadataNode) {
JsonFieldClassAliasMetadataNode fieldClassAliasNode = (JsonFieldClassAliasMetadataNode) node;
if (fieldClassAliasNode.getName().equals(fieldClassAlias)) {
return new FieldClass(fieldClassAliasNode.getFieldClass());
}
}
}
throw new JsonParseException("no previously occurring field class alias named '" + fieldClassAlias + '\''); //$NON-NLS-1$
}
} else if (jElement.isJsonObject()) {
JsonObject jObject = jElement.getAsJsonObject();
return new FieldClass(jObject);
}
throw new JsonParseException("field-class property is not a JSON object or JSON string"); //$NON-NLS-1$
}
}

/**
* Constructor
*
* @param fieldClass
* the field class JSON object
*/
public FieldClass(JsonObject fieldClass) {
fFieldClass = fieldClass;
}

/**
* Get the field class as a JSON object
*
* @return the field class
*/
public JsonObject getFieldClass() {
return fFieldClass;
}
}
Expand Up @@ -167,6 +167,8 @@ private void parseRoot(ICTFMetadataNode root) throws ParseException {
} else if (JsonMetadataStrings.FRAGMENT_PREAMBLE.equals(type)) {
// FIXME: support Preamble fragment (CTF2 spec 5.5)
// https://diamon.org/ctf/files/CTF2-SPECRC-7.0rA.html#preamble-frag
} else if (JsonMetadataStrings.FRAGMENT_FIELD_ALIAS.equals(type)) {
// nothing to do
} else {
throw childTypeError(child);
}
Expand Down
Expand Up @@ -29,7 +29,7 @@ public class JsonFieldClassAliasMetadataNode extends CTFJsonMetadataNode {
@SerializedName("name")
private final String fName;
@SerializedName("field-class")
private final JsonObject fFieldClass;
private final FieldClass fFieldClass;

/**
* Constructor for a JsonFieldClassAliasMetadataNode
Expand All @@ -45,7 +45,7 @@ public class JsonFieldClassAliasMetadataNode extends CTFJsonMetadataNode {
* @param fieldClass
* the field class described by this new node
*/
public JsonFieldClassAliasMetadataNode(ICTFMetadataNode parent, String type, String value, String name, JsonObject fieldClass) {
public JsonFieldClassAliasMetadataNode(ICTFMetadataNode parent, String type, String value, String name, FieldClass fieldClass) {
super(parent, type, value);
this.fName = name;
this.fFieldClass = fieldClass;
Expand All @@ -66,7 +66,7 @@ public String getName() {
* @return the field class
*/
public JsonObject getFieldClass() {
return fFieldClass;
return fFieldClass.getFieldClass();
}

}
Expand Up @@ -21,6 +21,7 @@
import org.eclipse.tracecompass.ctf.core.trace.CTFTrace;
import org.eclipse.tracecompass.ctf.parser.CTFParser;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.AbstractScopedCommonTreeParser;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.JsonFieldClassAliasMetadataNode;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.JsonStructureFieldMemberMetadataNode;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ParseException;
import org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl.enumeration.EnumParser;
Expand All @@ -30,7 +31,9 @@
import org.eclipse.tracecompass.internal.ctf.core.event.types.ICTFMetadataNode;
import org.eclipse.tracecompass.internal.ctf.core.utils.JsonMetadataStrings;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;

/**
* The "typealias" declaration can be used to give a name (including pointer
Expand Down Expand Up @@ -94,13 +97,43 @@ public IDeclaration parse(ICTFMetadataNode typealias, ICommonTreeParserParameter
IDeclaration targetDeclaration = null;
CTFTrace trace = ((Param) param).fTrace;

String aliasString;
String aliasString = null;
if (typealias instanceof JsonStructureFieldMemberMetadataNode) {
JsonStructureFieldMemberMetadataNode member = ((JsonStructureFieldMemberMetadataNode) typealias);
aliasString = member.getName();
String type = typealias.getType();
JsonObject fieldClass = null;
if (member.getFieldClass().isJsonObject()) {
JsonObject fieldClass = member.getFieldClass().getAsJsonObject();
fieldClass = member.getFieldClass().getAsJsonObject();
aliasString = member.getName();
type = member.getType();
} else if (member.getFieldClass().isJsonPrimitive()) {
JsonPrimitive jPrimitive = member.getFieldClass().getAsJsonPrimitive();
if (jPrimitive.isString()) {
String fieldClassAlias = jPrimitive.getAsString();
ICTFMetadataNode root = member;
while (root.getParent() != null) {
root = root.getParent();
}
for (ICTFMetadataNode node : root.getChildren()) {
if (node instanceof JsonFieldClassAliasMetadataNode) {
JsonFieldClassAliasMetadataNode aliasMetadataNode = (JsonFieldClassAliasMetadataNode) node;
if (aliasMetadataNode.getName().equals(fieldClassAlias)) {
fieldClass = aliasMetadataNode.getFieldClass();
aliasString = aliasMetadataNode.getName();
JsonElement typeMember = fieldClass.get(JsonMetadataStrings.TYPE);
if (typeMember != null && typeMember.isJsonPrimitive()) {
type = typeMember.getAsString();
}
break;
}
}
}
if (fieldClass == null) {
throw new ParseException("no previously occurring field class alias named '" + fieldClassAlias + '\''); //$NON-NLS-1$
}
}
}
if (fieldClass != null) {
if (JsonMetadataStrings.FIXED_UNSIGNED_INTEGER_FIELD.equals(type)) {
fieldClass.addProperty(SIGNED, false);
targetDeclaration = IntegerDeclarationParser.INSTANCE.parse(typealias, new IntegerDeclarationParser.Param(trace));
Expand All @@ -119,8 +152,7 @@ public IDeclaration parse(ICTFMetadataNode typealias, ICommonTreeParserParameter
throw new ParseException("Invalid field class: " + type); //$NON-NLS-1$
}
} else {
// TODO: Implement parsing of field class aliases
throw new ParseException("Field classes that are not Json Objects are not yet supported"); //$NON-NLS-1$
throw new ParseException("field-class property is not a JSON object or JSON string"); //$NON-NLS-1$
}
} else {
for (ICTFMetadataNode child : children) {
Expand Down

0 comments on commit 32f3220

Please sign in to comment.