/*******************************************************************************
* Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package com.cisco.yangide.core.parser;
import java.util.Stack;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.opendaylight.yangtools.antlrv4.code.gen.YangLexer;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Anyxml_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Augment_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Base_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Belongs_to_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Case_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Choice_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Config_argContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Config_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Contact_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Container_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Default_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Description_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviation_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Extension_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Feature_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Grouping_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Identity_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Include_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Input_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Key_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Leaf_list_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Leaf_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.List_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Mandatory_argContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Mandatory_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Max_elements_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Min_elements_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_header_stmtsContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Namespace_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Notification_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Ordered_by_argContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Ordered_by_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Organization_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Output_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Prefix_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Presence_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Reference_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_date_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtsContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Rpc_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Status_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.StringContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Submodule_header_stmtsContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Submodule_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Type_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Typedef_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Units_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Uses_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Yang_version_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParserBaseListener;
import com.cisco.yangide.core.dom.ASTNamedNode;
import com.cisco.yangide.core.dom.ASTNode;
import com.cisco.yangide.core.dom.AnyXmlSchemaNode;
import com.cisco.yangide.core.dom.AugmentationSchema;
import com.cisco.yangide.core.dom.BaseReference;
import com.cisco.yangide.core.dom.ChoiceCaseNode;
import com.cisco.yangide.core.dom.ChoiceNode;
import com.cisco.yangide.core.dom.ContrainerSchemaNode;
import com.cisco.yangide.core.dom.Deviation;
import com.cisco.yangide.core.dom.ExtensionDefinition;
import com.cisco.yangide.core.dom.FeatureDefinition;
import com.cisco.yangide.core.dom.GroupingDefinition;
import com.cisco.yangide.core.dom.IdentitySchemaNode;
import com.cisco.yangide.core.dom.LeafListSchemaNode;
import com.cisco.yangide.core.dom.LeafSchemaNode;
import com.cisco.yangide.core.dom.ListSchemaNode;
import com.cisco.yangide.core.dom.Module;
import com.cisco.yangide.core.dom.ModuleImport;
import com.cisco.yangide.core.dom.NotificationDefinition;
import com.cisco.yangide.core.dom.QName;
import com.cisco.yangide.core.dom.RevisionNode;
import com.cisco.yangide.core.dom.RpcDefinition;
import com.cisco.yangide.core.dom.RpcInputNode;
import com.cisco.yangide.core.dom.RpcOutputNode;
import com.cisco.yangide.core.dom.SimpleNamedNode;
import com.cisco.yangide.core.dom.SimpleNode;
import com.cisco.yangide.core.dom.SubModule;
import com.cisco.yangide.core.dom.SubModuleInclude;
import com.cisco.yangide.core.dom.TypeDefinition;
import com.cisco.yangide.core.dom.TypeReference;
import com.cisco.yangide.core.dom.UsesNode;
/**
* @author Konstantin Zaitsev
* @date Jun 26, 2014
*/
public class YangParserModelListener extends YangParserBaseListener {
private Module module;
private String yangModelPrefix;
private String revision = "1970-01-01"; // default revision Date(0L)
private Stack<ASTNode> stack = new Stack<>();
@Override
public void enterModule_stmt(Module_stmtContext ctx) {
module = new Module();
module.setNamespace("");
module.setRevision(revision);
stack.push(module);
updateNamedNode(module, ctx);
}
@Override
public void visitErrorNode(ErrorNode node) {
if (!stack.isEmpty()) {
stack.peek().setFlags(ASTNode.MALFORMED);
}
if (module != null) {
module.setFlags(ASTNode.MALFORMED);
}
super.visitErrorNode(node);
}
@Override
public void enterSubmodule_stmt(Submodule_stmtContext ctx) {
module = new SubModule();
module.setNamespace("");
module.setRevision(revision);
stack.push(module);
updateNamedNode(module, ctx);
}
@Override
public void enterBelongs_to_stmt(Belongs_to_stmtContext ctx) {
if (module instanceof SubModule) {
String parentModuleName = stringFromNode(ctx);
String parentPrefix = null;
for (int i = 0; i < ctx.getChildCount(); ++i) {
final ParseTree treeNode = ctx.getChild(i);
if (treeNode instanceof Prefix_stmtContext) {
parentPrefix = stringFromNode(treeNode);
((SubModule) module).setParentPrefix(parentPrefix);
}
}
SimpleNode<String> astNode = new SimpleNode<String>(module, ctx.BELONGS_TO_KEYWORD().getText(), parentModuleName);
updateNodePosition(astNode, ctx);
((SubModule) module).setParentModule(astNode);
}
}
@Override
public void exitModule_stmt(Module_stmtContext ctx) {
module.setLength(ctx.stop.getStopIndex() - module.getStartPosition());
}
@Override
public void enterModule_header_stmts(Module_header_stmtsContext ctx) {
for (int i = 0; i < ctx.getChildCount(); ++i) {
final ParseTree treeNode = ctx.getChild(i);
if (treeNode instanceof Namespace_stmtContext) {
final String namespaceStr = stringFromNode(treeNode);
SimpleNode<String> astNode = new SimpleNode<String>(module, ((Namespace_stmtContext) treeNode)
.NAMESPACE_KEYWORD().getText(), namespaceStr);
updateNodePosition(astNode, treeNode);
module.setNamespaceNode(astNode);
} else if (treeNode instanceof Prefix_stmtContext) {
yangModelPrefix = stringFromNode(treeNode);
SimpleNode<String> astNode = new SimpleNode<String>(module, ((Prefix_stmtContext) treeNode)
.PREFIX_KEYWORD().getText(), yangModelPrefix);
updateNodePosition(astNode, treeNode);
module.setPrefix(astNode);
} else if (treeNode instanceof Yang_version_stmtContext) {
SimpleNode<String> astNode = new SimpleNode<String>(module, ((Yang_version_stmtContext) treeNode)
.YANG_VERSION_KEYWORD().getText(), stringFromNode(treeNode));
updateNodePosition(astNode, treeNode);
module.setYangVersion(astNode);
}
}
}
@Override
public void enterSubmodule_header_stmts(Submodule_header_stmtsContext ctx) {
for (int i = 0; i < ctx.getChildCount(); ++i) {
final ParseTree treeNode = ctx.getChild(i);
if (treeNode instanceof Namespace_stmtContext) {
final String namespaceStr = stringFromNode(treeNode);
SimpleNode<String> astNode = new SimpleNode<String>(module, ((Namespace_stmtContext) treeNode)
.NAMESPACE_KEYWORD().getText(), namespaceStr);
updateNodePosition(astNode, treeNode);
module.setNamespaceNode(astNode);
} else if (treeNode instanceof Prefix_stmtContext) {
yangModelPrefix = stringFromNode(treeNode);
SimpleNode<String> astNode = new SimpleNode<String>(module, ((Prefix_stmtContext) treeNode)
.PREFIX_KEYWORD().getText(), yangModelPrefix);
updateNodePosition(astNode, treeNode);
module.setPrefix(astNode);
} else if (treeNode instanceof Yang_version_stmtContext) {
SimpleNode<String> astNode = new SimpleNode<String>(module, ((Yang_version_stmtContext) treeNode)
.YANG_VERSION_KEYWORD().getText(), stringFromNode(treeNode));
updateNodePosition(astNode, treeNode);
module.setYangVersion(astNode);
}
}
}
@Override
public void enterMeta_stmts(YangParser.Meta_stmtsContext ctx) {
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree treeNode = ctx.getChild(i);
if (treeNode instanceof Organization_stmtContext) {
SimpleNode<String> astNode = new SimpleNode<String>(module, ((Organization_stmtContext) treeNode)
.ORGANIZATION_KEYWORD().getText(), stringFromNode(treeNode));
updateNodePosition(astNode, treeNode);
module.setOrganization(astNode);
} else if (treeNode instanceof Contact_stmtContext) {
SimpleNode<String> astNode = new SimpleNode<String>(module, ((Contact_stmtContext) treeNode)
.CONTACT_KEYWORD().getText(), stringFromNode(treeNode));
updateNodePosition(astNode, treeNode);
module.setContact(astNode);
} else if (treeNode instanceof Description_stmtContext) {
SimpleNode<String> astNode = new SimpleNode<String>(module, ((Description_stmtContext) treeNode)
.DESCRIPTION_KEYWORD().getText(), stringFromNode(treeNode));
updateNodePosition(astNode, treeNode);
module.setDescriptionNode(astNode);
} else if (treeNode instanceof Reference_stmtContext) {
SimpleNode<String> astNode = new SimpleNode<String>(module, ((Reference_stmtContext) treeNode)
.REFERENCE_KEYWORD().getText(), stringFromNode(treeNode));
updateNodePosition(astNode, treeNode);
module.setReferenceNode(astNode);
}
}
}
@Override
public void enterRevision_stmts(Revision_stmtsContext ctx) {
for (int i = 0; i < ctx.getChildCount(); ++i) {
final ParseTree treeNode = ctx.getChild(i);
if (treeNode instanceof Revision_stmtContext) {
updateRevisionForRevisionStatement(treeNode);
}
}
}
@Override
public void enterImport_stmt(Import_stmtContext ctx) {
String importPrefix = null;
String importRevision = null;
for (int i = 0; i < ctx.getChildCount(); ++i) {
final ParseTree treeNode = ctx.getChild(i);
if (treeNode instanceof Prefix_stmtContext) {
importPrefix = stringFromNode(treeNode);
}
if (treeNode instanceof Revision_date_stmtContext) {
importRevision = stringFromNode(treeNode);
}
}
ModuleImport moduleImport = new ModuleImport(module, importRevision, importPrefix);
updateNamedNode(moduleImport, ctx);
module.addImport(moduleImport);
}
@Override
public void enterInclude_stmt(Include_stmtContext ctx) {
String includeRevision = null;
for (int i = 0; i < ctx.getChildCount(); ++i) {
final ParseTree treeNode = ctx.getChild(i);
if (treeNode instanceof Revision_date_stmtContext) {
includeRevision = stringFromNode(treeNode);
}
}
SubModuleInclude subModuleInclude = new SubModuleInclude(module, includeRevision);
updateNamedNode(subModuleInclude, ctx);
module.getIncludes().put(subModuleInclude.getName(), subModuleInclude);
}
@Override
public void enterTypedef_stmt(Typedef_stmtContext ctx) {
ASTNode parent = stack.peek();
TypeDefinition typeDefinition = new TypeDefinition(parent);
updateNamedNode(typeDefinition, ctx);
if (parent instanceof Module) {
module.getTypeDefinitions().add(typeDefinition);
}
stack.push(typeDefinition);
}
@Override
public void exitTypedef_stmt(Typedef_stmtContext ctx) {
stack.pop();
}
@Override
public void enterGrouping_stmt(Grouping_stmtContext ctx) {
GroupingDefinition grouping = new GroupingDefinition(stack.peek());
stack.push(grouping);
module.getGroupings().add(grouping);
updateNamedNode(grouping, ctx);
}
@Override
public void exitGrouping_stmt(Grouping_stmtContext ctx) {
stack.pop();
}
@Override
public void enterContainer_stmt(Container_stmtContext ctx) {
ContrainerSchemaNode container = new ContrainerSchemaNode(stack.peek());
stack.push(container);
updateNamedNode(container, ctx);
}
@Override
public void exitContainer_stmt(Container_stmtContext ctx) {
stack.pop();
}
@Override
public void enterLeaf_stmt(Leaf_stmtContext ctx) {
LeafSchemaNode leaf = new LeafSchemaNode(stack.peek());
stack.push(leaf);
updateNamedNode(leaf, ctx);
}
@Override
public void exitLeaf_stmt(Leaf_stmtContext ctx) {
stack.pop();
}
@Override
public void enterType_stmt(Type_stmtContext ctx) {
final String typeName = stringFromNode(ctx);
final QName typeQName = parseQName(typeName);
TypeReference typeRef = new TypeReference(stack.peek());
updateNamedNode(typeRef, ctx);
typeRef.setType(typeQName);
}
@Override
public void enterUses_stmt(Uses_stmtContext ctx) {
final String groupingPath = stringFromNode(ctx);
UsesNode usesNode = new UsesNode(stack.peek());
updateNamedNode(usesNode, ctx);
usesNode.setGrouping(parseQName(groupingPath));
}
@Override
public void enterAugment_stmt(Augment_stmtContext ctx) {
AugmentationSchema augmentation = new AugmentationSchema(stack.peek());
updateNamedNode(augmentation, ctx);
stack.push(augmentation);
}
@Override
public void exitAugment_stmt(Augment_stmtContext ctx) {
stack.pop();
}
@Override
public void enterDeviation_stmt(Deviation_stmtContext ctx) {
Deviation deviation = new Deviation(stack.peek());
updateNamedNode(deviation, ctx);
stack.push(deviation);
}
@Override
public void exitDeviation_stmt(Deviation_stmtContext ctx) {
stack.pop();
}
@Override
public void enterExtension_stmt(Extension_stmtContext ctx) {
ExtensionDefinition extension = new ExtensionDefinition(stack.peek());
updateNamedNode(extension, ctx);
stack.push(extension);
}
@Override
public void exitExtension_stmt(Extension_stmtContext ctx) {
stack.pop();
}
@Override
public void enterFeature_stmt(Feature_stmtContext ctx) {
FeatureDefinition feature = new FeatureDefinition(stack.peek());
updateNamedNode(feature, ctx);
stack.push(feature);
}
@Override
public void exitFeature_stmt(Feature_stmtContext ctx) {
stack.pop();
}
@Override
public void enterNotification_stmt(Notification_stmtContext ctx) {
NotificationDefinition notification = new NotificationDefinition(stack.peek());
updateNamedNode(notification, ctx);
stack.push(notification);
}
@Override
public void exitNotification_stmt(Notification_stmtContext ctx) {
stack.pop();
}
@Override
public void enterRpc_stmt(Rpc_stmtContext ctx) {
RpcDefinition rpc = new RpcDefinition(stack.peek());
updateNamedNode(rpc, ctx);
stack.push(rpc);
}
@Override
public void exitRpc_stmt(Rpc_stmtContext ctx) {
stack.pop();
}
@Override
public void enterInput_stmt(Input_stmtContext ctx) {
RpcInputNode input = new RpcInputNode(stack.peek());
updateNodePosition(input, ctx);
input.setName("input");
input.setNameStartPosition(input.getStartPosition());
input.setNameLength(input.getName().length());
stack.push(input);
}
@Override
public void exitInput_stmt(Input_stmtContext ctx) {
stack.pop();
}
@Override
public void enterOutput_stmt(Output_stmtContext ctx) {
RpcOutputNode output = new RpcOutputNode(stack.peek());
updateNodePosition(output, ctx);
output.setName("output");
output.setNameStartPosition(output.getStartPosition());
output.setNameLength(output.getName().length());
stack.push(output);
}
@Override
public void exitOutput_stmt(Output_stmtContext ctx) {
stack.pop();
}
@Override
public void enterIdentity_stmt(Identity_stmtContext ctx) {
IdentitySchemaNode identity = new IdentitySchemaNode(stack.peek());
updateNamedNode(identity, ctx);
Base_stmtContext base = getChildNode(ctx, Base_stmtContext.class);
if (base != null) {
BaseReference baseRef = new BaseReference(identity);
baseRef.setType(parseQName(stringFromNode(base)));
updateNamedNode(baseRef, base);
identity.setBase(baseRef);
}
}
@Override
public void enterLeaf_list_stmt(Leaf_list_stmtContext ctx) {
LeafListSchemaNode leafList = new LeafListSchemaNode(stack.peek());
stack.push(leafList);
updateNamedNode(leafList, ctx);
}
@Override
public void exitLeaf_list_stmt(Leaf_list_stmtContext ctx) {
stack.pop();
}
@Override
public void enterList_stmt(List_stmtContext ctx) {
ListSchemaNode list = new ListSchemaNode(stack.peek());
stack.push(list);
updateNamedNode(list, ctx);
}
@Override
public void enterKey_stmt(Key_stmtContext ctx) {
ASTNode node = stack.peek();
if (node instanceof ListSchemaNode) {
SimpleNamedNode keyNode = new SimpleNamedNode(node, "key");
updateNamedNode(keyNode, ctx);
((ListSchemaNode) node).setKey(keyNode);
}
}
@Override
public void exitList_stmt(List_stmtContext ctx) {
stack.pop();
}
@Override
public void enterAnyxml_stmt(Anyxml_stmtContext ctx) {
AnyXmlSchemaNode xml = new AnyXmlSchemaNode(stack.peek());
stack.push(xml);
updateNamedNode(xml, ctx);
}
@Override
public void exitAnyxml_stmt(Anyxml_stmtContext ctx) {
stack.pop();
}
@Override
public void enterChoice_stmt(Choice_stmtContext ctx) {
ChoiceNode choice = new ChoiceNode(stack.peek());
stack.push(choice);
updateNamedNode(choice, ctx);
}
@Override
public void exitChoice_stmt(Choice_stmtContext ctx) {
stack.pop();
}
@Override
public void enterCase_stmt(Case_stmtContext ctx) {
ChoiceCaseNode choiceCase = new ChoiceCaseNode(stack.peek());
stack.push(choiceCase);
updateNamedNode(choiceCase, ctx);
}
@Override
public void exitCase_stmt(Case_stmtContext ctx) {
stack.pop();
}
@Override
public void enterConfig_stmt(Config_stmtContext ctx) {
Config_argContext val = getChildNode(ctx, Config_argContext.class);
SimpleNode<String> node = new SimpleNode<String>(stack.peek(), "config", stringFromNode(val));
updateNodePosition(node, ctx);
}
@Override
public void enterPresence_stmt(Presence_stmtContext ctx) {
SimpleNode<String> node = new SimpleNode<String>(stack.peek(), "presence", stringFromNode(ctx));
updateNodePosition(node, ctx);
}
@Override
public void enterMax_elements_stmt(Max_elements_stmtContext ctx) {
SimpleNode<String> node = new SimpleNode<String>(stack.peek(), "max-elements", stringFromNode(ctx));
updateNodePosition(node, ctx);
}
@Override
public void enterMin_elements_stmt(Min_elements_stmtContext ctx) {
SimpleNode<String> node = new SimpleNode<String>(stack.peek(), "min-elements", stringFromNode(ctx));
updateNodePosition(node, ctx);
}
@Override
public void enterOrdered_by_stmt(Ordered_by_stmtContext ctx) {
Ordered_by_argContext val = getChildNode(ctx, Ordered_by_argContext.class);
SimpleNode<String> node = new SimpleNode<String>(stack.peek(), "ordered-by", stringFromNode(val));
updateNodePosition(node, ctx);
}
@Override
public void enterUnits_stmt(Units_stmtContext ctx) {
SimpleNode<String> node = new SimpleNode<String>(stack.peek(), "units", stringFromNode(ctx));
updateNodePosition(node, ctx);
}
@Override
public void enterMandatory_stmt(Mandatory_stmtContext ctx) {
Mandatory_argContext val = getChildNode(ctx, Mandatory_argContext.class);
SimpleNode<String> node = new SimpleNode<String>(stack.peek(), "mandatory", stringFromNode(val));
updateNodePosition(node, ctx);
}
@Override
public void enterDefault_stmt(Default_stmtContext ctx) {
SimpleNode<String> node = new SimpleNode<String>(stack.peek(), "default", stringFromNode(ctx));
updateNodePosition(node, ctx);
}
/**
* @return
*/
public Module getModule() {
return module;
}
/**
* @param typeName
* @return
*/
private QName parseQName(String typeName) {
String[] parts = typeName.split(":");
if (parts.length == 2) {
ModuleImport moduleImport = module.getImportByPrefix(parts[0]);
if (moduleImport != null) {
return new QName(moduleImport.getName(), moduleImport.getPrefix(), parts[1], moduleImport.getRevision());
}
if (module instanceof SubModule) {
SubModule subModule = (SubModule) module;
if (parts[0].equals(subModule.getParentPrefix())) {
return new QName(subModule.getParentModule().getValue(), parts[0], parts[1], null);
}
}
}
String prefix = module.getPrefix() != null ? module.getPrefix().getValue() : null;
return new QName(module.getName(), prefix, typeName, revision);
}
private void updateRevisionForRevisionStatement(final ParseTree treeNode) {
final String revisionDate = stringFromNode(treeNode);
if ((revisionDate != null) && (this.revision.compareTo(revisionDate) < 0)) {
this.revision = revisionDate;
RevisionNode revisionNode = new RevisionNode(module);
updateNodePosition(revisionNode, treeNode);
updateNamedNode(revisionNode, treeNode);
module.setRevisionNode(revisionNode);
}
}
private void updateNodePosition(ASTNode astNode, ParseTree treeNode) {
if (astNode != null && treeNode instanceof ParserRuleContext) {
astNode.setStartPosition(((ParserRuleContext) treeNode).start.getStartIndex());
astNode.setLineNumber(((ParserRuleContext) treeNode).start.getLine());
astNode.setLength(((ParserRuleContext) treeNode).stop.getStopIndex() - astNode.getStartPosition());
Token bodyToken = null;
for (int i = 0; i < treeNode.getChildCount(); ++i) {
if (treeNode.getChild(i) instanceof TerminalNode) {
final TerminalNode term = (TerminalNode) treeNode.getChild(i);
if (term != null && term.getSymbol() != null && term.getSymbol().getType() == YangLexer.LEFT_BRACE) {
bodyToken = term.getSymbol();
}
}
}
if (bodyToken != null) {
astNode.setBodyStartPosition(bodyToken.getStartIndex());
}
setNodeDescription(astNode, treeNode);
}
}
private void setNodeDescription(ASTNode astNode, ParseTree treeNode) {
for (int i = 0; i < treeNode.getChildCount(); i++) {
ParseTree child = treeNode.getChild(i);
if (child instanceof Description_stmtContext) {
SimpleNode<String> astChild = new SimpleNode<String>(module, ((Description_stmtContext) child)
.DESCRIPTION_KEYWORD().getText(), stringFromNode(child));
updateNodePosition(astChild, child);
astNode.setDescriptionNode(astChild);
} else if (child instanceof Reference_stmtContext) {
SimpleNode<String> astChild = new SimpleNode<String>(module, ((Reference_stmtContext) child)
.REFERENCE_KEYWORD().getText(), stringFromNode(child));
updateNodePosition(astChild, child);
astNode.setReferenceNode(astChild);
} else if (child instanceof Status_stmtContext) {
SimpleNode<String> astChild = new SimpleNode<String>(module, ((Status_stmtContext) child)
.STATUS_KEYWORD().getText(), stringFromNode(child));
updateNodePosition(astChild, child);
astNode.setStatusNode(astChild);
}
}
}
private void updateNamedNode(ASTNamedNode astNode, ParseTree treeNode) {
updateNodePosition(astNode, treeNode);
for (int i = 0; i < treeNode.getChildCount(); ++i) {
if (treeNode.getChild(i) instanceof StringContext) {
final StringContext context = (StringContext) treeNode.getChild(i);
if (context != null) {
Token token = context.getStart();
astNode.setNameStartPosition(token.getStartIndex());
astNode.setNameLength(token.getStopIndex() - token.getStartIndex() + 1);
astNode.setLineNumber(token.getLine());
astNode.setName(stringFromStringContext(context));
}
}
}
}
/**
* Parse given tree and get first string value.
*
* @param treeNode tree to parse
* @return first string value from given tree
*/
private static String stringFromNode(final ParseTree treeNode) {
String result = "";
for (int i = 0; i < treeNode.getChildCount(); ++i) {
if (treeNode.getChild(i) instanceof StringContext) {
final StringContext context = (StringContext) treeNode.getChild(i);
if (context != null) {
return stringFromStringContext(context);
}
}
}
return result;
}
private static String stringFromStringContext(final StringContext context) {
StringBuilder str = new StringBuilder();
for (TerminalNode stringNode : context.STRING()) {
String result = stringNode.getText();
if (!result.contains("\"")) {
str.append(result);
} else {
str.append(result.replace("\"", ""));
}
}
return str.toString();
}
@SuppressWarnings("unchecked")
private <T> T getChildNode(ParseTree ctx, Class<T> clazz) {
for (int i = 0; i < ctx.getChildCount(); ++i) {
final ParseTree treeNode = ctx.getChild(i);
if (treeNode.getClass().equals(clazz)) {
return (T) treeNode;
}
}
return null;
}
}