use of org.antlr.v4.codegen.model.ModelElement in project antlr4 by antlr.
the class OutputModelWalker method walk.
public ST walk(OutputModelObject omo, boolean header) {
// CREATE TEMPLATE FOR THIS OUTPUT OBJECT
Class<? extends OutputModelObject> cl = omo.getClass();
String templateName = cl.getSimpleName();
if (templateName == null) {
tool.errMgr.toolError(ErrorType.NO_MODEL_TO_TEMPLATE_MAPPING, cl.getSimpleName());
return new ST("[" + templateName + " invalid]");
}
if (header)
templateName += "Header";
ST st = templates.getInstanceOf(templateName);
if (st == null) {
tool.errMgr.toolError(ErrorType.CODE_GEN_TEMPLATES_INCOMPLETE, templateName);
return new ST("[" + templateName + " invalid]");
}
if (st.impl.formalArguments == null) {
tool.errMgr.toolError(ErrorType.CODE_TEMPLATE_ARG_ISSUE, templateName, "<none>");
return st;
}
Map<String, FormalArgument> formalArgs = st.impl.formalArguments;
// PASS IN OUTPUT MODEL OBJECT TO TEMPLATE AS FIRST ARG
Set<String> argNames = formalArgs.keySet();
Iterator<String> arg_it = argNames.iterator();
// ordered so this is first arg
String modelArgName = arg_it.next();
st.add(modelArgName, omo);
// COMPUTE STs FOR EACH NESTED MODEL OBJECT MARKED WITH @ModelElement AND MAKE ST ATTRIBUTE
Set<String> usedFieldNames = new HashSet<String>();
Field[] fields = cl.getFields();
for (Field fi : fields) {
ModelElement annotation = fi.getAnnotation(ModelElement.class);
if (annotation == null) {
continue;
}
String fieldName = fi.getName();
if (!usedFieldNames.add(fieldName)) {
tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "Model object " + omo.getClass().getSimpleName() + " has multiple fields named '" + fieldName + "'");
continue;
}
// Just don't set @ModelElement fields w/o formal arg in target ST
if (formalArgs.get(fieldName) == null)
continue;
try {
Object o = fi.get(omo);
if (o instanceof OutputModelObject) {
// SINGLE MODEL OBJECT?
OutputModelObject nestedOmo = (OutputModelObject) o;
ST nestedST = walk(nestedOmo, header);
// System.out.println("set ModelElement "+fieldName+"="+nestedST+" in "+templateName);
st.add(fieldName, nestedST);
} else if (o instanceof Collection || o instanceof OutputModelObject[]) {
// LIST OF MODEL OBJECTS?
if (o instanceof OutputModelObject[]) {
o = Arrays.asList((OutputModelObject[]) o);
}
Collection<?> nestedOmos = (Collection<?>) o;
for (Object nestedOmo : nestedOmos) {
if (nestedOmo == null)
continue;
ST nestedST = walk((OutputModelObject) nestedOmo, header);
// System.out.println("set ModelElement "+fieldName+"="+nestedST+" in "+templateName);
st.add(fieldName, nestedST);
}
} else if (o instanceof Map) {
Map<?, ?> nestedOmoMap = (Map<?, ?>) o;
Map<Object, ST> m = new LinkedHashMap<Object, ST>();
for (Map.Entry<?, ?> entry : nestedOmoMap.entrySet()) {
ST nestedST = walk((OutputModelObject) entry.getValue(), header);
// System.out.println("set ModelElement "+fieldName+"="+nestedST+" in "+templateName);
m.put(entry.getKey(), nestedST);
}
st.add(fieldName, m);
} else if (o != null) {
tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "not recognized nested model element: " + fieldName);
}
} catch (IllegalAccessException iae) {
tool.errMgr.toolError(ErrorType.CODE_TEMPLATE_ARG_ISSUE, templateName, fieldName);
}
}
//st.impl.dump();
return st;
}
Aggregations