BUG-1270: improve QNameModule reuse
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / YangParserListenerImpl.java
index 55b610e1e3f7ceada209cf4fae926cf75848ac62..a536c1cbf85a2abaf518006afb048bd21107f314 100644 (file)
@@ -34,7 +34,6 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Stack;
 
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
@@ -70,6 +69,7 @@ import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.When_stmtContext;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Yang_version_stmtContext;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangParserBaseListener;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.BaseTypes;
@@ -99,30 +99,18 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public final class YangParserListenerImpl extends YangParserBaseListener {
-    private static final Logger LOGGER = LoggerFactory.getLogger(YangParserListenerImpl.class);
+    private static final Logger LOG = LoggerFactory.getLogger(YangParserListenerImpl.class);
     private static final Splitter COLON_SPLITTER = Splitter.on(':');
     private static final String AUGMENT_STR = "augment";
 
     private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
-    private final Stack<Stack<QName>> actualPath = new Stack<>();
+    private final SchemaPathStack stack = new SchemaPathStack();
     private final String sourcePath;
     private QName moduleQName = new QName(null, new Date(0L), null, "dummy");
     private ModuleBuilder moduleBuilder;
     private String moduleName;
     private int augmentOrder;
 
-    private void addNodeToPath(final QName name) {
-        actualPath.peek().push(name);
-    }
-
-    private QName removeNodeFromPath() {
-        return actualPath.peek().pop();
-    }
-
-    private SchemaPath currentSchemaPath() {
-        return SchemaPath.create(actualPath.peek(), true);
-    }
-
     public YangParserListenerImpl(final String sourcePath) {
         this.sourcePath = sourcePath;
     }
@@ -130,9 +118,9 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void enterModule_stmt(final YangParser.Module_stmtContext ctx) {
         moduleName = stringFromNode(ctx);
-        LOGGER.trace("entering module {}", moduleName);
+        LOG.trace("entering module {}", moduleName);
         enterLog("module", moduleName, 0);
-        actualPath.push(new Stack<QName>());
+        stack.push();
 
         moduleBuilder = new ModuleBuilder(moduleName, sourcePath);
 
@@ -157,15 +145,15 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitModule_stmt(final YangParser.Module_stmtContext ctx) {
         exitLog("module");
-        actualPath.pop();
+        stack.pop();
     }
 
     @Override
     public void enterSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
         moduleName = stringFromNode(ctx);
-        LOGGER.trace("entering submodule {}", moduleName);
+        LOG.trace("entering submodule {}", moduleName);
         enterLog("submodule", moduleName, 0);
-        actualPath.push(new Stack<QName>());
+        stack.push();
 
         moduleBuilder = new ModuleBuilder(moduleName, true, sourcePath);
 
@@ -190,7 +178,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
         exitLog("submodule");
-        actualPath.pop();
+        stack.pop();
     }
 
     @Override
@@ -212,7 +200,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 setLog("namespace", namespaceStr);
             } else if (treeNode instanceof Prefix_stmtContext) {
                 final String yangModelPrefix = stringFromNode(treeNode);
-                this.moduleQName = new QName(moduleQName.getNamespace(), moduleQName.getRevision(), yangModelPrefix, moduleQName.getLocalName());
+                this.moduleQName = QName.create(moduleQName.getModule(), yangModelPrefix, moduleQName.getLocalName());
                 moduleBuilder.setPrefix(yangModelPrefix);
                 setLog("prefix", yangModelPrefix);
             } else if (treeNode instanceof Yang_version_stmtContext) {
@@ -294,8 +282,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 }
             }
         } catch (ParseException e) {
-            final String message = "Failed to parse revision string: " + revisionDateStr;
-            LOGGER.warn(message);
+            LOG.warn("Failed to parse revision string: {}", revisionDateStr, e);
         }
     }
 
@@ -318,12 +305,12 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 try {
                     importRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
                 } catch (ParseException e) {
-                    LOGGER.warn("Failed to parse import revision-date at line " + line + ": " + importRevisionStr);
+                    LOG.warn("Failed to parse import revision-date at line {}: {}", line, importRevisionStr, e);
                 }
             }
         }
         moduleBuilder.addModuleImport(importName, importRevision, importPrefix);
-        setLog("import", "(" + importName + "; " + importRevision + "; " + importPrefix + ")");
+        LOG.trace("setting import ({}; {}; {})", importName, importRevision, importPrefix);
     }
 
     @Override
@@ -336,7 +323,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final int line = ctx.getStart().getLine();
         final String augmentPath = stringFromNode(ctx);
         enterLog(AUGMENT_STR, augmentPath, line);
-        actualPath.push(new Stack<QName>());
+        stack.push();
 
         AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
 
@@ -360,7 +347,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitAugment_stmt(final YangParser.Augment_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog(AUGMENT_STR);
-        actualPath.pop();
+        stack.pop();
     }
 
     @Override
@@ -369,8 +356,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final String extName = stringFromNode(ctx);
         enterLog("extension", extName, line);
         QName qname = QName.create(moduleQName, extName);
-        addNodeToPath(qname);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(qname);
 
         ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
         parseSchemaNodeArgs(ctx, builder);
@@ -394,7 +380,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitExtension_stmt(final YangParser.Extension_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("extension", removeNodeFromPath());
+        exitLog("extension", stack.removeNodeFromPath());
     }
 
     @Override
@@ -403,8 +389,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final String typedefName = stringFromNode(ctx);
         enterLog("typedef", typedefName, line);
         QName typedefQName = QName.create(moduleQName, typedefName);
-        addNodeToPath(typedefQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(typedefQName);
 
         TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
         parseSchemaNodeArgs(ctx, builder);
@@ -417,7 +402,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitTypedef_stmt(final YangParser.Typedef_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("typedef", removeNodeFromPath());
+        exitLog("typedef", stack.removeNodeFromPath());
     }
 
     @Override
@@ -444,14 +429,14 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 checkMissingBody(typeName, moduleName, line);
                 // if there are no constraints, just grab default base yang type
                 type = BaseTypes.defaultBaseTypeFor(typeName).orNull();
-                addNodeToPath(type.getQName());
+                stack.addNodeToPath(type.getQName());
                 moduleBuilder.setType(type);
             } else {
                 QName qname;
                 switch (typeName) {
                 case "union":
                     qname = BaseTypes.UNION_QNAME;
-                    addNodeToPath(qname);
+                    stack.addNodeToPath(qname);
                     UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, moduleQName.getModule());
                     Builder parent = moduleBuilder.getActualNode();
                     unionBuilder.setParent(parent);
@@ -459,22 +444,21 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                     break;
                 case "identityref":
                     qname = BaseTypes.IDENTITYREF_QNAME;
-                    addNodeToPath(qname);
-                    SchemaPath path = currentSchemaPath();
+                    SchemaPath path = stack.addNodeToPath(qname);
                     moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
                     break;
                 default:
-                    type = parseTypeWithBody(typeName, typeBody, currentSchemaPath(), moduleQName, moduleBuilder.getActualNode());
+                    type = parseTypeWithBody(typeName, typeBody, stack.currentSchemaPath(), moduleQName, moduleBuilder.getActualNode());
                     moduleBuilder.setType(type);
-                    addNodeToPath(type.getQName());
+                    stack.addNodeToPath(type.getQName());
                 }
             }
         } else {
-            type = parseUnknownTypeWithBody(typeQName, typeBody, currentSchemaPath(), moduleQName, moduleBuilder.getActualNode());
+            type = parseUnknownTypeWithBody(typeQName, typeBody, stack.currentSchemaPath(), moduleQName, moduleBuilder.getActualNode());
             // add parent node of this type statement to dirty nodes
             moduleBuilder.markActualNodeDirty();
             moduleBuilder.setType(type);
-            addNodeToPath(type.getQName());
+            stack.addNodeToPath(type.getQName());
         }
 
     }
@@ -488,7 +472,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             if (prefix.equals(moduleQName.getPrefix())) {
                 typeQName = QName.create(moduleQName, name);
             } else {
-                typeQName = new QName(null, null, prefix, name);
+                typeQName = QName.create(QNameModule.create(null, null), prefix, name);
             }
         } else {
             typeQName = QName.create(moduleQName, typeName);
@@ -502,7 +486,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         if ("union".equals(typeName)) {
             moduleBuilder.exitNode();
         }
-        exitLog("type", removeNodeFromPath());
+        exitLog("type", stack.removeNodeFromPath());
     }
 
     @Override
@@ -511,8 +495,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final String groupName = stringFromNode(ctx);
         enterLog("grouping", groupName, line);
         QName groupQName = QName.create(moduleQName, groupName);
-        addNodeToPath(groupQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(groupQName);
 
         GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
         parseSchemaNodeArgs(ctx, builder);
@@ -523,7 +506,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitGrouping_stmt(final YangParser.Grouping_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("grouping", removeNodeFromPath());
+        exitLog("grouping", stack.removeNodeFromPath());
     }
 
     @Override
@@ -533,8 +516,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("container", containerName, line);
 
         QName containerQName = QName.create(moduleQName, containerName);
-        addNodeToPath(containerQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(containerQName);
 
         ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
         parseSchemaNodeArgs(ctx, builder);
@@ -555,7 +537,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitContainer_stmt(final Container_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("container", removeNodeFromPath());
+        exitLog("container", stack.removeNodeFromPath());
     }
 
     @Override
@@ -565,8 +547,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("leaf", leafName, line);
 
         QName leafQName = QName.create(moduleQName, leafName);
-        addNodeToPath(leafQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(leafQName);
 
         LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
         parseSchemaNodeArgs(ctx, builder);
@@ -592,7 +573,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitLeaf_stmt(final YangParser.Leaf_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("leaf", removeNodeFromPath());
+        exitLog("leaf", stack.removeNodeFromPath());
     }
 
     @Override
@@ -614,10 +595,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void enterUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
-        actualPath.push(new Stack<QName>());
         final int line = ctx.getStart().getLine();
         final String augmentPath = stringFromNode(ctx);
         enterLog(AUGMENT_STR, augmentPath, line);
+        stack.push();
 
         AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
 
@@ -641,7 +622,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog(AUGMENT_STR);
-        actualPath.pop();
+        stack.pop();
     }
 
     @Override
@@ -666,8 +647,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final String leafListName = stringFromNode(ctx);
         enterLog("leaf-list", leafListName, line);
         QName leafListQName = QName.create(moduleQName, leafListName);
-        addNodeToPath(leafListQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(leafListQName);
 
         LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
         moduleBuilder.enterNode(builder);
@@ -690,7 +670,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitLeaf_list_stmt(final YangParser.Leaf_list_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("leaf-list", removeNodeFromPath());
+        exitLog("leaf-list", stack.removeNodeFromPath());
     }
 
     @Override
@@ -700,8 +680,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("list", listName, line);
 
         QName listQName = QName.create(moduleQName, listName);
-        addNodeToPath(listQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(listQName);
 
         ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
         moduleBuilder.enterNode(builder);
@@ -726,7 +705,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitList_stmt(final List_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("list", removeNodeFromPath());
+        exitLog("list", stack.removeNodeFromPath());
     }
 
     @Override
@@ -736,8 +715,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("anyxml", anyXmlName, line);
 
         QName anyXmlQName = QName.create(moduleQName, anyXmlName);
-        addNodeToPath(anyXmlQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(anyXmlQName);
 
         AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
         moduleBuilder.enterNode(builder);
@@ -750,7 +728,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitAnyxml_stmt(final YangParser.Anyxml_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("anyxml", removeNodeFromPath());
+        exitLog("anyxml", stack.removeNodeFromPath());
     }
 
     @Override
@@ -760,8 +738,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("choice", choiceName, line);
 
         QName choiceQName = QName.create(moduleQName, choiceName);
-        addNodeToPath(choiceQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(choiceQName);
 
         ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
         moduleBuilder.enterNode(builder);
@@ -784,7 +761,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitChoice_stmt(final YangParser.Choice_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("choice", removeNodeFromPath());
+        exitLog("choice", stack.removeNodeFromPath());
     }
 
     @Override
@@ -794,8 +771,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("case", caseName, line);
 
         QName caseQName = QName.create(moduleQName, caseName);
-        addNodeToPath(caseQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(caseQName);
 
         ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
         moduleBuilder.enterNode(builder);
@@ -807,7 +783,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitCase_stmt(final YangParser.Case_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("case", removeNodeFromPath());
+        exitLog("case", stack.removeNodeFromPath());
     }
 
     @Override
@@ -817,8 +793,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("notification", notificationName, line);
 
         QName notificationQName = QName.create(moduleQName, notificationName);
-        addNodeToPath(notificationQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(notificationQName);
 
         NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
         moduleBuilder.enterNode(builder);
@@ -829,7 +804,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitNotification_stmt(final YangParser.Notification_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("notification", removeNodeFromPath());
+        exitLog("notification", stack.removeNodeFromPath());
     }
 
     // Unknown nodes
@@ -841,7 +816,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("unknown-node", removeNodeFromPath());
+        exitLog("unknown-node", stack.removeNodeFromPath());
     }
 
     @Override public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
@@ -850,7 +825,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("unknown-node", removeNodeFromPath());
+        exitLog("unknown-node", stack.removeNodeFromPath());
     }
 
     @Override public void enterUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
@@ -859,7 +834,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override public void exitUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
         moduleBuilder.exitNode();
-        exitLog("unknown-node", removeNodeFromPath());
+        exitLog("unknown-node", stack.removeNodeFromPath());
     }
 
     @Override public void enterUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
@@ -868,7 +843,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override public void exitUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
         moduleBuilder.exitNode();
-        exitLog("unknown-node", removeNodeFromPath());
+        exitLog("unknown-node", stack.removeNodeFromPath());
     }
 
     @Override
@@ -878,8 +853,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("rpc", rpcName, line);
 
         QName rpcQName = QName.create(moduleQName, rpcName);
-        addNodeToPath(rpcQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(rpcQName);
 
         RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
         moduleBuilder.enterNode(rpcBuilder);
@@ -891,7 +865,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitRpc_stmt(final YangParser.Rpc_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("rpc", removeNodeFromPath());
+        exitLog("rpc", stack.removeNodeFromPath());
     }
 
     @Override
@@ -901,8 +875,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog(input, input, line);
 
         QName rpcQName = QName.create(moduleQName, input);
-        addNodeToPath(rpcQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(rpcQName);
 
         ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
         moduleBuilder.enterNode(builder);
@@ -915,7 +888,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitInput_stmt(final YangParser.Input_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("input", removeNodeFromPath());
+        exitLog("input", stack.removeNodeFromPath());
     }
 
     @Override
@@ -925,8 +898,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog(output, output, line);
 
         QName rpcQName = QName.create(moduleQName, output);
-        addNodeToPath(rpcQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(rpcQName);
 
         ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
         moduleBuilder.enterNode(builder);
@@ -939,7 +911,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitOutput_stmt(final YangParser.Output_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("output", removeNodeFromPath());
+        exitLog("output", stack.removeNodeFromPath());
     }
 
     @Override
@@ -949,8 +921,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("feature", featureName, line);
 
         QName featureQName = QName.create(moduleQName, featureName);
-        addNodeToPath(featureQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(featureQName);
 
         FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
         moduleBuilder.enterNode(featureBuilder);
@@ -961,7 +932,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitFeature_stmt(final YangParser.Feature_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("feature", removeNodeFromPath());
+        exitLog("feature", stack.removeNodeFromPath());
     }
 
     @Override
@@ -1006,8 +977,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("identity", identityName, line);
 
         final QName identityQName = QName.create(moduleQName, identityName);
-        addNodeToPath(identityQName);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(identityQName);
 
         IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
         moduleBuilder.enterNode(builder);
@@ -1026,27 +996,27 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitIdentity_stmt(final YangParser.Identity_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("identity", removeNodeFromPath());
+        exitLog("identity", stack.removeNodeFromPath());
     }
 
     public ModuleBuilder getModuleBuilder() {
         return moduleBuilder;
     }
 
-    private void enterLog(final String p1, final String p2, final int line) {
-        LOGGER.trace("entering {} {} ({})", p1, p2, line);
+    private static void enterLog(final String p1, final String p2, final int line) {
+        LOG.trace("entering {} {} ({})", p1, p2, line);
     }
 
-    private void exitLog(final String p1) {
-        LOGGER.trace("exiting {}", p1);
+    private static void exitLog(final String p1) {
+        LOG.trace("exiting {}", p1);
     }
 
-    private void exitLog(final String p1, final QName p2) {
-        LOGGER.trace("exiting {} {}", p1, p2.getLocalName());
+    private static void exitLog(final String p1, final QName p2) {
+        LOG.trace("exiting {} {}", p1, p2.getLocalName());
     }
 
-    private void setLog(final String p1, final String p2) {
-        LOGGER.trace("setting {} {}", p1, p2);
+    private static void setLog(final String p1, final String p2) {
+        LOG.trace("setting {} {}", p1, p2);
     }
 
     private void handleUnknownNode(final int line, final ParseTree ctx) {
@@ -1058,7 +1028,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final String e0 = splittedElement.next();
         final QName nodeType;
         if (splittedElement.hasNext()) {
-            nodeType = new QName(moduleQName.getNamespace(), moduleQName.getRevision(), e0, splittedElement.next());
+            nodeType = QName.create(moduleQName.getModule(), e0, splittedElement.next());
         } else {
             nodeType = QName.create(moduleQName, e0);
         }
@@ -1070,7 +1040,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 final Iterator<String> it = splittedName.iterator();
 
                 if (Iterables.size(splittedName) == 2) {
-                    qname = new QName(null, null, it.next(), it.next());
+                    qname = QName.create(QNameModule.create(null, null), it.next(), it.next());
                 } else {
                     qname = QName.create(moduleQName, it.next());
                 }
@@ -1080,8 +1050,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         } catch (IllegalArgumentException e) {
             qname = nodeType;
         }
-        addNodeToPath(qname);
-        SchemaPath path = currentSchemaPath();
+        SchemaPath path = stack.addNodeToPath(qname);
 
         UnknownSchemaNodeBuilderImpl builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
         builder.setNodeType(nodeType);