Refactored YangModelParserImpl
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / main / java / org / opendaylight / controller / yang / model / parser / impl / YangModelParserListenerImpl.java
index 24f6b381b677032563392878c15277aee48f2680..7e64c6e41cc82fd27cd6b8a61125e60a863755f9 100644 (file)
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.yang.model.parser.impl;
-
-import static org.opendaylight.controller.yang.model.parser.util.YangModelBuilderUtil.*;
-
-import java.net.URI;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Stack;
-import java.util.TreeMap;
-
-import org.antlr.v4.runtime.tree.ParseTree;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Contact_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Container_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Description_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_add_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_delete_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_not_supported_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_replace_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Import_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Key_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Leaf_list_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Leaf_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.List_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Module_header_stmtsContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Namespace_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Ordered_by_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Organization_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Prefix_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Presence_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Reference_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_date_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_stmtsContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Type_body_stmtsContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Union_specificationContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yang_version_stmtContext;
-import org.opendaylight.controller.antlrv4.code.gen.YangParserBaseListener;
-import org.opendaylight.controller.yang.common.QName;
-import org.opendaylight.controller.yang.model.api.Status;
-import org.opendaylight.controller.yang.model.api.TypeDefinition;
-import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationSchemaBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.api.GroupingBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.ContainerSchemaNodeBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.DeviationBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.ExtensionBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.FeatureBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.LeafListSchemaNodeBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.LeafSchemaNodeBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.ListSchemaNodeBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.NotificationBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.RpcDefinitionBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.TypedefBuilder;
-import org.opendaylight.controller.yang.model.parser.builder.impl.UnknownSchemaNodeBuilder;
-import org.opendaylight.controller.yang.model.util.YangTypesConverter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class YangModelParserListenerImpl extends YangParserBaseListener {
-
-    private static final Logger logger = LoggerFactory
-            .getLogger(YangModelParserListenerImpl.class);
-
-    private ModuleBuilder moduleBuilder;
-
-    private String moduleName;
-    private URI namespace;
-    private String yangModelPrefix;
-    private Date revision;
-
-    private final DateFormat simpleDateFormat = new SimpleDateFormat(
-            "yyyy-mm-dd");
-    private final Stack<String> actualPath = new Stack<String>();
-
-
-    @Override
-    public void enterModule_stmt(YangParser.Module_stmtContext ctx) {
-        moduleName = stringFromNode(ctx);
-        actualPath.push(moduleName);
-        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) {
-                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 exitModule_stmt(YangParser.Module_stmtContext ctx) {
-        final String moduleName = actualPath.pop();
-        logger.debug("Exiting module " + moduleName);
-    }
-
-    @Override
-    public void enterModule_header_stmts(final Module_header_stmtsContext ctx) {
-        super.enterModule_header_stmts(ctx);
-
-        for (int i = 0; i < ctx.getChildCount(); ++i) {
-            final ParseTree treeNode = ctx.getChild(i);
-            if (treeNode instanceof Namespace_stmtContext) {
-                final String namespaceStr = stringFromNode(treeNode);
-                namespace = URI.create(namespaceStr);
-                moduleBuilder.setNamespace(namespace);
-            } else if (treeNode instanceof Prefix_stmtContext) {
-                yangModelPrefix = stringFromNode(treeNode);
-                moduleBuilder.setPrefix(yangModelPrefix);
-            } else if (treeNode instanceof Yang_version_stmtContext) {
-                final String yangVersion = stringFromNode(treeNode);
-                moduleBuilder.setYangVersion(yangVersion);
-            }
-        }
-    }
-
-    @Override
-    public void enterMeta_stmts(YangParser.Meta_stmtsContext ctx) {
-        for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
-            if (child instanceof Organization_stmtContext) {
-                final String organization = stringFromNode(child);
-                moduleBuilder.setOrganization(organization);
-            } else if (child instanceof Contact_stmtContext) {
-                final String contact = stringFromNode(child);
-                moduleBuilder.setContact(contact);
-            } else if (child instanceof Description_stmtContext) {
-                final String description = stringFromNode(child);
-                moduleBuilder.setDescription(description);
-            } else if (child instanceof Reference_stmtContext) {
-                final String reference = stringFromNode(child);
-                moduleBuilder.setReference(reference);
-            }
-        }
-    }
-
-    @Override
-    public void exitSubmodule_header_stmts(
-            YangParser.Submodule_header_stmtsContext ctx) {
-        final String submodule = actualPath.pop();
-        logger.debug("exiting submodule " + submodule);
-    }
-
-    @Override
-    public void enterRevision_stmts(Revision_stmtsContext ctx) {
-        TreeMap<Date, Revision_stmtContext> revisions = new TreeMap<Date, Revision_stmtContext>();
-
-        for (int i = 0; i < ctx.getChildCount(); ++i) {
-            final ParseTree treeNode = ctx.getChild(i);
-            if (treeNode instanceof Revision_stmtContext) {
-                final String revisionDateStr = stringFromNode(treeNode);
-                try {
-                    Date revision = simpleDateFormat.parse(revisionDateStr);
-                    revisions.put(revision, (Revision_stmtContext)treeNode);
-
-                } catch (ParseException e) {
-                    final String message = "Failed to parse revision string: "+ revisionDateStr;
-                    logger.warn(message);
-                }
-            }
-        }
-        if(revisions.size() > 0) {
-            Revision_stmtContext revisionCtx = revisions.firstEntry().getValue();
-            moduleBuilder.setRevision(revisions.firstKey());
-
-            for(int i = 0; i < revisionCtx.getChildCount(); i++) {
-                ParseTree child = revisionCtx.getChild(i);
-                if(child instanceof Reference_stmtContext) {
-                    moduleBuilder.setReference(stringFromNode(child));
-                }
-            }
-        }
-    }
-
-    @Override
-    public void enterImport_stmt(Import_stmtContext ctx) {
-        super.enterImport_stmt(ctx);
-
-        final String importName = stringFromNode(ctx);
-        String importPrefix = null;
-        Date importRevision = null;
-
-        for (int i = 0; i < ctx.getChildCount(); ++i) {
-            final ParseTree treeNode = ctx.getChild(i);
-            if (treeNode instanceof Prefix_stmtContext) {
-                importPrefix = stringFromNode(treeNode);
-            }
-            if (treeNode instanceof Revision_date_stmtContext) {
-                String importRevisionStr = stringFromNode(treeNode);
-                try {
-                    importRevision = simpleDateFormat.parse(importRevisionStr);
-                } catch(ParseException e) {
-                    logger.warn("Failed to parse import revision-date: "+ importRevisionStr);
-                }
-            }
-        }
-        moduleBuilder.addModuleImport(importName, importRevision, importPrefix);
-    }
-
-    @Override
-    public void enterAugment_stmt(YangParser.Augment_stmtContext ctx) {
-        final String augmentPath = stringFromNode(ctx);
-        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(
-                augmentPath, getActualPath());
-        updatePath(augmentPath);
-
-        for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
-            if (child instanceof Description_stmtContext) {
-                String desc = stringFromNode(child);
-                builder.setDescription(desc);
-            } else if (child instanceof Reference_stmtContext) {
-                String ref = stringFromNode(child);
-                builder.setReference(ref);
-            } else if (child instanceof Status_stmtContext) {
-                Status status = parseStatus((Status_stmtContext) child);
-                builder.setStatus(status);
-            }
-        }
-    }
-
-    @Override
-    public void exitAugment_stmt(YangParser.Augment_stmtContext ctx) {
-        final String augment = actualPath.pop();
-        logger.debug("exiting augment " + augment);
-    }
-
-    @Override
-    public void enterExtension_stmt(YangParser.Extension_stmtContext ctx) {
-        String argument = stringFromNode(ctx);
-        QName qname = new QName(namespace, revision, yangModelPrefix, argument);
-        ExtensionBuilder builder = moduleBuilder.addExtension(qname);
-        parseSchemaNodeArgs(ctx, builder);
-    }
-
-    @Override
-    public void enterTypedef_stmt(YangParser.Typedef_stmtContext ctx) {
-        String typedefName = stringFromNode(ctx);
-        QName typedefQName = new QName(namespace, revision, yangModelPrefix,
-                typedefName);
-        TypedefBuilder builder = moduleBuilder.addTypedef(typedefQName,
-                getActualPath());
-        updatePath(typedefName);
-
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision,
-                yangModelPrefix));
-        parseSchemaNodeArgs(ctx, builder);
-        builder.setUnits(parseUnits(ctx));
-    }
-
-    @Override
-    public void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @Override
-    public void enterType_stmt(YangParser.Type_stmtContext ctx) {
-        String typeName = stringFromNode(ctx);
-        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);
-            } else {
-                typeQName = new QName(null, null, prefix, name);
-            }
-        } else {
-            typeQName = new QName(namespace, revision, yangModelPrefix,
-                    typeName);
-        }
-
-        TypeDefinition<?> type = null;
-        Type_body_stmtsContext typeBody = null;
-        for (int i = 0; i < ctx.getChildCount(); i++) {
-            if (ctx.getChild(i) instanceof Type_body_stmtsContext) {
-                typeBody = (Type_body_stmtsContext) ctx.getChild(i);
-                break;
-            }
-        }
-
-
-
-        // if this is base yang type...
-        if(YangTypesConverter.isBaseYangType(typeName)) {
-            if (typeBody == null) {
-                // if there are no constraints, just grab default base yang type
-                type = YangTypesConverter.javaTypeForBaseYangType(typeName);
-                moduleBuilder.setType(type, actualPath);
-            } else {
-                if(typeName.equals("union")) {
-                    List<String> types = new ArrayList<String>();
-                    for(int i = 0; i < typeBody.getChildCount(); i++) {
-                        ParseTree unionSpec = typeBody.getChild(i);
-                        if(unionSpec instanceof Union_specificationContext) {
-                            for(int j = 0; j < unionSpec.getChildCount(); j++) {
-                                ParseTree typeSpec = unionSpec.getChild(j);
-                                types.add(stringFromNode(typeSpec));
-                            }
-                        }
-                    }
-                    moduleBuilder.addUnionType(actualPath);
-                } else {
-                    type = parseTypeBody(typeName, typeBody, actualPath, namespace, revision, yangModelPrefix);
-                    moduleBuilder.setType(type, actualPath);
-                }
-            }
-        } else {
-            type = parseUnknownTypeBody(typeQName, typeBody);
-            // mark parent node of this type statement as dirty
-            moduleBuilder.addDirtyNode(actualPath);
-            moduleBuilder.setType(type, actualPath);
-        }
-
-        updatePath(typeName);
-
-    }
-
-    @Override
-    public void exitType_stmt(YangParser.Type_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @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);
-        updatePath("grouping");
-        updatePath(groupName);
-        parseSchemaNodeArgs(ctx, groupBuilder);
-    }
-
-    @Override
-    public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {
-        String actContainer = actualPath.pop();
-        actContainer += "-" + actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @Override
-    public void enterContainer_stmt(Container_stmtContext ctx) {
-        super.enterContainer_stmt(ctx);
-        String containerName = stringFromNode(ctx);
-        QName containerQName = new QName(namespace, revision, yangModelPrefix,
-                containerName);
-        ContainerSchemaNodeBuilder containerBuilder = moduleBuilder
-                .addContainerNode(containerQName, actualPath);
-        updatePath(containerName);
-
-        containerBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, containerBuilder);
-        parseConstraints(ctx, containerBuilder.getConstraintsBuilder());
-
-        for (int i = 0; i < ctx.getChildCount(); ++i) {
-            final ParseTree childNode = ctx.getChild(i);
-            if (childNode instanceof Presence_stmtContext) {
-                containerBuilder.setPresenceContainer(true);
-                break;
-            }
-        }
-    }
-
-    @Override
-    public void exitContainer_stmt(Container_stmtContext ctx) {
-        super.exitContainer_stmt(ctx);
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @Override
-    public void enterLeaf_stmt(Leaf_stmtContext ctx) {
-        super.enterLeaf_stmt(ctx);
-
-        final String leafName = stringFromNode(ctx);
-        QName leafQName = new QName(namespace, revision, yangModelPrefix,
-                leafName);
-        LeafSchemaNodeBuilder leafBuilder = moduleBuilder.addLeafNode(
-                leafQName, actualPath);
-        updatePath(leafName);
-
-        leafBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, leafBuilder);
-        parseConstraints(ctx, leafBuilder.getConstraintsBuilder());
-    }
-
-    @Override
-    public void exitLeaf_stmt(YangParser.Leaf_stmtContext ctx) {
-        final String actLeaf = actualPath.pop();
-        logger.debug("exiting " + actLeaf);
-    }
-
-    @Override
-    public void enterUses_stmt(YangParser.Uses_stmtContext ctx) {
-        final String groupingPathStr = stringFromNode(ctx);
-        moduleBuilder.addUsesNode(groupingPathStr, actualPath);
-        updatePath(groupingPathStr);
-    }
-
-    @Override
-    public void exitUses_stmt(YangParser.Uses_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @Override
-    public void enterLeaf_list_stmt(Leaf_list_stmtContext ctx) {
-        super.enterLeaf_list_stmt(ctx);
-
-        final String leafListName = stringFromNode(ctx);
-        QName leafListQName = new QName(namespace, revision, yangModelPrefix,
-                leafListName);
-        LeafListSchemaNodeBuilder leafListBuilder = moduleBuilder
-                .addLeafListNode(leafListQName, actualPath);
-        updatePath(leafListName);
-
-        parseSchemaNodeArgs(ctx, leafListBuilder);
-        parseConstraints(ctx, leafListBuilder.getConstraintsBuilder());
-
-        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);
-                break;
-            }
-        }
-    }
-
-    @Override
-    public void exitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @Override
-    public void enterList_stmt(List_stmtContext ctx) {
-        super.enterList_stmt(ctx);
-
-        final String containerName = stringFromNode(ctx);
-        QName containerQName = new QName(namespace, revision, yangModelPrefix,
-                containerName);
-        ListSchemaNodeBuilder listBuilder = moduleBuilder.addListNode(
-                containerQName, actualPath);
-        updatePath(containerName);
-
-        listBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, listBuilder);
-        parseConstraints(ctx, listBuilder.getConstraintsBuilder());
-
-        String keyDefinition = "";
-        for (int i = 0; i < ctx.getChildCount(); ++i) {
-            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);
-                listBuilder.setUserOrdered(userOrdered);
-            } else if (childNode instanceof Key_stmtContext) {
-                keyDefinition = stringFromNode(childNode);
-                List<QName> key = createListKey(keyDefinition, namespace,
-                        revision, yangModelPrefix);
-                listBuilder.setKeyDefinition(key);
-            }
-        }
-    }
-
-    @Override
-    public void exitList_stmt(List_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @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);
-        updatePath(notificationName);
-
-        notificationBuilder.setPath(createActualSchemaPath(actualPath, namespace,
-                revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, notificationBuilder);
-    }
-
-    @Override
-    public void exitNotification_stmt(YangParser.Notification_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    // Unknown types
-    @Override
-    public void enterIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
-        String name = stringFromNode(ctx);
-
-        QName qname;
-        if(name != null) {
-            String[] splittedName = name.split(":");
-            if(splittedName.length == 2) {
-                qname = new QName(null, null, splittedName[0], splittedName[1]);
-            } else {
-                qname = new QName(namespace, revision, yangModelPrefix, splittedName[0]);
-            }
-        } else {
-            qname = new QName(namespace, revision, yangModelPrefix, name);
-        }
-
-        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(qname, getActualPath());
-        updatePath(name);
-
-        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, builder);
-    }
-
-    @Override
-    public void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @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);
-        updatePath(rpcName);
-
-        rpcBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision,
-                yangModelPrefix));
-        parseSchemaNodeArgs(ctx, rpcBuilder);
-    }
-
-    @Override
-    public void exitRpc_stmt(YangParser.Rpc_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @Override
-    public void enterInput_stmt(YangParser.Input_stmtContext ctx) {
-        updatePath("input");
-    }
-
-    @Override
-    public void exitInput_stmt(YangParser.Input_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @Override
-    public void enterOutput_stmt(YangParser.Output_stmtContext ctx) {
-        updatePath("output");
-    }
-
-    @Override
-    public void exitOutput_stmt(YangParser.Output_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @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);
-        updatePath(featureName);
-
-        featureBuilder.setPath(createActualSchemaPath(actualPath, namespace,
-                revision, yangModelPrefix));
-        parseSchemaNodeArgs(ctx, featureBuilder);
-    }
-
-    @Override
-    public void exitFeature_stmt(YangParser.Feature_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @Override
-    public void enterDeviation_stmt(YangParser.Deviation_stmtContext ctx) {
-        final String targetPath = stringFromNode(ctx);
-        String reference = null;
-        String deviate = null;
-        DeviationBuilder builder = moduleBuilder.addDeviation(targetPath);
-        updatePath(targetPath);
-
-        for (int i = 0; i < ctx.getChildCount(); i++) {
-            ParseTree child = ctx.getChild(i);
-            if (child instanceof Reference_stmtContext) {
-                reference = stringFromNode(child);
-            } else if (child instanceof Deviate_not_supported_stmtContext) {
-                deviate = stringFromNode(child);
-            } else if (child instanceof Deviate_add_stmtContext) {
-                deviate = stringFromNode(child);
-            } else if (child instanceof Deviate_replace_stmtContext) {
-                deviate = stringFromNode(child);
-            } else if (child instanceof Deviate_delete_stmtContext) {
-                deviate = stringFromNode(child);
-            }
-        }
-        builder.setReference(reference);
-        builder.setDeviate(deviate);
-    }
-
-    @Override
-    public void exitDeviation_stmt(YangParser.Deviation_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-    }
-
-    @Override
-    public void enterConfig_stmt(YangParser.Config_stmtContext ctx) {
-        boolean configuration = parseConfig(ctx);
-        moduleBuilder.addConfiguration(configuration, actualPath);
-    }
-
-    public ModuleBuilder getModuleBuilder() {
-        return moduleBuilder;
-    }
-
-    private void updatePath(String containerName) {
-        actualPath.push(containerName);
-    }
-
-    private List<String> getActualPath() {
-        return Collections.unmodifiableList(actualPath);
-    }
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.model.parser.impl;\r
+\r
+import static org.opendaylight.controller.yang.model.parser.util.YangModelBuilderUtil.*;\r
+\r
+import java.net.URI;\r
+import java.text.DateFormat;\r
+import java.text.ParseException;\r
+import java.text.SimpleDateFormat;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Stack;\r
+import java.util.TreeMap;\r
+\r
+import org.antlr.v4.runtime.tree.ParseTree;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Base_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Contact_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Container_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Description_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_add_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_delete_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_not_supported_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_replace_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Import_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Key_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Leaf_list_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Leaf_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.List_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Module_header_stmtsContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Namespace_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Ordered_by_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Organization_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Prefix_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Presence_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Reference_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_date_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_stmtsContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Type_body_stmtsContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Union_specificationContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yang_version_stmtContext;\r
+import org.opendaylight.controller.antlrv4.code.gen.YangParserBaseListener;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.Status;\r
+import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationSchemaBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.api.GroupingBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.ContainerSchemaNodeBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.DeviationBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.ExtensionBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.FeatureBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.IdentitySchemaNodeBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.LeafListSchemaNodeBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.LeafSchemaNodeBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.ListSchemaNodeBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.NotificationBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.RpcDefinitionBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.TypedefBuilder;\r
+import org.opendaylight.controller.yang.model.parser.builder.impl.UnknownSchemaNodeBuilder;\r
+import org.opendaylight.controller.yang.model.util.YangTypesConverter;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+final class YangModelParserListenerImpl extends YangParserBaseListener {\r
+\r
+    private static final Logger logger = LoggerFactory\r
+            .getLogger(YangModelParserListenerImpl.class);\r
+\r
+    private ModuleBuilder moduleBuilder;\r
+\r
+    private String moduleName;\r
+    private URI namespace;\r
+    private String yangModelPrefix;\r
+    private Date revision;\r
+\r
+    private final DateFormat simpleDateFormat = new SimpleDateFormat(\r
+            "yyyy-mm-dd");\r
+    private final Stack<String> actualPath = new Stack<String>();\r
+\r
+\r
+    @Override\r
+    public void enterModule_stmt(YangParser.Module_stmtContext ctx) {\r
+        moduleName = stringFromNode(ctx);\r
+        actualPath.push(moduleName);\r
+        moduleBuilder = new ModuleBuilder(moduleName);\r
+\r
+        String description = null;\r
+        String reference = null;\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Description_stmtContext) {\r
+                description = stringFromNode(child);\r
+            } else if (child instanceof Reference_stmtContext) {\r
+                reference = stringFromNode(child);\r
+            } else {\r
+                if (description != null && reference != null) {\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+        moduleBuilder.setDescription(description);\r
+        moduleBuilder.setReference(reference);\r
+    }\r
+\r
+    @Override\r
+    public void exitModule_stmt(YangParser.Module_stmtContext ctx) {\r
+        final String moduleName = actualPath.pop();\r
+        logger.debug("Exiting module " + moduleName);\r
+    }\r
+\r
+    @Override\r
+    public void enterModule_header_stmts(final Module_header_stmtsContext ctx) {\r
+        super.enterModule_header_stmts(ctx);\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            final ParseTree treeNode = ctx.getChild(i);\r
+            if (treeNode instanceof Namespace_stmtContext) {\r
+                final String namespaceStr = stringFromNode(treeNode);\r
+                namespace = URI.create(namespaceStr);\r
+                moduleBuilder.setNamespace(namespace);\r
+            } else if (treeNode instanceof Prefix_stmtContext) {\r
+                yangModelPrefix = stringFromNode(treeNode);\r
+                moduleBuilder.setPrefix(yangModelPrefix);\r
+            } else if (treeNode instanceof Yang_version_stmtContext) {\r
+                final String yangVersion = stringFromNode(treeNode);\r
+                moduleBuilder.setYangVersion(yangVersion);\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void enterMeta_stmts(YangParser.Meta_stmtsContext ctx) {\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Organization_stmtContext) {\r
+                final String organization = stringFromNode(child);\r
+                moduleBuilder.setOrganization(organization);\r
+            } else if (child instanceof Contact_stmtContext) {\r
+                final String contact = stringFromNode(child);\r
+                moduleBuilder.setContact(contact);\r
+            } else if (child instanceof Description_stmtContext) {\r
+                final String description = stringFromNode(child);\r
+                moduleBuilder.setDescription(description);\r
+            } else if (child instanceof Reference_stmtContext) {\r
+                final String reference = stringFromNode(child);\r
+                moduleBuilder.setReference(reference);\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitSubmodule_header_stmts(\r
+            YangParser.Submodule_header_stmtsContext ctx) {\r
+        final String submodule = actualPath.pop();\r
+        logger.debug("exiting submodule " + submodule);\r
+    }\r
+\r
+    @Override\r
+    public void enterRevision_stmts(Revision_stmtsContext ctx) {\r
+        TreeMap<Date, Revision_stmtContext> revisions = new TreeMap<Date, Revision_stmtContext>();\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            final ParseTree treeNode = ctx.getChild(i);\r
+            if (treeNode instanceof Revision_stmtContext) {\r
+                final String revisionDateStr = stringFromNode(treeNode);\r
+                try {\r
+                    Date revision = simpleDateFormat.parse(revisionDateStr);\r
+                    revisions.put(revision, (Revision_stmtContext)treeNode);\r
+\r
+                } catch (ParseException e) {\r
+                    final String message = "Failed to parse revision string: "+ revisionDateStr;\r
+                    logger.warn(message);\r
+                }\r
+            }\r
+        }\r
+        if(revisions.size() > 0) {\r
+            Revision_stmtContext revisionCtx = revisions.firstEntry().getValue();\r
+            moduleBuilder.setRevision(revisions.firstKey());\r
+\r
+            for(int i = 0; i < revisionCtx.getChildCount(); i++) {\r
+                ParseTree child = revisionCtx.getChild(i);\r
+                if(child instanceof Reference_stmtContext) {\r
+                    moduleBuilder.setReference(stringFromNode(child));\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void enterImport_stmt(Import_stmtContext ctx) {\r
+        super.enterImport_stmt(ctx);\r
+\r
+        final String importName = stringFromNode(ctx);\r
+        String importPrefix = null;\r
+        Date importRevision = null;\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            final ParseTree treeNode = ctx.getChild(i);\r
+            if (treeNode instanceof Prefix_stmtContext) {\r
+                importPrefix = stringFromNode(treeNode);\r
+            }\r
+            if (treeNode instanceof Revision_date_stmtContext) {\r
+                String importRevisionStr = stringFromNode(treeNode);\r
+                try {\r
+                    importRevision = simpleDateFormat.parse(importRevisionStr);\r
+                } catch(ParseException e) {\r
+                    logger.warn("Failed to parse import revision-date: "+ importRevisionStr);\r
+                }\r
+            }\r
+        }\r
+        moduleBuilder.addModuleImport(importName, importRevision, importPrefix);\r
+    }\r
+\r
+    @Override\r
+    public void enterAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
+        final String augmentPath = stringFromNode(ctx);\r
+        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(\r
+                augmentPath, getActualPath());\r
+        updatePath(augmentPath);\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Description_stmtContext) {\r
+                String desc = stringFromNode(child);\r
+                builder.setDescription(desc);\r
+            } else if (child instanceof Reference_stmtContext) {\r
+                String ref = stringFromNode(child);\r
+                builder.setReference(ref);\r
+            } else if (child instanceof Status_stmtContext) {\r
+                Status status = parseStatus((Status_stmtContext) child);\r
+                builder.setStatus(status);\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
+        final String augment = actualPath.pop();\r
+        logger.debug("exiting augment " + augment);\r
+    }\r
+\r
+    @Override\r
+    public void enterExtension_stmt(YangParser.Extension_stmtContext ctx) {\r
+        String argument = stringFromNode(ctx);\r
+        QName qname = new QName(namespace, revision, yangModelPrefix, argument);\r
+        ExtensionBuilder builder = moduleBuilder.addExtension(qname);\r
+        parseSchemaNodeArgs(ctx, builder);\r
+    }\r
+\r
+    @Override\r
+    public void enterTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
+        String typedefName = stringFromNode(ctx);\r
+        QName typedefQName = new QName(namespace, revision, yangModelPrefix,\r
+                typedefName);\r
+        TypedefBuilder builder = moduleBuilder.addTypedef(typedefQName,\r
+                getActualPath());\r
+        updatePath(typedefName);\r
+\r
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision,\r
+                yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, builder);\r
+        builder.setUnits(parseUnits(ctx));\r
+    }\r
+\r
+    @Override\r
+    public void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterType_stmt(YangParser.Type_stmtContext ctx) {\r
+        String typeName = stringFromNode(ctx);\r
+        QName typeQName;\r
+        if (typeName.contains(":")) {\r
+            String[] splittedName = typeName.split(":");\r
+            String prefix = splittedName[0];\r
+            String name = splittedName[1];\r
+            if (prefix.equals(yangModelPrefix)) {\r
+                typeQName = new QName(namespace, revision, prefix, name);\r
+            } else {\r
+                typeQName = new QName(null, null, prefix, name);\r
+            }\r
+        } else {\r
+            typeQName = new QName(namespace, revision, yangModelPrefix,\r
+                    typeName);\r
+        }\r
+\r
+        TypeDefinition<?> type = null;\r
+        Type_body_stmtsContext typeBody = null;\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            if (ctx.getChild(i) instanceof Type_body_stmtsContext) {\r
+                typeBody = (Type_body_stmtsContext) ctx.getChild(i);\r
+                break;\r
+            }\r
+        }\r
+\r
+        // if this is base yang type...\r
+        if(YangTypesConverter.isBaseYangType(typeName)) {\r
+            if (typeBody == null) {\r
+                // if there are no constraints, just grab default base yang type\r
+                type = YangTypesConverter.javaTypeForBaseYangType(typeName);\r
+                moduleBuilder.setType(type, actualPath);\r
+            } else {\r
+                if(typeName.equals("union")) {\r
+                    List<String> types = new ArrayList<String>();\r
+                    for(int i = 0; i < typeBody.getChildCount(); i++) {\r
+                        ParseTree unionSpec = typeBody.getChild(i);\r
+                        if(unionSpec instanceof Union_specificationContext) {\r
+                            for(int j = 0; j < unionSpec.getChildCount(); j++) {\r
+                                ParseTree typeSpec = unionSpec.getChild(j);\r
+                                types.add(stringFromNode(typeSpec));\r
+                            }\r
+                        }\r
+                    }\r
+                    moduleBuilder.addUnionType(actualPath);\r
+                } else {\r
+                    type = parseTypeBody(typeName, typeBody, actualPath, namespace, revision, yangModelPrefix);\r
+                    moduleBuilder.setType(type, actualPath);\r
+                }\r
+            }\r
+        } else {\r
+            type = parseUnknownTypeBody(typeQName, typeBody);\r
+            // mark parent node of this type statement as dirty\r
+            moduleBuilder.addDirtyNode(actualPath);\r
+            moduleBuilder.setType(type, actualPath);\r
+        }\r
+\r
+        updatePath(typeName);\r
+\r
+    }\r
+\r
+    @Override\r
+    public void exitType_stmt(YangParser.Type_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterGrouping_stmt(YangParser.Grouping_stmtContext ctx) {\r
+        final String groupName = stringFromNode(ctx);\r
+        QName groupQName = new QName(namespace, revision, yangModelPrefix,\r
+                groupName);\r
+        GroupingBuilder groupBuilder = moduleBuilder.addGrouping(groupQName,\r
+                actualPath);\r
+        updatePath("grouping");\r
+        updatePath(groupName);\r
+        parseSchemaNodeArgs(ctx, groupBuilder);\r
+    }\r
+\r
+    @Override\r
+    public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {\r
+        String actContainer = actualPath.pop();\r
+        actContainer += "-" + actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterContainer_stmt(Container_stmtContext ctx) {\r
+        super.enterContainer_stmt(ctx);\r
+        String containerName = stringFromNode(ctx);\r
+        QName containerQName = new QName(namespace, revision, yangModelPrefix,\r
+                containerName);\r
+        ContainerSchemaNodeBuilder containerBuilder = moduleBuilder\r
+                .addContainerNode(containerQName, actualPath);\r
+        updatePath(containerName);\r
+\r
+        containerBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, containerBuilder);\r
+        parseConstraints(ctx, containerBuilder.getConstraintsBuilder());\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            final ParseTree childNode = ctx.getChild(i);\r
+            if (childNode instanceof Presence_stmtContext) {\r
+                containerBuilder.setPresenceContainer(true);\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitContainer_stmt(Container_stmtContext ctx) {\r
+        super.exitContainer_stmt(ctx);\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterLeaf_stmt(Leaf_stmtContext ctx) {\r
+        super.enterLeaf_stmt(ctx);\r
+\r
+        final String leafName = stringFromNode(ctx);\r
+        QName leafQName = new QName(namespace, revision, yangModelPrefix,\r
+                leafName);\r
+        LeafSchemaNodeBuilder leafBuilder = moduleBuilder.addLeafNode(\r
+                leafQName, actualPath);\r
+        updatePath(leafName);\r
+\r
+        leafBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, leafBuilder);\r
+        parseConstraints(ctx, leafBuilder.getConstraintsBuilder());\r
+    }\r
+\r
+    @Override\r
+    public void exitLeaf_stmt(YangParser.Leaf_stmtContext ctx) {\r
+        final String actLeaf = actualPath.pop();\r
+        logger.debug("exiting " + actLeaf);\r
+    }\r
+\r
+    @Override\r
+    public void enterUses_stmt(YangParser.Uses_stmtContext ctx) {\r
+        final String groupingPathStr = stringFromNode(ctx);\r
+        moduleBuilder.addUsesNode(groupingPathStr, actualPath);\r
+        updatePath(groupingPathStr);\r
+    }\r
+\r
+    @Override\r
+    public void exitUses_stmt(YangParser.Uses_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterLeaf_list_stmt(Leaf_list_stmtContext ctx) {\r
+        super.enterLeaf_list_stmt(ctx);\r
+\r
+        final String leafListName = stringFromNode(ctx);\r
+        QName leafListQName = new QName(namespace, revision, yangModelPrefix,\r
+                leafListName);\r
+        LeafListSchemaNodeBuilder leafListBuilder = moduleBuilder\r
+                .addLeafListNode(leafListQName, actualPath);\r
+        updatePath(leafListName);\r
+\r
+        parseSchemaNodeArgs(ctx, leafListBuilder);\r
+        parseConstraints(ctx, leafListBuilder.getConstraintsBuilder());\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            final ParseTree childNode = ctx.getChild(i);\r
+            if (childNode instanceof Ordered_by_stmtContext) {\r
+                final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;\r
+                final boolean userOrdered = parseUserOrdered(orderedBy);\r
+                leafListBuilder.setUserOrdered(userOrdered);\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterList_stmt(List_stmtContext ctx) {\r
+        super.enterList_stmt(ctx);\r
+\r
+        final String containerName = stringFromNode(ctx);\r
+        QName containerQName = new QName(namespace, revision, yangModelPrefix,\r
+                containerName);\r
+        ListSchemaNodeBuilder listBuilder = moduleBuilder.addListNode(\r
+                containerQName, actualPath);\r
+        updatePath(containerName);\r
+\r
+        listBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, listBuilder);\r
+        parseConstraints(ctx, listBuilder.getConstraintsBuilder());\r
+\r
+        String keyDefinition = "";\r
+        for (int i = 0; i < ctx.getChildCount(); ++i) {\r
+            ParseTree childNode = ctx.getChild(i);\r
+            if (childNode instanceof Ordered_by_stmtContext) {\r
+                final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;\r
+                final boolean userOrdered = parseUserOrdered(orderedBy);\r
+                listBuilder.setUserOrdered(userOrdered);\r
+            } else if (childNode instanceof Key_stmtContext) {\r
+                keyDefinition = stringFromNode(childNode);\r
+                List<QName> key = createListKey(keyDefinition, namespace,\r
+                        revision, yangModelPrefix);\r
+                listBuilder.setKeyDefinition(key);\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitList_stmt(List_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterNotification_stmt(YangParser.Notification_stmtContext ctx) {\r
+        final String notificationName = stringFromNode(ctx);\r
+        QName notificationQName = new QName(namespace, revision,\r
+                yangModelPrefix, notificationName);\r
+        NotificationBuilder notificationBuilder = moduleBuilder\r
+                .addNotification(notificationQName, actualPath);\r
+        updatePath(notificationName);\r
+\r
+        notificationBuilder.setPath(createActualSchemaPath(actualPath, namespace,\r
+                revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, notificationBuilder);\r
+    }\r
+\r
+    @Override\r
+    public void exitNotification_stmt(YangParser.Notification_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    // Unknown types\r
+    @Override\r
+    public void enterIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {\r
+        String name = stringFromNode(ctx);\r
+\r
+        QName qname;\r
+        if(name != null) {\r
+            String[] splittedName = name.split(":");\r
+            if(splittedName.length == 2) {\r
+                qname = new QName(null, null, splittedName[0], splittedName[1]);\r
+            } else {\r
+                qname = new QName(namespace, revision, yangModelPrefix, splittedName[0]);\r
+            }\r
+        } else {\r
+            qname = new QName(namespace, revision, yangModelPrefix, name);\r
+        }\r
+\r
+        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(qname, getActualPath());\r
+        updatePath(name);\r
+\r
+        builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, builder);\r
+    }\r
+\r
+    @Override\r
+    public void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterRpc_stmt(YangParser.Rpc_stmtContext ctx) {\r
+        final String rpcName = stringFromNode(ctx);\r
+        QName rpcQName = new QName(namespace, revision, yangModelPrefix,\r
+                rpcName);\r
+        RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(rpcQName,\r
+                actualPath);\r
+        updatePath(rpcName);\r
+\r
+        rpcBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision,\r
+                yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, rpcBuilder);\r
+    }\r
+\r
+    @Override\r
+    public void exitRpc_stmt(YangParser.Rpc_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterInput_stmt(YangParser.Input_stmtContext ctx) {\r
+        updatePath("input");\r
+    }\r
+\r
+    @Override\r
+    public void exitInput_stmt(YangParser.Input_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterOutput_stmt(YangParser.Output_stmtContext ctx) {\r
+        updatePath("output");\r
+    }\r
+\r
+    @Override\r
+    public void exitOutput_stmt(YangParser.Output_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterFeature_stmt(YangParser.Feature_stmtContext ctx) {\r
+        final String featureName = stringFromNode(ctx);\r
+        QName featureQName = new QName(namespace, revision, yangModelPrefix,\r
+                featureName);\r
+        FeatureBuilder featureBuilder = moduleBuilder.addFeature(featureQName,\r
+                actualPath);\r
+        updatePath(featureName);\r
+\r
+        featureBuilder.setPath(createActualSchemaPath(actualPath, namespace,\r
+                revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, featureBuilder);\r
+    }\r
+\r
+    @Override\r
+    public void exitFeature_stmt(YangParser.Feature_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterDeviation_stmt(YangParser.Deviation_stmtContext ctx) {\r
+        final String targetPath = stringFromNode(ctx);\r
+        String reference = null;\r
+        String deviate = null;\r
+        DeviationBuilder builder = moduleBuilder.addDeviation(targetPath);\r
+        updatePath(targetPath);\r
+\r
+        for (int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if (child instanceof Reference_stmtContext) {\r
+                reference = stringFromNode(child);\r
+            } else if (child instanceof Deviate_not_supported_stmtContext) {\r
+                deviate = stringFromNode(child);\r
+            } else if (child instanceof Deviate_add_stmtContext) {\r
+                deviate = stringFromNode(child);\r
+            } else if (child instanceof Deviate_replace_stmtContext) {\r
+                deviate = stringFromNode(child);\r
+            } else if (child instanceof Deviate_delete_stmtContext) {\r
+                deviate = stringFromNode(child);\r
+            }\r
+        }\r
+        builder.setReference(reference);\r
+        builder.setDeviate(deviate);\r
+    }\r
+\r
+    @Override\r
+    public void exitDeviation_stmt(YangParser.Deviation_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    @Override\r
+    public void enterConfig_stmt(YangParser.Config_stmtContext ctx) {\r
+        boolean configuration = parseConfig(ctx);\r
+        moduleBuilder.addConfiguration(configuration, actualPath);\r
+    }\r
+\r
+    @Override\r
+    public void enterIdentity_stmt(YangParser.Identity_stmtContext ctx) {\r
+        final String identityName = stringFromNode(ctx);\r
+        final QName identityQName = new QName(namespace, revision,\r
+                yangModelPrefix, identityName);\r
+        IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName);\r
+        updatePath(identityName);\r
+\r
+        builder.setPath(createActualSchemaPath(actualPath, namespace,\r
+                revision, yangModelPrefix));\r
+        parseSchemaNodeArgs(ctx, builder);\r
+\r
+        for(int i = 0; i < ctx.getChildCount(); i++) {\r
+            ParseTree child = ctx.getChild(i);\r
+            if(child instanceof Base_stmtContext) {\r
+                String baseIdentityName = stringFromNode(child);\r
+                builder.setBaseIdentityName(baseIdentityName);\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void exitIdentity_stmt(YangParser.Identity_stmtContext ctx) {\r
+        final String actContainer = actualPath.pop();\r
+        logger.debug("exiting " + actContainer);\r
+    }\r
+\r
+    public ModuleBuilder getModuleBuilder() {\r
+        return moduleBuilder;\r
+    }\r
+\r
+    private void updatePath(String containerName) {\r
+        actualPath.push(containerName);\r
+    }\r
+\r
+    private List<String> getActualPath() {\r
+        return Collections.unmodifiableList(actualPath);\r
+    }\r
 
 }