Merge "HostTracker StaticHost changes"
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / main / java / org / opendaylight / controller / yang / parser / impl / YangParserListenerImpl.java
index fcc4cd0452a4a4a92401a928cd2de9b8bdeb4788..5bd46d1231aaa8f3bacad6b67efec62c7a6c87c5 100644 (file)
@@ -58,6 +58,8 @@ import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.util.YangTypesConverter;
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ChoiceCaseBuilder;
@@ -72,26 +74,22 @@ import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilde
 import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.NotificationBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.RpcDefinitionBuilder;
-import org.opendaylight.controller.yang.parser.builder.impl.TypedefBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.UnionTypeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 import org.opendaylight.controller.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 ModuleBuilder moduleBuilder;
-
     private String moduleName;
     private URI namespace;
     private String yangModelPrefix;
     private Date revision = new Date(0L);
 
-    public final static DateFormat simpleDateFormat = new SimpleDateFormat(
-            "yyyy-MM-dd");
+    public final static DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
     private final Stack<String> actualPath = new Stack<String>();
 
     @Override
@@ -171,8 +169,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     }
 
     @Override
-    public void exitSubmodule_header_stmts(
-            YangParser.Submodule_header_stmtsContext ctx) {
+    public void exitSubmodule_header_stmts(YangParser.Submodule_header_stmtsContext ctx) {
         final String submodule = actualPath.pop();
         logger.debug("exiting submodule " + submodule);
     }
@@ -204,8 +201,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 }
             }
         } catch (ParseException e) {
-            final String message = "Failed to parse revision string: "
-                    + revisionDateStr;
+            final String message = "Failed to parse revision string: " + revisionDateStr;
             logger.warn(message);
         }
     }
@@ -226,8 +222,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 try {
                     importRevision = simpleDateFormat.parse(importRevisionStr);
                 } catch (ParseException e) {
-                    logger.warn("Failed to parse import revision-date: "
-                            + importRevisionStr);
+                    logger.warn("Failed to parse import revision-date: " + importRevisionStr);
                 }
             }
         }
@@ -237,8 +232,8 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void enterAugment_stmt(YangParser.Augment_stmtContext ctx) {
         final String augmentPath = stringFromNode(ctx);
-        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(
-                augmentPath, actualPath, ctx.getStart().getLine());
+        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(augmentPath, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(augmentPath);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -263,14 +258,14 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitAugment_stmt(YangParser.Augment_stmtContext ctx) {
         final String augment = actualPath.pop();
         logger.debug("exiting augment " + augment);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterExtension_stmt(YangParser.Extension_stmtContext ctx) {
         final String extName = stringFromNode(ctx);
         QName qname = new QName(namespace, revision, yangModelPrefix, extName);
-        ExtensionBuilder builder = moduleBuilder.addExtension(qname, ctx
-                .getStart().getLine());
+        ExtensionBuilder builder = moduleBuilder.addExtension(qname, ctx.getStart().getLine());
         parseSchemaNodeArgs(ctx, builder);
 
         String argument = null;
@@ -290,14 +285,12 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void enterTypedef_stmt(YangParser.Typedef_stmtContext ctx) {
         final String typedefName = stringFromNode(ctx);
-        QName typedefQName = new QName(namespace, revision, yangModelPrefix,
-                typedefName);
-        TypedefBuilder builder = moduleBuilder.addTypedef(typedefQName,
-                actualPath, ctx.getStart().getLine());
+        QName typedefQName = new QName(namespace, revision, yangModelPrefix, typedefName);
+        TypeDefinitionBuilder builder = moduleBuilder.addTypedef(typedefQName, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(typedefName);
 
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision,
-                yangModelPrefix));
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
         builder.setUnits(parseUnits(ctx));
     }
@@ -306,6 +299,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
@@ -329,29 +323,28 @@ 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(actualPath, namespace, revision, typeName);
                 moduleBuilder.setType(type, actualPath);
             } else {
                 if ("union".equals(typeName)) {
-                    moduleBuilder.addUnionType(actualPath, namespace, revision,
-                            line);
+                    List<String> typePath = new ArrayList<String>(actualPath);
+                    typePath.add(typeName);
+                    SchemaPath p = createActualSchemaPath(typePath, namespace, revision, yangModelPrefix);
+                    UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(actualPath, namespace, revision, line);
+                    moduleBuilder.enterNode(unionBuilder);
+                    unionBuilder.setPath(p);
                 } else if ("identityref".equals(typeName)) {
-                    SchemaPath path = createActualSchemaPath(actualPath,
-                            namespace, revision, yangModelPrefix);
-                    moduleBuilder.addIdentityrefType(
-                            getIdentityrefBase(typeBody), actualPath, path,
-                            line);
+                    SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix);
+                    moduleBuilder.addIdentityrefType(getIdentityrefBase(typeBody), actualPath, path, line);
                 } else {
-                    List<String> typePath = new ArrayList<String>(actualPath);
-                    typePath.remove(0);
-                    type = parseTypeBody(typeName, typeBody, typePath,
-                            namespace, revision, yangModelPrefix);
+                    type = parseTypeBody(moduleName, typeName, typeBody, actualPath, namespace, revision,
+                            yangModelPrefix, moduleBuilder.getActualNode());
                     moduleBuilder.setType(type, actualPath);
                 }
             }
         } else {
-            type = parseUnknownTypeBody(typeQName, typeBody);
+            type = parseUnknownTypeBody(typeQName, typeBody, actualPath, namespace, revision, yangModelPrefix,
+                    moduleBuilder.getActualNode(), moduleBuilder);
             // mark parent node of this type statement as dirty
             moduleBuilder.addDirtyNode(actualPath);
             moduleBuilder.setType(type, actualPath);
@@ -372,8 +365,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 typeQName = new QName(null, null, prefix, name);
             }
         } else {
-            typeQName = new QName(namespace, revision, yangModelPrefix,
-                    typeName);
+            typeQName = new QName(namespace, revision, yangModelPrefix, typeName);
         }
         return typeQName;
     }
@@ -382,46 +374,48 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitType_stmt(YangParser.Type_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+
+        final String typeName = stringFromNode(ctx);
+        if ("union".equals(typeName)) {
+            moduleBuilder.exitNode();
+        }
     }
 
     @Override
     public void enterGrouping_stmt(YangParser.Grouping_stmtContext ctx) {
         final String groupName = stringFromNode(ctx);
-        QName groupQName = new QName(namespace, revision, yangModelPrefix,
-                groupName);
-        GroupingBuilder groupBuilder = moduleBuilder.addGrouping(groupQName,
-                actualPath, ctx.getStart().getLine());
-        updatePath("grouping");
+        QName groupQName = new QName(namespace, revision, yangModelPrefix, groupName);
+        GroupingBuilder builder = moduleBuilder.addGrouping(groupQName, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(groupName);
-        parseSchemaNodeArgs(ctx, groupBuilder);
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
     }
 
     @Override
     public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {
         String actContainer = actualPath.pop();
-        actContainer += "-" + actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterContainer_stmt(Container_stmtContext ctx) {
         final String containerName = stringFromNode(ctx);
-        QName containerQName = new QName(namespace, revision, yangModelPrefix,
-                containerName);
-        ContainerSchemaNodeBuilder containerBuilder = moduleBuilder
-                .addContainerNode(containerQName, actualPath, ctx.getStart()
-                        .getLine());
+        QName containerQName = new QName(namespace, revision, yangModelPrefix, containerName);
+        ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(containerQName, actualPath, ctx.getStart()
+                .getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(containerName);
 
-        containerBuilder.setPath(createActualSchemaPath(actualPath, namespace,
-                revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, containerBuilder);
-        parseConstraints(ctx, containerBuilder.getConstraints());
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
+        parseConstraints(ctx, builder.getConstraints());
 
         for (int i = 0; i < ctx.getChildCount(); ++i) {
             final ParseTree childNode = ctx.getChild(i);
             if (childNode instanceof Presence_stmtContext) {
-                containerBuilder.setPresence(true);
+                builder.setPresence(true);
                 break;
             }
         }
@@ -431,21 +425,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitContainer_stmt(Container_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterLeaf_stmt(Leaf_stmtContext ctx) {
         final String leafName = stringFromNode(ctx);
-        QName leafQName = new QName(namespace, revision, yangModelPrefix,
-                leafName);
-        LeafSchemaNodeBuilder leafBuilder = moduleBuilder.addLeafNode(
-                leafQName, actualPath, ctx.getStart().getLine());
+        QName leafQName = new QName(namespace, revision, yangModelPrefix, leafName);
+        LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(leafQName, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(leafName);
 
-        leafBuilder.setPath(createActualSchemaPath(actualPath, namespace,
-                revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, leafBuilder);
-        parseConstraints(ctx, leafBuilder.getConstraints());
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
+        parseConstraints(ctx, builder.getConstraints());
 
         String defaultStr = null;
         String unitsStr = null;
@@ -457,28 +450,32 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 unitsStr = stringFromNode(child);
             }
         }
-        leafBuilder.setDefaultStr(defaultStr);
-        leafBuilder.setUnits(unitsStr);
+        builder.setDefaultStr(defaultStr);
+        builder.setUnits(unitsStr);
     }
 
     @Override
     public void exitLeaf_stmt(YangParser.Leaf_stmtContext ctx) {
         final String actLeaf = actualPath.pop();
         logger.debug("exiting " + actLeaf);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterUses_stmt(YangParser.Uses_stmtContext ctx) {
         final String groupingPathStr = stringFromNode(ctx);
-        moduleBuilder.addUsesNode(groupingPathStr, actualPath, ctx.getStart()
-                .getLine());
+        UsesNodeBuilder builder = moduleBuilder.addUsesNode(groupingPathStr, actualPath, ctx.getStart().getLine());
+
+        moduleBuilder.enterNode(builder);
         updatePath(groupingPathStr);
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
     }
 
     @Override
     public void exitUses_stmt(YangParser.Uses_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
@@ -486,6 +483,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         String refineString = stringFromNode(ctx);
         RefineHolder refine = parseRefine(ctx);
         moduleBuilder.addRefine(refine, actualPath);
+        moduleBuilder.enterNode(refine);
         updatePath(refineString);
     }
 
@@ -493,27 +491,28 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitRefine_stmt(YangParser.Refine_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterLeaf_list_stmt(Leaf_list_stmtContext ctx) {
         final String leafListName = stringFromNode(ctx);
-        QName leafListQName = new QName(namespace, revision, yangModelPrefix,
-                leafListName);
-        LeafListSchemaNodeBuilder leafListBuilder = moduleBuilder
-                .addLeafListNode(leafListQName, actualPath, ctx.getStart()
-                        .getLine());
+        QName leafListQName = new QName(namespace, revision, yangModelPrefix, leafListName);
+        LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(leafListQName, actualPath, ctx.getStart()
+                .getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(leafListName);
 
-        parseSchemaNodeArgs(ctx, leafListBuilder);
-        parseConstraints(ctx, leafListBuilder.getConstraints());
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
+        parseConstraints(ctx, builder.getConstraints());
 
         for (int i = 0; i < ctx.getChildCount(); ++i) {
             final ParseTree childNode = ctx.getChild(i);
             if (childNode instanceof Ordered_by_stmtContext) {
                 final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;
                 final boolean userOrdered = parseUserOrdered(orderedBy);
-                leafListBuilder.setUserOrdered(userOrdered);
+                builder.setUserOrdered(userOrdered);
                 break;
             }
         }
@@ -523,21 +522,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterList_stmt(List_stmtContext ctx) {
         final String containerName = stringFromNode(ctx);
-        QName containerQName = new QName(namespace, revision, yangModelPrefix,
-                containerName);
-        ListSchemaNodeBuilder listBuilder = moduleBuilder.addListNode(
-                containerQName, actualPath, ctx.getStart().getLine());
+        QName containerQName = new QName(namespace, revision, yangModelPrefix, containerName);
+        ListSchemaNodeBuilder builder = moduleBuilder.addListNode(containerQName, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(containerName);
 
-        listBuilder.setPath(createActualSchemaPath(actualPath, namespace,
-                revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, listBuilder);
-        parseConstraints(ctx, listBuilder.getConstraints());
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
+        parseConstraints(ctx, builder.getConstraints());
 
         String keyDefinition = "";
         for (int i = 0; i < ctx.getChildCount(); ++i) {
@@ -545,12 +543,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             if (childNode instanceof Ordered_by_stmtContext) {
                 final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;
                 final boolean userOrdered = parseUserOrdered(orderedBy);
-                listBuilder.setUserOrdered(userOrdered);
+                builder.setUserOrdered(userOrdered);
             } else if (childNode instanceof Key_stmtContext) {
                 keyDefinition = stringFromNode(childNode);
-                List<QName> key = createListKey(keyDefinition, namespace,
-                        revision, yangModelPrefix);
-                listBuilder.setKeyDefinition(key);
+                List<QName> key = createListKey(keyDefinition, namespace, revision, yangModelPrefix);
+                builder.setKeyDefinition(key);
             }
         }
     }
@@ -559,49 +556,47 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitList_stmt(List_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterAnyxml_stmt(YangParser.Anyxml_stmtContext ctx) {
         final String anyXmlName = stringFromNode(ctx);
-        QName anyXmlQName = new QName(namespace, revision, yangModelPrefix,
-                anyXmlName);
-        AnyXmlBuilder anyXmlBuilder = moduleBuilder.addAnyXml(anyXmlQName,
-                actualPath, ctx.getStart().getLine());
+        QName anyXmlQName = new QName(namespace, revision, yangModelPrefix, anyXmlName);
+        AnyXmlBuilder builder = moduleBuilder.addAnyXml(anyXmlQName, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(anyXmlName);
 
-        anyXmlBuilder.setPath(createActualSchemaPath(actualPath, namespace,
-                revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, anyXmlBuilder);
-        parseConstraints(ctx, anyXmlBuilder.getConstraints());
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
+        parseConstraints(ctx, builder.getConstraints());
     }
 
     @Override
     public void exitAnyxml_stmt(YangParser.Anyxml_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterChoice_stmt(YangParser.Choice_stmtContext ctx) {
         final String choiceName = stringFromNode(ctx);
-        QName choiceQName = new QName(namespace, revision, yangModelPrefix,
-                choiceName);
-        ChoiceBuilder choiceBuilder = moduleBuilder.addChoice(choiceQName,
-                actualPath, ctx.getStart().getLine());
+        QName choiceQName = new QName(namespace, revision, yangModelPrefix, choiceName);
+        ChoiceBuilder builder = moduleBuilder.addChoice(choiceQName, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
 
         updatePath(choiceName);
-        choiceBuilder.setPath(createActualSchemaPath(actualPath, namespace,
-                revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, choiceBuilder);
-        parseConstraints(ctx, choiceBuilder.getConstraints());
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
+        parseConstraints(ctx, builder.getConstraints());
 
         // set 'default' case
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Default_stmtContext) {
                 String defaultCase = stringFromNode(child);
-                choiceBuilder.setDefaultCase(defaultCase);
+                builder.setDefaultCase(defaultCase);
                 break;
             }
         }
@@ -611,48 +606,47 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitChoice_stmt(YangParser.Choice_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterCase_stmt(YangParser.Case_stmtContext ctx) {
         final String caseName = stringFromNode(ctx);
-        QName choiceQName = new QName(namespace, revision, yangModelPrefix,
-                caseName);
-        ChoiceCaseBuilder caseBuilder = moduleBuilder.addCase(choiceQName,
-                actualPath, ctx.getStart().getLine());
+        QName choiceQName = new QName(namespace, revision, yangModelPrefix, caseName);
+        ChoiceCaseBuilder builder = moduleBuilder.addCase(choiceQName, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
 
         updatePath(caseName);
-        caseBuilder.setPath(createActualSchemaPath(actualPath, namespace,
-                revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, caseBuilder);
-        parseConstraints(ctx, caseBuilder.getConstraints());
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
+        parseConstraints(ctx, builder.getConstraints());
     }
 
     @Override
     public void exitCase_stmt(YangParser.Case_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterNotification_stmt(YangParser.Notification_stmtContext ctx) {
         final String notificationName = stringFromNode(ctx);
-        QName notificationQName = new QName(namespace, revision,
-                yangModelPrefix, notificationName);
-        NotificationBuilder notificationBuilder = moduleBuilder
-                .addNotification(notificationQName, actualPath, ctx.getStart()
-                        .getLine());
+        QName notificationQName = new QName(namespace, revision, yangModelPrefix, notificationName);
+        NotificationBuilder builder = moduleBuilder.addNotification(notificationQName, actualPath, ctx.getStart()
+                .getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(notificationName);
 
-        notificationBuilder.setPath(createActualSchemaPath(actualPath,
-                namespace, revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, notificationBuilder);
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
     }
 
     @Override
     public void exitNotification_stmt(YangParser.Notification_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     // Unknown types
@@ -664,11 +658,9 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         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(null, null, yangModelPrefix, splittedElement[0]);
         } else {
-            nodeType = new QName(null, null, splittedElement[0],
-                    splittedElement[1]);
+            nodeType = new QName(null, null, splittedElement[0], splittedElement[1]);
         }
 
         QName qname;
@@ -677,41 +669,38 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             if (splittedName.length == 2) {
                 qname = new QName(null, null, splittedName[0], splittedName[1]);
             } else {
-                qname = new QName(namespace, revision, yangModelPrefix,
-                        splittedName[0]);
+                qname = new QName(namespace, revision, yangModelPrefix, splittedName[0]);
             }
         } else {
-            qname = new QName(namespace, revision, yangModelPrefix,
-                    nodeParameter);
+            qname = new QName(namespace, revision, yangModelPrefix, nodeParameter);
         }
 
-        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(
-                qname, actualPath, ctx.getStart().getLine());
+        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(qname, actualPath, ctx.getStart()
+                .getLine());
         builder.setNodeType(nodeType);
         builder.setNodeParameter(nodeParameter);
         updatePath(nodeParameter);
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision,
-                yangModelPrefix));
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
+        moduleBuilder.enterNode(builder);
     }
 
     @Override
     public void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterRpc_stmt(YangParser.Rpc_stmtContext ctx) {
         final String rpcName = stringFromNode(ctx);
-        QName rpcQName = new QName(namespace, revision, yangModelPrefix,
-                rpcName);
-        RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(rpcQName,
-                actualPath, ctx.getStart().getLine());
+        QName rpcQName = new QName(namespace, revision, yangModelPrefix, rpcName);
+        RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(rpcQName, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(rpcBuilder);
         updatePath(rpcName);
 
-        rpcBuilder.setPath(createActualSchemaPath(actualPath, namespace,
-                revision, yangModelPrefix));
+        rpcBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, rpcBuilder);
     }
 
@@ -719,41 +708,58 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitRpc_stmt(YangParser.Rpc_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterInput_stmt(YangParser.Input_stmtContext ctx) {
-        updatePath("input");
+        final String input = "input";
+        QName rpcQName = new QName(namespace, revision, yangModelPrefix, input);
+        ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(rpcQName, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
+        updatePath(input);
+
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
+        parseConstraints(ctx, builder.getConstraints());
     }
 
     @Override
     public void exitInput_stmt(YangParser.Input_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterOutput_stmt(YangParser.Output_stmtContext ctx) {
-        updatePath("output");
+        final String output = "output";
+        QName rpcQName = new QName(namespace, revision, yangModelPrefix, output);
+        ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(rpcQName, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
+        updatePath(output);
+
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
+        parseSchemaNodeArgs(ctx, builder);
+        parseConstraints(ctx, builder.getConstraints());
     }
 
     @Override
     public void exitOutput_stmt(YangParser.Output_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterFeature_stmt(YangParser.Feature_stmtContext ctx) {
         final String featureName = stringFromNode(ctx);
-        QName featureQName = new QName(namespace, revision, yangModelPrefix,
-                featureName);
-        FeatureBuilder featureBuilder = moduleBuilder.addFeature(featureQName,
-                actualPath, ctx.getStart().getLine());
+        QName featureQName = new QName(namespace, revision, yangModelPrefix, featureName);
+        FeatureBuilder featureBuilder = moduleBuilder.addFeature(featureQName, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(featureBuilder);
         updatePath(featureName);
 
-        featureBuilder.setPath(createActualSchemaPath(actualPath, namespace,
-                revision, yangModelPrefix));
+        featureBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, featureBuilder);
     }
 
@@ -761,6 +767,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitFeature_stmt(YangParser.Feature_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
@@ -768,8 +775,8 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         final String targetPath = stringFromNode(ctx);
         String reference = null;
         String deviate = null;
-        DeviationBuilder builder = moduleBuilder.addDeviation(targetPath,
-                actualPath, ctx.getStart().getLine());
+        DeviationBuilder builder = moduleBuilder.addDeviation(targetPath, actualPath, ctx.getStart().getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(targetPath);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -794,25 +801,25 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitDeviation_stmt(YangParser.Deviation_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     @Override
     public void enterConfig_stmt(YangParser.Config_stmtContext ctx) {
         boolean configuration = parseConfig(ctx);
-        moduleBuilder.addConfiguration(configuration, actualPath);
+        moduleBuilder.addConfiguration(configuration, actualPath, ctx.getStart().getLine());
     }
 
     @Override
     public void enterIdentity_stmt(YangParser.Identity_stmtContext ctx) {
         final String identityName = stringFromNode(ctx);
-        final QName identityQName = new QName(namespace, revision,
-                yangModelPrefix, identityName);
-        IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(
-                identityQName, actualPath, ctx.getStart().getLine());
+        final QName identityQName = new QName(namespace, revision, yangModelPrefix, identityName);
+        IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, actualPath, ctx.getStart()
+                .getLine());
+        moduleBuilder.enterNode(builder);
         updatePath(identityName);
 
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision,
-                yangModelPrefix));
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -828,6 +835,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     public void exitIdentity_stmt(YangParser.Identity_stmtContext ctx) {
         final String actContainer = actualPath.pop();
         logger.debug("exiting " + actContainer);
+        moduleBuilder.exitNode();
     }
 
     public ModuleBuilder getModuleBuilder() {