Added support for parsing submodules & added dependency utility parser
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / YangParserListenerImpl.java
index 32d245e98fedee9473f89591d9ac77e59b6ab397..12c230d5bc3894d649990fb7d458fd978a8e17a0 100644 (file)
@@ -10,12 +10,8 @@ package org.opendaylight.yangtools.yang.parser.impl;
 import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.*;
 
 import java.net.URI;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Stack;
+import java.text.*;
+import java.util.*;
 
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.opendaylight.yangtools.antlrv4.code.gen.*;
@@ -52,33 +48,17 @@ import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Yang_version_stmtC
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.BaseTypes;
 import org.opendaylight.yangtools.yang.model.util.YangTypesConverter;
-import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.AnyXmlBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.DeviationBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ExtensionBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.FeatureBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.*;
+import org.opendaylight.yangtools.yang.parser.builder.impl.*;
 import org.opendaylight.yangtools.yang.parser.util.RefineHolder;
 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 LOGGER = LoggerFactory.getLogger(YangParserListenerImpl.class);
+    private static final String AUGMENT_STR = "augment";
 
     private ModuleBuilder moduleBuilder;
     private String moduleName;
@@ -86,19 +66,28 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     private String yangModelPrefix;
     private Date revision = new Date(0L);
 
-    public final static DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
-    private final Stack<String> actualPath = new Stack<String>();
+    private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+    private final Stack<Stack<QName>> actualPath = new Stack<>();
+
+    private void addNodeToPath(QName name) {
+        actualPath.peek().push(name);
+    }
+
+    private QName removeNodeFromPath() {
+        return actualPath.peek().pop();
+    }
 
     @Override
     public void enterModule_stmt(YangParser.Module_stmtContext ctx) {
         moduleName = stringFromNode(ctx);
-        logger.debug("enter module " + moduleName);
-        actualPath.push(moduleName);
+        LOGGER.debug("entering module " + moduleName);
+        enterLog("module", moduleName, 0);
+        actualPath.push(new Stack<QName>());
+
         moduleBuilder = new ModuleBuilder(moduleName);
 
         String description = null;
         String reference = null;
-
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
@@ -117,7 +106,43 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitModule_stmt(YangParser.Module_stmtContext ctx) {
-        exitLog("module", actualPath.pop());
+        exitLog("module", "");
+        actualPath.pop();
+    }
+
+    @Override public void enterSubmodule_stmt(YangParser.Submodule_stmtContext ctx) {
+        moduleName = stringFromNode(ctx);
+        LOGGER.debug("entering submodule " + moduleName);
+        enterLog("submodule", moduleName, 0);
+        actualPath.push(new Stack<QName>());
+
+        moduleBuilder = new ModuleBuilder(moduleName, true);
+
+        String description = null;
+        String reference = null;
+        for (int i = 0; i < ctx.getChildCount(); i++) {
+            ParseTree child = ctx.getChild(i);
+            if (child instanceof Description_stmtContext) {
+                description = stringFromNode(child);
+            } else if (child instanceof Reference_stmtContext) {
+                reference = stringFromNode(child);
+            } else {
+                if (description != null && reference != null) {
+                    break;
+                }
+            }
+        }
+        moduleBuilder.setDescription(description);
+        moduleBuilder.setReference(reference);
+    }
+
+    @Override public void exitSubmodule_stmt(YangParser.Submodule_stmtContext ctx) {
+        exitLog("submodule", "");
+        actualPath.pop();
+    }
+
+    @Override public void enterBelongs_to_stmt(YangParser.Belongs_to_stmtContext ctx) {
+        moduleBuilder.setBelongsTo(stringFromNode(ctx));
     }
 
     @Override
@@ -201,9 +226,9 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     private void updateRevisionForRevisionStatement(final ParseTree treeNode) {
         final String revisionDateStr = stringFromNode(treeNode);
         try {
-            final Date revision = simpleDateFormat.parse(revisionDateStr);
-            if ((revision != null) && (this.revision.compareTo(revision) < 0)) {
-                this.revision = revision;
+            final Date revisionDate = SIMPLE_DATE_FORMAT.parse(revisionDateStr);
+            if ((revisionDate != null) && (this.revision.compareTo(revisionDate) < 0)) {
+                this.revision = revisionDate;
                 moduleBuilder.setRevision(this.revision);
                 setLog("revision", this.revision.toString());
                 for (int i = 0; i < treeNode.getChildCount(); ++i) {
@@ -215,7 +240,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             }
         } catch (ParseException e) {
             final String message = "Failed to parse revision string: " + revisionDateStr;
-            logger.warn(message);
+            LOGGER.warn(message);
         }
     }
 
@@ -236,9 +261,9 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             if (treeNode instanceof Revision_date_stmtContext) {
                 String importRevisionStr = stringFromNode(treeNode);
                 try {
-                    importRevision = simpleDateFormat.parse(importRevisionStr);
+                    importRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
                 } catch (ParseException e) {
-                    logger.warn("Failed to parse import revision-date at line " + line + ": " + importRevisionStr);
+                    LOGGER.warn("Failed to parse import revision-date at line " + line + ": " + importRevisionStr);
                 }
             }
         }
@@ -255,7 +280,8 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void enterAugment_stmt(YangParser.Augment_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String augmentPath = stringFromNode(ctx);
-        enterLog("augment", augmentPath, line);
+        enterLog(AUGMENT_STR, augmentPath, line);
+        actualPath.push(new Stack<QName>());
 
         AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath);
 
@@ -273,13 +299,13 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         }
 
         moduleBuilder.enterNode(builder);
-        actualPath.push(augmentPath);
     }
 
     @Override
     public void exitAugment_stmt(YangParser.Augment_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("augment", actualPath.pop());
+        exitLog(AUGMENT_STR, "");
+        actualPath.pop();
     }
 
     @Override
@@ -287,9 +313,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final int line = ctx.getStart().getLine();
         final String extName = stringFromNode(ctx);
         enterLog("extension", extName, line);
-
         QName qname = new QName(namespace, revision, yangModelPrefix, extName);
-        ExtensionBuilder builder = moduleBuilder.addExtension(qname, line);
+        addNodeToPath(qname);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
+
+        ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
         parseSchemaNodeArgs(ctx, builder);
 
         String argument = null;
@@ -306,13 +334,12 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         builder.setYinElement(yin);
 
         moduleBuilder.enterNode(builder);
-        actualPath.push(extName);
     }
 
     @Override
     public void exitExtension_stmt(YangParser.Extension_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("extension", actualPath.pop());
+        exitLog("extension", removeNodeFromPath());
     }
 
     @Override
@@ -320,22 +347,22 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final int line = ctx.getStart().getLine();
         final String typedefName = stringFromNode(ctx);
         enterLog("typedef", typedefName, line);
-
         QName typedefQName = new QName(namespace, revision, yangModelPrefix, typedefName);
-        TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName);
-        moduleBuilder.enterNode(builder);
-        actualPath.push(typedefName);
+        addNodeToPath(typedefQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
 
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
         parseSchemaNodeArgs(ctx, builder);
         builder.setUnits(parseUnits(ctx));
         builder.setDefaultValue(parseDefault(ctx));
+
+        moduleBuilder.enterNode(builder);
     }
 
     @Override
     public void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("typedef", actualPath.pop());
+        exitLog("typedef", removeNodeFromPath());
     }
 
     @Override
@@ -361,32 +388,42 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 // check for types which must have body
                 checkMissingBody(typeName, moduleName, line);
                 // if there are no constraints, just grab default base yang type
-                type = YangTypesConverter.javaTypeForBaseYangType(actualPath, namespace, revision, typeName);
+                type = YangTypesConverter.javaTypeForBaseYangType(typeName);
+                addNodeToPath(type.getQName());
                 moduleBuilder.setType(type);
             } else {
-                if ("union".equals(typeName)) {
-                    SchemaPath p = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, typeName);
-                    UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, namespace, revision);
-                    moduleBuilder.enterNode(unionBuilder);
-                    unionBuilder.setPath(p);
-                } else if ("identityref".equals(typeName)) {
-                    SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, typeName);
-                    moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
-                } else {
-                    type = parseTypeWithBody(typeName, typeBody, actualPath, namespace, revision, yangModelPrefix,
-                            moduleBuilder.getActualNode());
-                    moduleBuilder.setType(type);
+                QName qname;
+                switch (typeName) {
+                    case "union":
+                        qname = BaseTypes.constructQName("union");
+                        addNodeToPath(qname);
+                        UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, namespace, revision);
+                        Builder parent = moduleBuilder.getActualNode();
+                        unionBuilder.setParent(parent);
+                        moduleBuilder.enterNode(unionBuilder);
+                        break;
+                    case "identityref":
+                        qname = BaseTypes.constructQName("identityref");
+                        addNodeToPath(qname);
+                        SchemaPath path = createActualSchemaPath(actualPath.peek());
+                        moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
+                        break;
+                    default:
+                        type = parseTypeWithBody(typeName, typeBody, actualPath.peek(), namespace, revision,
+                                yangModelPrefix, moduleBuilder.getActualNode());
+                        moduleBuilder.setType(type);
+                        addNodeToPath(type.getQName());
                 }
             }
         } else {
-            type = parseUnknownTypeWithBody(typeQName, typeBody, actualPath, namespace, revision, yangModelPrefix,
-                    moduleBuilder.getActualNode());
+            type = parseUnknownTypeWithBody(typeQName, typeBody, actualPath.peek(), namespace, revision,
+                    yangModelPrefix, moduleBuilder.getActualNode());
             // add parent node of this type statement to dirty nodes
             moduleBuilder.markActualNodeDirty();
             moduleBuilder.setType(type);
+            addNodeToPath(type.getQName());
         }
 
-        actualPath.push(typeName);
     }
 
     private QName parseQName(String typeName) {
@@ -412,7 +449,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         if ("union".equals(typeName)) {
             moduleBuilder.exitNode();
         }
-        exitLog("type", actualPath.pop());
+        exitLog("type", removeNodeFromPath());
     }
 
     @Override
@@ -420,20 +457,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final int line = ctx.getStart().getLine();
         final String groupName = stringFromNode(ctx);
         enterLog("grouping", groupName, line);
-
         QName groupQName = new QName(namespace, revision, yangModelPrefix, groupName);
-        GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName);
-        moduleBuilder.enterNode(builder);
-        actualPath.push(groupName);
+        addNodeToPath(groupQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
 
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
         parseSchemaNodeArgs(ctx, builder);
+
+        moduleBuilder.enterNode(builder);
     }
 
     @Override
     public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("grouping", actualPath.pop());
+        exitLog("grouping", removeNodeFromPath());
     }
 
     @Override
@@ -443,12 +480,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("container", containerName, line);
 
         QName containerQName = new QName(namespace, revision, yangModelPrefix, containerName);
-        SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, containerName);
+        addNodeToPath(containerQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
 
         ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
-        moduleBuilder.enterNode(builder);
-        actualPath.push(containerName);
-
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
         builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, line));
@@ -460,12 +495,14 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 break;
             }
         }
+
+        moduleBuilder.enterNode(builder);
     }
 
     @Override
     public void exitContainer_stmt(Container_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("container", actualPath.pop());
+        exitLog("container", removeNodeFromPath());
     }
 
     @Override
@@ -475,12 +512,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("leaf", leafName, line);
 
         QName leafQName = new QName(namespace, revision, yangModelPrefix, leafName);
-        SchemaPath schemaPath = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, leafName);
-
-        LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, schemaPath);
-        moduleBuilder.enterNode(builder);
-        actualPath.push(leafName);
+        addNodeToPath(leafQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
 
+        LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
         builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, line));
@@ -497,12 +532,14 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         }
         builder.setDefaultStr(defaultStr);
         builder.setUnits(unitsStr);
+
+        moduleBuilder.enterNode(builder);
     }
 
     @Override
     public void exitLeaf_stmt(YangParser.Leaf_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("leaf", actualPath.pop());
+        exitLog("leaf", removeNodeFromPath());
     }
 
     @Override
@@ -514,19 +551,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         UsesNodeBuilder builder = moduleBuilder.addUsesNode(line, groupingPathStr);
 
         moduleBuilder.enterNode(builder);
-        actualPath.push(groupingPathStr);
     }
 
     @Override
     public void exitUses_stmt(YangParser.Uses_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("uses", actualPath.pop());
+        exitLog("uses", "");
     }
 
-    @Override public void enterUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {
+    @Override
+    public void enterUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {
+        actualPath.push(new Stack<QName>());
         final int line = ctx.getStart().getLine();
         final String augmentPath = stringFromNode(ctx);
-        enterLog("augment", augmentPath, line);
+        enterLog(AUGMENT_STR, augmentPath, line);
 
         AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath);
 
@@ -544,12 +582,13 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         }
 
         moduleBuilder.enterNode(builder);
-        actualPath.push(augmentPath);
     }
 
-    @Override public void exitUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {
+    @Override
+    public void exitUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("augment", actualPath.pop());
+        exitLog(AUGMENT_STR, "");
+        actualPath.pop();
     }
 
     @Override
@@ -560,13 +599,12 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         RefineHolder refine = parseRefine(ctx, moduleName);
         moduleBuilder.addRefine(refine);
         moduleBuilder.enterNode(refine);
-        actualPath.push(refineString);
     }
 
     @Override
     public void exitRefine_stmt(YangParser.Refine_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("refine", actualPath.pop());
+        exitLog("refine", "");
     }
 
     @Override
@@ -574,13 +612,12 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final int line = ctx.getStart().getLine();
         final String leafListName = stringFromNode(ctx);
         enterLog("leaf-list", leafListName, line);
-
         QName leafListQName = new QName(namespace, revision, yangModelPrefix, leafListName);
-        SchemaPath schemaPath = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, leafListName);
+        addNodeToPath(leafListQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
 
-        LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, schemaPath);
+        LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
         moduleBuilder.enterNode(builder);
-        actualPath.push(leafListName);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
@@ -600,7 +637,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("leaf-list", actualPath.pop());
+        exitLog("leaf-list", removeNodeFromPath());
     }
 
     @Override
@@ -610,11 +647,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("list", listName, line);
 
         QName listQName = new QName(namespace, revision, yangModelPrefix, listName);
-        SchemaPath schemaPath = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, listName);
+        addNodeToPath(listQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
 
-        ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, schemaPath);
+        ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
         moduleBuilder.enterNode(builder);
-        actualPath.push(listName);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
@@ -638,7 +675,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitList_stmt(List_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("list", actualPath.pop());
+        exitLog("list", removeNodeFromPath());
     }
 
     @Override
@@ -648,11 +685,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("anyxml", anyXmlName, line);
 
         QName anyXmlQName = new QName(namespace, revision, yangModelPrefix, anyXmlName);
-        SchemaPath schemaPath = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, anyXmlName);
+        addNodeToPath(anyXmlQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
 
-        AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, schemaPath);
+        AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
         moduleBuilder.enterNode(builder);
-        actualPath.push(anyXmlName);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
@@ -662,7 +699,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitAnyxml_stmt(YangParser.Anyxml_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("anyxml", actualPath.pop());
+        exitLog("anyxml", removeNodeFromPath());
     }
 
     @Override
@@ -672,12 +709,12 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("choice", choiceName, line);
 
         QName choiceQName = new QName(namespace, revision, yangModelPrefix, choiceName);
+        addNodeToPath(choiceQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
 
-        ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName);
+        ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
         moduleBuilder.enterNode(builder);
-        actualPath.push(choiceName);
 
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
         builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, line));
@@ -696,7 +733,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitChoice_stmt(YangParser.Choice_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("choice", actualPath.pop());
+        exitLog("choice", removeNodeFromPath());
     }
 
     @Override
@@ -706,11 +743,12 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("case", caseName, line);
 
         QName caseQName = new QName(namespace, revision, yangModelPrefix, caseName);
-        ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName);
+        addNodeToPath(caseQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
+
+        ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
         moduleBuilder.enterNode(builder);
-        actualPath.push(caseName);
 
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
     }
@@ -718,7 +756,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitCase_stmt(YangParser.Case_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("case", actualPath.pop());
+        exitLog("case", removeNodeFromPath());
     }
 
     @Override
@@ -728,18 +766,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("notification", notificationName, line);
 
         QName notificationQName = new QName(namespace, revision, yangModelPrefix, notificationName);
-        NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName);
+        addNodeToPath(notificationQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
+
+        NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
         moduleBuilder.enterNode(builder);
-        actualPath.push(notificationName);
 
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
     }
 
     @Override
     public void exitNotification_stmt(YangParser.Notification_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("notification", actualPath.pop());
+        exitLog("notification", removeNodeFromPath());
     }
 
     // Unknown nodes
@@ -749,14 +788,13 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final String nodeParameter = stringFromNode(ctx);
         enterLog("unknown-node", nodeParameter, line);
 
-        QName nodeType = null;
-
+        QName nodeType;
         final String nodeTypeStr = ctx.getChild(0).getText();
         final String[] splittedElement = nodeTypeStr.split(":");
         if (splittedElement.length == 1) {
-            nodeType = new QName(null, null, yangModelPrefix, splittedElement[0]);
+            nodeType = new QName(namespace, revision, yangModelPrefix, splittedElement[0]);
         } else {
-            nodeType = new QName(null, null, splittedElement[0], splittedElement[1]);
+            nodeType = new QName(namespace, revision, splittedElement[0], splittedElement[1]);
         }
 
         QName qname;
@@ -771,11 +809,14 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             qname = new QName(namespace, revision, yangModelPrefix, nodeParameter);
         }
 
-        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(line, qname);
+        addNodeToPath(new QName(namespace, revision, yangModelPrefix, nodeParameter));
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
+
+        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
         builder.setNodeType(nodeType);
         builder.setNodeParameter(nodeParameter);
-        actualPath.push(nodeParameter);
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+
+
         parseSchemaNodeArgs(ctx, builder);
         moduleBuilder.enterNode(builder);
     }
@@ -783,7 +824,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("unknown-node", actualPath.pop());
+        exitLog("unknown-node", removeNodeFromPath());
     }
 
     @Override
@@ -793,18 +834,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("rpc", rpcName, line);
 
         QName rpcQName = new QName(namespace, revision, yangModelPrefix, rpcName);
-        RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName);
+        addNodeToPath(rpcQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
+
+        RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
         moduleBuilder.enterNode(rpcBuilder);
-        actualPath.push(rpcName);
 
-        rpcBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+
         parseSchemaNodeArgs(ctx, rpcBuilder);
     }
 
     @Override
     public void exitRpc_stmt(YangParser.Rpc_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("rpc", actualPath.pop());
+        exitLog("rpc", removeNodeFromPath());
     }
 
     @Override
@@ -814,11 +857,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog(input, input, line);
 
         QName rpcQName = new QName(namespace, revision, yangModelPrefix, input);
-        SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, input);
+        addNodeToPath(rpcQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
 
         ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
         moduleBuilder.enterNode(builder);
-        actualPath.push(input);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
@@ -827,7 +870,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitInput_stmt(YangParser.Input_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("input", actualPath.pop());
+        exitLog("input", removeNodeFromPath());
     }
 
     @Override
@@ -837,11 +880,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog(output, output, line);
 
         QName rpcQName = new QName(namespace, revision, yangModelPrefix, output);
-        SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, output);
+        addNodeToPath(rpcQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
 
         ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
         moduleBuilder.enterNode(builder);
-        actualPath.push(output);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
@@ -850,7 +893,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitOutput_stmt(YangParser.Output_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("output", actualPath.pop());
+        exitLog("output", removeNodeFromPath());
     }
 
     @Override
@@ -860,18 +903,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("feature", featureName, line);
 
         QName featureQName = new QName(namespace, revision, yangModelPrefix, featureName);
-        FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName);
+        addNodeToPath(featureQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
+
+        FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
         moduleBuilder.enterNode(featureBuilder);
-        actualPath.push(featureName);
 
-        featureBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, featureBuilder);
     }
 
     @Override
     public void exitFeature_stmt(YangParser.Feature_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("feature", actualPath.pop());
+        exitLog("feature", removeNodeFromPath());
     }
 
     @Override
@@ -884,7 +928,6 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         String deviate = null;
         DeviationBuilder builder = moduleBuilder.addDeviation(line, targetPath);
         moduleBuilder.enterNode(builder);
-        actualPath.push(targetPath);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
@@ -907,7 +950,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitDeviation_stmt(YangParser.Deviation_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("deviation", actualPath.pop());
+        exitLog("deviation", "");
     }
 
     @Override
@@ -917,11 +960,13 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("identity", identityName, line);
 
         final QName identityQName = new QName(namespace, revision, yangModelPrefix, identityName);
-        IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, actualPath, line);
+        addNodeToPath(identityQName);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
+
+        IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
         moduleBuilder.enterNode(builder);
-        actualPath.push(identityName);
 
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+
         parseSchemaNodeArgs(ctx, builder);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -936,7 +981,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void exitIdentity_stmt(YangParser.Identity_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("identity", actualPath.pop());
+        exitLog("identity", removeNodeFromPath());
     }
 
     public ModuleBuilder getModuleBuilder() {
@@ -944,15 +989,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     private void enterLog(String p1, String p2, int line) {
-        logger.trace("entering {} {} ({})", p1, p2, line);
+        LOGGER.trace("entering {} {} ({})", p1, p2, line);
     }
 
     private void exitLog(String p1, String p2) {
-        logger.trace("exiting {} {}", p1, p2);
+        LOGGER.trace("exiting {} {}", p1, p2);
+    }
+
+    private void exitLog(String p1, QName p2) {
+        LOGGER.trace("exiting {} {}", p1, p2.getLocalName());
     }
 
     private void setLog(String p1, String p2) {
-        logger.trace("setting {} {}", p1, p2);
+        LOGGER.trace("setting {} {}", p1, p2);
     }
 
 }