Introduce moduleQName for sharing
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / YangParserListenerImpl.java
index cc4ac33d3afee232f834b229efdeb5cf1d557f95..55b610e1e3f7ceada209cf4fae926cf75848ac62 100644 (file)
@@ -7,31 +7,35 @@
  */
 package org.opendaylight.yangtools.yang.parser.impl;
 
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.checkMissingBody;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.createActualSchemaPath;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.createListKey;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getConfig;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getIdentityrefBase;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.parseConstraints;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.parseDefault;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.parseRefine;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.parseSchemaNodeArgs;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.parseStatus;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.parseTypeWithBody;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.parseUnits;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.parseUnknownTypeWithBody;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.parseUserOrdered;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.parseYinValue;
-import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.stringFromNode;
-
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.checkMissingBody;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.createListKey;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.getConfig;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.getIdentityrefBase;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseConstraints;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseDefault;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseRefine;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseSchemaNodeArgs;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseStatus;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseTypeWithBody;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUnits;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUnknownTypeWithBody;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUserOrdered;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseYinValue;
+import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.stringFromNode;
+
+import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
+import com.google.common.collect.Iterables;
+
 import java.net.URI;
 import java.text.DateFormat;
 import java.text.ParseException;
 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;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Argument_stmtContext;
@@ -69,9 +73,9 @@ 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.Builder;
+import org.opendaylight.yangtools.yang.parser.builder.api.ExtensionBuilder;
 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;
@@ -80,7 +84,6 @@ 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;
@@ -88,28 +91,27 @@ 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.RefineHolderImpl;
 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.util.RefineHolder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilderImpl;
 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 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 String sourcePath;
+    private QName moduleQName = new QName(null, new Date(0L), null, "dummy");
     private ModuleBuilder moduleBuilder;
     private String moduleName;
-    private URI namespace;
-    private String yangModelPrefix;
-    private Date revision = new Date(0L);
+    private int augmentOrder;
 
-    private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
-    private final Stack<Stack<QName>> actualPath = new Stack<>();
-
-    private void addNodeToPath(QName name) {
+    private void addNodeToPath(final QName name) {
         actualPath.peek().push(name);
     }
 
@@ -117,14 +119,18 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         return actualPath.peek().pop();
     }
 
-    public YangParserListenerImpl(String sourcePath) {
+    private SchemaPath currentSchemaPath() {
+        return SchemaPath.create(actualPath.peek(), true);
+    }
+
+    public YangParserListenerImpl(final String sourcePath) {
         this.sourcePath = sourcePath;
     }
 
     @Override
-    public void enterModule_stmt(YangParser.Module_stmtContext ctx) {
+    public void enterModule_stmt(final YangParser.Module_stmtContext ctx) {
         moduleName = stringFromNode(ctx);
-        LOGGER.trace("entering module " + moduleName);
+        LOGGER.trace("entering module {}", moduleName);
         enterLog("module", moduleName, 0);
         actualPath.push(new Stack<QName>());
 
@@ -149,14 +155,15 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitModule_stmt(YangParser.Module_stmtContext ctx) {
-        exitLog("module", "");
+    public void exitModule_stmt(final YangParser.Module_stmtContext ctx) {
+        exitLog("module");
         actualPath.pop();
     }
 
-    @Override public void enterSubmodule_stmt(YangParser.Submodule_stmtContext ctx) {
+    @Override
+    public void enterSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
         moduleName = stringFromNode(ctx);
-        LOGGER.trace("entering submodule " + moduleName);
+        LOGGER.trace("entering submodule {}", moduleName);
         enterLog("submodule", moduleName, 0);
         actualPath.push(new Stack<QName>());
 
@@ -180,28 +187,32 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         moduleBuilder.setReference(reference);
     }
 
-    @Override public void exitSubmodule_stmt(YangParser.Submodule_stmtContext ctx) {
-        exitLog("submodule", "");
+    @Override
+    public void exitSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
+        exitLog("submodule");
         actualPath.pop();
     }
 
-    @Override public void enterBelongs_to_stmt(YangParser.Belongs_to_stmtContext ctx) {
+    @Override
+    public void enterBelongs_to_stmt(final YangParser.Belongs_to_stmtContext ctx) {
         moduleBuilder.setBelongsTo(stringFromNode(ctx));
     }
 
     @Override
-    public void enterModule_header_stmts(Module_header_stmtsContext ctx) {
+    public void enterModule_header_stmts(final Module_header_stmtsContext ctx) {
         enterLog("module_header", "", ctx.getStart().getLine());
         String yangVersion = null;
         for (int i = 0; i < ctx.getChildCount(); ++i) {
             final ParseTree treeNode = ctx.getChild(i);
             if (treeNode instanceof Namespace_stmtContext) {
                 final String namespaceStr = stringFromNode(treeNode);
-                namespace = URI.create(namespaceStr);
-                moduleBuilder.setNamespace(namespace);
+                final URI namespace = URI.create(namespaceStr);
+                this.moduleQName = new QName(namespace, moduleQName.getRevision(), moduleQName.getPrefix(), moduleQName.getLocalName());
+                moduleBuilder.setQNameModule(moduleQName.getModule());
                 setLog("namespace", namespaceStr);
             } else if (treeNode instanceof Prefix_stmtContext) {
-                yangModelPrefix = stringFromNode(treeNode);
+                final String yangModelPrefix = stringFromNode(treeNode);
+                this.moduleQName = new QName(moduleQName.getNamespace(), moduleQName.getRevision(), yangModelPrefix, moduleQName.getLocalName());
                 moduleBuilder.setPrefix(yangModelPrefix);
                 setLog("prefix", yangModelPrefix);
             } else if (treeNode instanceof Yang_version_stmtContext) {
@@ -217,12 +228,12 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitModule_header_stmts(Module_header_stmtsContext ctx) {
-        exitLog("module_header", "");
+    public void exitModule_header_stmts(final Module_header_stmtsContext ctx) {
+        exitLog("module_header");
     }
 
     @Override
-    public void enterMeta_stmts(YangParser.Meta_stmtsContext ctx) {
+    public void enterMeta_stmts(final YangParser.Meta_stmtsContext ctx) {
         enterLog("meta_stmt", "", ctx.getStart().getLine());
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
@@ -247,12 +258,12 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitMeta_stmts(YangParser.Meta_stmtsContext ctx) {
-        exitLog("meta_stmt", "");
+    public void exitMeta_stmts(final YangParser.Meta_stmtsContext ctx) {
+        exitLog("meta_stmt");
     }
 
     @Override
-    public void enterRevision_stmts(Revision_stmtsContext ctx) {
+    public void enterRevision_stmts(final Revision_stmtsContext ctx) {
         enterLog("revisions", "", ctx.getStart().getLine());
         for (int i = 0; i < ctx.getChildCount(); ++i) {
             final ParseTree treeNode = ctx.getChild(i);
@@ -263,18 +274,18 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitRevision_stmts(Revision_stmtsContext ctx) {
-        exitLog("revisions", "");
+    public void exitRevision_stmts(final Revision_stmtsContext ctx) {
+        exitLog("revisions");
     }
 
     private void updateRevisionForRevisionStatement(final ParseTree treeNode) {
         final String revisionDateStr = stringFromNode(treeNode);
         try {
             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());
+            if ((revisionDate != null) && (this.moduleQName.getRevision().compareTo(revisionDate) < 0)) {
+                this.moduleQName = new QName(moduleQName.getNamespace(), revisionDate, moduleQName.getPrefix(), moduleQName.getLocalName());
+                moduleBuilder.setQNameModule(moduleQName.getModule());
+                setLog("revision", revisionDate.toString());
                 for (int i = 0; i < treeNode.getChildCount(); ++i) {
                     ParseTree child = treeNode.getChild(i);
                     if (child instanceof Reference_stmtContext) {
@@ -289,7 +300,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void enterImport_stmt(Import_stmtContext ctx) {
+    public void enterImport_stmt(final Import_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String importName = stringFromNode(ctx);
         enterLog("import", importName, line);
@@ -316,18 +327,18 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitImport_stmt(Import_stmtContext ctx) {
-        exitLog("import", "");
+    public void exitImport_stmt(final Import_stmtContext ctx) {
+        exitLog("import");
     }
 
     @Override
-    public void enterAugment_stmt(YangParser.Augment_stmtContext ctx) {
+    public void enterAugment_stmt(final YangParser.Augment_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String augmentPath = stringFromNode(ctx);
         enterLog(AUGMENT_STR, augmentPath, line);
         actualPath.push(new Stack<QName>());
 
-        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath);
+        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
@@ -346,20 +357,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitAugment_stmt(YangParser.Augment_stmtContext ctx) {
+    public void exitAugment_stmt(final YangParser.Augment_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog(AUGMENT_STR, "");
+        exitLog(AUGMENT_STR);
         actualPath.pop();
     }
 
     @Override
-    public void enterExtension_stmt(YangParser.Extension_stmtContext ctx) {
+    public void enterExtension_stmt(final YangParser.Extension_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String extName = stringFromNode(ctx);
         enterLog("extension", extName, line);
-        QName qname = new QName(namespace, revision, yangModelPrefix, extName);
+        QName qname = QName.create(moduleQName, extName);
         addNodeToPath(qname);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
         parseSchemaNodeArgs(ctx, builder);
@@ -381,19 +392,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitExtension_stmt(YangParser.Extension_stmtContext ctx) {
+    public void exitExtension_stmt(final YangParser.Extension_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("extension", removeNodeFromPath());
     }
 
     @Override
-    public void enterTypedef_stmt(YangParser.Typedef_stmtContext ctx) {
+    public void enterTypedef_stmt(final YangParser.Typedef_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String typedefName = stringFromNode(ctx);
         enterLog("typedef", typedefName, line);
-        QName typedefQName = new QName(namespace, revision, yangModelPrefix, typedefName);
+        QName typedefQName = QName.create(moduleQName, typedefName);
         addNodeToPath(typedefQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
         parseSchemaNodeArgs(ctx, builder);
@@ -404,20 +415,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {
+    public void exitTypedef_stmt(final YangParser.Typedef_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("typedef", removeNodeFromPath());
     }
 
     @Override
-    public void enterType_stmt(YangParser.Type_stmtContext ctx) {
+    public void enterType_stmt(final YangParser.Type_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String typeName = stringFromNode(ctx);
         enterLog("type", typeName, line);
 
         final QName typeQName = parseQName(typeName);
 
-        TypeDefinition<?> type = null;
+        TypeDefinition<?> type;
         Type_body_stmtsContext typeBody = null;
         for (int i = 0; i < ctx.getChildCount(); i++) {
             if (ctx.getChild(i) instanceof Type_body_stmtsContext) {
@@ -427,41 +438,39 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         }
 
         // if this is base yang type...
-        if (YangTypesConverter.isBaseYangType(typeName)) {
+        if (BaseTypes.isYangBuildInType(typeName)) {
             if (typeBody == null) {
                 // 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(typeName);
+                type = BaseTypes.defaultBaseTypeFor(typeName).orNull();
                 addNodeToPath(type.getQName());
                 moduleBuilder.setType(type);
             } else {
                 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());
+                case "union":
+                    qname = BaseTypes.UNION_QNAME;
+                    addNodeToPath(qname);
+                    UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, moduleQName.getModule());
+                    Builder parent = moduleBuilder.getActualNode();
+                    unionBuilder.setParent(parent);
+                    moduleBuilder.enterNode(unionBuilder);
+                    break;
+                case "identityref":
+                    qname = BaseTypes.IDENTITYREF_QNAME;
+                    addNodeToPath(qname);
+                    SchemaPath path = currentSchemaPath();
+                    moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
+                    break;
+                default:
+                    type = parseTypeWithBody(typeName, typeBody, currentSchemaPath(), moduleQName, moduleBuilder.getActualNode());
+                    moduleBuilder.setType(type);
+                    addNodeToPath(type.getQName());
                 }
             }
         } else {
-            type = parseUnknownTypeWithBody(typeQName, typeBody, actualPath.peek(), namespace, revision,
-                    yangModelPrefix, moduleBuilder.getActualNode());
+            type = parseUnknownTypeWithBody(typeQName, typeBody, currentSchemaPath(), moduleQName, moduleBuilder.getActualNode());
             // add parent node of this type statement to dirty nodes
             moduleBuilder.markActualNodeDirty();
             moduleBuilder.setType(type);
@@ -470,25 +479,25 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     }
 
-    private QName parseQName(String typeName) {
-        QName typeQName;
-        if (typeName.contains(":")) {
-            String[] splittedName = typeName.split(":");
-            String prefix = splittedName[0];
-            String name = splittedName[1];
-            if (prefix.equals(yangModelPrefix)) {
-                typeQName = new QName(namespace, revision, prefix, name);
+    private QName parseQName(final String typeName) {
+        final QName typeQName;
+        if (typeName.indexOf(':') != -1) {
+            final Iterator<String> split = COLON_SPLITTER.split(typeName).iterator();
+            final String prefix = split.next();
+            final String name = split.next();
+            if (prefix.equals(moduleQName.getPrefix())) {
+                typeQName = QName.create(moduleQName, name);
             } else {
                 typeQName = new QName(null, null, prefix, name);
             }
         } else {
-            typeQName = new QName(namespace, revision, yangModelPrefix, typeName);
+            typeQName = QName.create(moduleQName, typeName);
         }
         return typeQName;
     }
 
     @Override
-    public void exitType_stmt(YangParser.Type_stmtContext ctx) {
+    public void exitType_stmt(final YangParser.Type_stmtContext ctx) {
         final String typeName = stringFromNode(ctx);
         if ("union".equals(typeName)) {
             moduleBuilder.exitNode();
@@ -497,13 +506,13 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void enterGrouping_stmt(YangParser.Grouping_stmtContext ctx) {
+    public void enterGrouping_stmt(final YangParser.Grouping_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String groupName = stringFromNode(ctx);
         enterLog("grouping", groupName, line);
-        QName groupQName = new QName(namespace, revision, yangModelPrefix, groupName);
+        QName groupQName = QName.create(moduleQName, groupName);
         addNodeToPath(groupQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
         parseSchemaNodeArgs(ctx, builder);
@@ -512,20 +521,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {
+    public void exitGrouping_stmt(final YangParser.Grouping_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("grouping", removeNodeFromPath());
     }
 
     @Override
-    public void enterContainer_stmt(Container_stmtContext ctx) {
+    public void enterContainer_stmt(final Container_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String containerName = stringFromNode(ctx);
         enterLog("container", containerName, line);
 
-        QName containerQName = new QName(namespace, revision, yangModelPrefix, containerName);
+        QName containerQName = QName.create(moduleQName, containerName);
         addNodeToPath(containerQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
         parseSchemaNodeArgs(ctx, builder);
@@ -544,20 +553,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitContainer_stmt(Container_stmtContext ctx) {
+    public void exitContainer_stmt(final Container_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("container", removeNodeFromPath());
     }
 
     @Override
-    public void enterLeaf_stmt(Leaf_stmtContext ctx) {
+    public void enterLeaf_stmt(final Leaf_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String leafName = stringFromNode(ctx);
         enterLog("leaf", leafName, line);
 
-        QName leafQName = new QName(namespace, revision, yangModelPrefix, leafName);
+        QName leafQName = QName.create(moduleQName, leafName);
         addNodeToPath(leafQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
         parseSchemaNodeArgs(ctx, builder);
@@ -581,13 +590,13 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitLeaf_stmt(YangParser.Leaf_stmtContext ctx) {
+    public void exitLeaf_stmt(final YangParser.Leaf_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("leaf", removeNodeFromPath());
     }
 
     @Override
-    public void enterUses_stmt(YangParser.Uses_stmtContext ctx) {
+    public void enterUses_stmt(final YangParser.Uses_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String groupingPathStr = stringFromNode(ctx);
         enterLog("uses", groupingPathStr, line);
@@ -598,19 +607,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitUses_stmt(YangParser.Uses_stmtContext ctx) {
+    public void exitUses_stmt(final YangParser.Uses_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("uses", "");
+        exitLog("uses");
     }
 
     @Override
-    public void enterUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {
+    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);
 
-        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath);
+        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
@@ -629,36 +638,36 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {
+    public void exitUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog(AUGMENT_STR, "");
+        exitLog(AUGMENT_STR);
         actualPath.pop();
     }
 
     @Override
-    public void enterRefine_stmt(YangParser.Refine_stmtContext ctx) {
+    public void enterRefine_stmt(final YangParser.Refine_stmtContext ctx) {
         final String refineString = stringFromNode(ctx);
         enterLog("refine", refineString, ctx.getStart().getLine());
 
-        RefineHolder refine = parseRefine(ctx, moduleName);
+        RefineHolderImpl refine = parseRefine(ctx, moduleName);
         moduleBuilder.addRefine(refine);
         moduleBuilder.enterNode(refine);
     }
 
     @Override
-    public void exitRefine_stmt(YangParser.Refine_stmtContext ctx) {
+    public void exitRefine_stmt(final YangParser.Refine_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("refine", "");
+        exitLog("refine");
     }
 
     @Override
-    public void enterLeaf_list_stmt(Leaf_list_stmtContext ctx) {
+    public void enterLeaf_list_stmt(final Leaf_list_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String leafListName = stringFromNode(ctx);
         enterLog("leaf-list", leafListName, line);
-        QName leafListQName = new QName(namespace, revision, yangModelPrefix, leafListName);
+        QName leafListQName = QName.create(moduleQName, leafListName);
         addNodeToPath(leafListQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
         moduleBuilder.enterNode(builder);
@@ -679,20 +688,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {
+    public void exitLeaf_list_stmt(final YangParser.Leaf_list_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("leaf-list", removeNodeFromPath());
     }
 
     @Override
-    public void enterList_stmt(List_stmtContext ctx) {
+    public void enterList_stmt(final List_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String listName = stringFromNode(ctx);
         enterLog("list", listName, line);
 
-        QName listQName = new QName(namespace, revision, yangModelPrefix, listName);
+        QName listQName = QName.create(moduleQName, listName);
         addNodeToPath(listQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
         moduleBuilder.enterNode(builder);
@@ -715,20 +724,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitList_stmt(List_stmtContext ctx) {
+    public void exitList_stmt(final List_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("list", removeNodeFromPath());
     }
 
     @Override
-    public void enterAnyxml_stmt(YangParser.Anyxml_stmtContext ctx) {
+    public void enterAnyxml_stmt(final YangParser.Anyxml_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String anyXmlName = stringFromNode(ctx);
         enterLog("anyxml", anyXmlName, line);
 
-        QName anyXmlQName = new QName(namespace, revision, yangModelPrefix, anyXmlName);
+        QName anyXmlQName = QName.create(moduleQName, anyXmlName);
         addNodeToPath(anyXmlQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
         moduleBuilder.enterNode(builder);
@@ -739,20 +748,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitAnyxml_stmt(YangParser.Anyxml_stmtContext ctx) {
+    public void exitAnyxml_stmt(final YangParser.Anyxml_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("anyxml", removeNodeFromPath());
     }
 
     @Override
-    public void enterChoice_stmt(YangParser.Choice_stmtContext ctx) {
+    public void enterChoice_stmt(final YangParser.Choice_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String choiceName = stringFromNode(ctx);
         enterLog("choice", choiceName, line);
 
-        QName choiceQName = new QName(namespace, revision, yangModelPrefix, choiceName);
+        QName choiceQName = QName.create(moduleQName, choiceName);
         addNodeToPath(choiceQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
         moduleBuilder.enterNode(builder);
@@ -773,20 +782,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitChoice_stmt(YangParser.Choice_stmtContext ctx) {
+    public void exitChoice_stmt(final YangParser.Choice_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("choice", removeNodeFromPath());
     }
 
     @Override
-    public void enterCase_stmt(YangParser.Case_stmtContext ctx) {
+    public void enterCase_stmt(final YangParser.Case_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String caseName = stringFromNode(ctx);
         enterLog("case", caseName, line);
 
-        QName caseQName = new QName(namespace, revision, yangModelPrefix, caseName);
+        QName caseQName = QName.create(moduleQName, caseName);
         addNodeToPath(caseQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
         moduleBuilder.enterNode(builder);
@@ -796,20 +805,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitCase_stmt(YangParser.Case_stmtContext ctx) {
+    public void exitCase_stmt(final YangParser.Case_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("case", removeNodeFromPath());
     }
 
     @Override
-    public void enterNotification_stmt(YangParser.Notification_stmtContext ctx) {
+    public void enterNotification_stmt(final YangParser.Notification_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String notificationName = stringFromNode(ctx);
         enterLog("notification", notificationName, line);
 
-        QName notificationQName = new QName(namespace, revision, yangModelPrefix, notificationName);
+        QName notificationQName = QName.create(moduleQName, notificationName);
         addNodeToPath(notificationQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
         moduleBuilder.enterNode(builder);
@@ -818,59 +827,59 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitNotification_stmt(YangParser.Notification_stmtContext ctx) {
+    public void exitNotification_stmt(final YangParser.Notification_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("notification", removeNodeFromPath());
     }
 
     // Unknown nodes
     @Override
-    public void enterIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
+    public void enterIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
         handleUnknownNode(ctx.getStart().getLine(), ctx);
     }
 
     @Override
-    public void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
+    public void exitIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("unknown-node", removeNodeFromPath());
     }
 
-    @Override public void enterUnknown_statement(YangParser.Unknown_statementContext ctx) {
+    @Override public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
         handleUnknownNode(ctx.getStart().getLine(), ctx);
     }
 
-    @Override public void exitUnknown_statement(YangParser.Unknown_statementContext ctx) {
+    @Override public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
         moduleBuilder.exitNode();
         exitLog("unknown-node", removeNodeFromPath());
     }
 
-    @Override public void enterUnknown_statement2(YangParser.Unknown_statement2Context ctx) {
+    @Override public void enterUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
         handleUnknownNode(ctx.getStart().getLine(), ctx);
     }
 
-    @Override public void exitUnknown_statement2(YangParser.Unknown_statement2Context ctx) {
+    @Override public void exitUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
         moduleBuilder.exitNode();
         exitLog("unknown-node", removeNodeFromPath());
     }
 
-    @Override public void enterUnknown_statement3(YangParser.Unknown_statement3Context ctx) {
+    @Override public void enterUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
         handleUnknownNode(ctx.getStart().getLine(), ctx);
     }
 
-    @Override public void exitUnknown_statement3(YangParser.Unknown_statement3Context ctx) {
+    @Override public void exitUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
         moduleBuilder.exitNode();
         exitLog("unknown-node", removeNodeFromPath());
     }
 
     @Override
-    public void enterRpc_stmt(YangParser.Rpc_stmtContext ctx) {
+    public void enterRpc_stmt(final YangParser.Rpc_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String rpcName = stringFromNode(ctx);
         enterLog("rpc", rpcName, line);
 
-        QName rpcQName = new QName(namespace, revision, yangModelPrefix, rpcName);
+        QName rpcQName = QName.create(moduleQName, rpcName);
         addNodeToPath(rpcQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
         moduleBuilder.enterNode(rpcBuilder);
@@ -880,20 +889,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitRpc_stmt(YangParser.Rpc_stmtContext ctx) {
+    public void exitRpc_stmt(final YangParser.Rpc_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("rpc", removeNodeFromPath());
     }
 
     @Override
-    public void enterInput_stmt(YangParser.Input_stmtContext ctx) {
+    public void enterInput_stmt(final YangParser.Input_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String input = "input";
         enterLog(input, input, line);
 
-        QName rpcQName = new QName(namespace, revision, yangModelPrefix, input);
+        QName rpcQName = QName.create(moduleQName, input);
         addNodeToPath(rpcQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
         moduleBuilder.enterNode(builder);
@@ -904,20 +913,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitInput_stmt(YangParser.Input_stmtContext ctx) {
+    public void exitInput_stmt(final YangParser.Input_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("input", removeNodeFromPath());
     }
 
     @Override
-    public void enterOutput_stmt(YangParser.Output_stmtContext ctx) {
+    public void enterOutput_stmt(final YangParser.Output_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String output = "output";
         enterLog(output, output, line);
 
-        QName rpcQName = new QName(namespace, revision, yangModelPrefix, output);
+        QName rpcQName = QName.create(moduleQName, output);
         addNodeToPath(rpcQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
         moduleBuilder.enterNode(builder);
@@ -928,20 +937,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitOutput_stmt(YangParser.Output_stmtContext ctx) {
+    public void exitOutput_stmt(final YangParser.Output_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("output", removeNodeFromPath());
     }
 
     @Override
-    public void enterFeature_stmt(YangParser.Feature_stmtContext ctx) {
+    public void enterFeature_stmt(final YangParser.Feature_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String featureName = stringFromNode(ctx);
         enterLog("feature", featureName, line);
 
-        QName featureQName = new QName(namespace, revision, yangModelPrefix, featureName);
+        QName featureQName = QName.create(moduleQName, featureName);
         addNodeToPath(featureQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
         moduleBuilder.enterNode(featureBuilder);
@@ -950,13 +959,13 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitFeature_stmt(YangParser.Feature_stmtContext ctx) {
+    public void exitFeature_stmt(final YangParser.Feature_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("feature", removeNodeFromPath());
     }
 
     @Override
-    public void enterDeviation_stmt(YangParser.Deviation_stmtContext ctx) {
+    public void enterDeviation_stmt(final YangParser.Deviation_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String targetPath = stringFromNode(ctx);
         enterLog("deviation", targetPath, line);
@@ -985,25 +994,24 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitDeviation_stmt(YangParser.Deviation_stmtContext ctx) {
+    public void exitDeviation_stmt(final YangParser.Deviation_stmtContext ctx) {
         moduleBuilder.exitNode();
-        exitLog("deviation", "");
+        exitLog("deviation");
     }
 
     @Override
-    public void enterIdentity_stmt(YangParser.Identity_stmtContext ctx) {
+    public void enterIdentity_stmt(final YangParser.Identity_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String identityName = stringFromNode(ctx);
         enterLog("identity", identityName, line);
 
-        final QName identityQName = new QName(namespace, revision, yangModelPrefix, identityName);
+        final QName identityQName = QName.create(moduleQName, identityName);
         addNodeToPath(identityQName);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
         IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
         moduleBuilder.enterNode(builder);
 
-
         parseSchemaNodeArgs(ctx, builder);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -1016,7 +1024,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitIdentity_stmt(YangParser.Identity_stmtContext ctx) {
+    public void exitIdentity_stmt(final YangParser.Identity_stmtContext ctx) {
         moduleBuilder.exitNode();
         exitLog("identity", removeNodeFromPath());
     }
@@ -1025,19 +1033,19 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         return moduleBuilder;
     }
 
-    private void enterLog(String p1, String p2, int line) {
+    private void enterLog(final String p1, final String p2, final int line) {
         LOGGER.trace("entering {} {} ({})", p1, p2, line);
     }
 
-    private void exitLog(String p1, String p2) {
-        LOGGER.trace("exiting {} {}", p1, p2);
+    private void exitLog(final String p1) {
+        LOGGER.trace("exiting {}", p1);
     }
 
-    private void exitLog(String p1, QName p2) {
+    private void exitLog(final String p1, final QName p2) {
         LOGGER.trace("exiting {} {}", p1, p2.getLocalName());
     }
 
-    private void setLog(String p1, String p2) {
+    private void setLog(final String p1, final String p2) {
         LOGGER.trace("setting {} {}", p1, p2);
     }
 
@@ -1045,35 +1053,37 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final String nodeParameter = stringFromNode(ctx);
         enterLog("unknown-node", nodeParameter, line);
 
-        QName nodeType;
         final String nodeTypeStr = ctx.getChild(0).getText();
-        final String[] splittedElement = nodeTypeStr.split(":");
-        if (splittedElement.length == 1) {
-            nodeType = new QName(namespace, revision, yangModelPrefix, splittedElement[0]);
+        final Iterator<String> splittedElement = COLON_SPLITTER.split(nodeTypeStr).iterator();
+        final String e0 = splittedElement.next();
+        final QName nodeType;
+        if (splittedElement.hasNext()) {
+            nodeType = new QName(moduleQName.getNamespace(), moduleQName.getRevision(), e0, splittedElement.next());
         } else {
-            nodeType = new QName(namespace, revision, splittedElement[0], splittedElement[1]);
+            nodeType = QName.create(moduleQName, e0);
         }
 
-        QName qname = null;
+        QName qname;
         try {
             if (!Strings.isNullOrEmpty(nodeParameter)) {
-                String[] splittedName = nodeParameter.split(":");
-                if (splittedName.length == 2) {
-                    qname = new QName(null, null, splittedName[0], splittedName[1]);
+                final Iterable<String> splittedName = COLON_SPLITTER.split(nodeParameter);
+                final Iterator<String> it = splittedName.iterator();
+
+                if (Iterables.size(splittedName) == 2) {
+                    qname = new QName(null, null, it.next(), it.next());
                 } else {
-                    qname = new QName(namespace, revision, yangModelPrefix, splittedName[0]);
+                    qname = QName.create(moduleQName, it.next());
                 }
             } else {
                 qname = nodeType;
             }
         } catch (IllegalArgumentException e) {
             qname = nodeType;
-
         }
         addNodeToPath(qname);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+        SchemaPath path = currentSchemaPath();
 
-        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
+        UnknownSchemaNodeBuilderImpl builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
         builder.setNodeType(nodeType);
         builder.setNodeParameter(nodeParameter);