BUG-865: deprecate pre-Beryllium parser elements
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / YangParserImpl.java
index 38055d908df31608a5a3d100c8976fc69f0c182c..b25986d34db17c3b1fb089c331f525b9df9bc54c 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * 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
@@ -10,15 +11,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.fillAugmentTarget;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findBaseIdentity;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findModuleFromContext;
-import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findSchemaNode;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findSchemaNodeInModule;
+import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findTargetNode;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.processAugmentation;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveType;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeUnion;
-
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.base.Splitter;
 import com.google.common.collect.HashBiMap;
 import com.google.common.io.ByteSource;
 import java.io.File;
@@ -35,6 +34,7 @@ import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.NavigableMap;
 import java.util.Set;
 import java.util.TreeMap;
 import javax.annotation.concurrent.Immutable;
@@ -47,11 +47,17 @@ import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
@@ -84,10 +90,13 @@ import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * @deprecated Pre-Beryllium implementation, scheduled for removal.
+ */
+@Deprecated
 @Immutable
 public final class YangParserImpl implements YangContextParser {
     private static final Logger LOG = LoggerFactory.getLogger(YangParserImpl.class);
-    private static final Splitter COLON_SPLITTER = Splitter.on(':');
     private static final YangParserImpl INSTANCE = new YangParserImpl();
 
     public static YangParserImpl getInstance() {
@@ -137,7 +146,7 @@ public final class YangParserImpl implements YangContextParser {
 
         // module builders sorted by dependencies
         List<ModuleBuilder> sortedBuilders = ModuleDependencySort.sort(resolved);
-        LinkedHashMap<URI, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sortedBuilders, null);
+        Map<URI, NavigableMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sortedBuilders, null);
         Collection<Module> unsorted = build(modules).values();
         Set<Module> result = new LinkedHashSet<>(
                 ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
@@ -214,7 +223,7 @@ public final class YangParserImpl implements YangContextParser {
         }
 
         final List<ModuleBuilder> sorted = resolveModuleBuilders(sources, context);
-        final Map<URI, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, context);
+        final Map<URI, NavigableMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, context);
 
         final Set<Module> unsorted = new LinkedHashSet<>(build(modules).values());
         if (context != null) {
@@ -229,9 +238,9 @@ public final class YangParserImpl implements YangContextParser {
         return resolveSchemaContext(result);
     }
 
-    private static LinkedHashMap<URI, TreeMap<Date, ModuleBuilder>> resolveModulesWithImports(final List<ModuleBuilder> sorted,
+    private static Map<URI, NavigableMap<Date, ModuleBuilder>> resolveModulesWithImports(final List<ModuleBuilder> sorted,
             final SchemaContext context) {
-        final LinkedHashMap<URI, TreeMap<Date, ModuleBuilder>> modules = orderModules(sorted);
+        final Map<URI, NavigableMap<Date, ModuleBuilder>> modules = orderModules(sorted);
         for (ModuleBuilder module : sorted) {
             if (module != null) {
                 for (ModuleImport imp : module.getImports().values()) {
@@ -240,7 +249,7 @@ public final class YangParserImpl implements YangContextParser {
                     if (targetModule == null) {
                         Module result = findModuleFromContext(context, module, prefix, 0);
                         targetModule = new ModuleBuilder(result);
-                        TreeMap<Date, ModuleBuilder> map = modules.get(prefix);
+                        NavigableMap<Date, ModuleBuilder> map = modules.get(targetModule.getNamespace());
                         if (map == null) {
                             map = new TreeMap<>();
                             map.put(targetModule.getRevision(), targetModule);
@@ -331,7 +340,7 @@ public final class YangParserImpl implements YangContextParser {
     public Collection<Module> buildModules(final Collection<ModuleBuilder> builders) {
         Collection<ModuleBuilder> unsorted = resolveSubmodules(builders);
         List<ModuleBuilder> sorted = ModuleDependencySort.sort(unsorted);
-        Map<URI, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, null);
+        Map<URI, NavigableMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, null);
         Map<ModuleBuilder, Module> builderToModule = build(modules);
         return builderToModule.values();
     }
@@ -350,7 +359,7 @@ public final class YangParserImpl implements YangContextParser {
         Map<ByteSource, ModuleBuilder> sourceToBuilder = resolveSources(sources, context);
         // sort and check for duplicates
         List<ModuleBuilder> sorted = ModuleDependencySort.sort(sourceToBuilder.values());
-        Map<URI, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, null);
+        Map<URI, NavigableMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, null);
         Map<ModuleBuilder, Module> builderToModule = build(modules);
         Map<ModuleBuilder, ByteSource> builderToSource = HashBiMap.create(sourceToBuilder).inverse();
         sorted = ModuleDependencySort.sort(builderToModule.keySet());
@@ -379,7 +388,7 @@ public final class YangParserImpl implements YangContextParser {
         return resolveSubmodules(builders);
     }
 
-    private Map<ByteSource, ModuleBuilder> parseSourcesToBuilders(final Collection<ByteSource> sources,
+    private static Map<ByteSource, ModuleBuilder> parseSourcesToBuilders(final Collection<ByteSource> sources,
             final SchemaContext context) throws IOException, YangSyntaxErrorException {
         final ParseTreeWalker walker = new ParseTreeWalker();
         final Map<ByteSource, ParseTree> sourceToTree = parseYangSources(sources);
@@ -388,7 +397,7 @@ public final class YangParserImpl implements YangContextParser {
         // validate yang
         new YangModelBasicValidator(walker).validate(sourceToTree.values());
 
-        Map<String, TreeMap<Date, URI>> namespaceContext = BuilderUtils.createYangNamespaceContext(
+        Map<String, NavigableMap<Date, URI>> namespaceContext = BuilderUtils.createYangNamespaceContext(
                 sourceToTree.values(), Optional.fromNullable(context));
         YangParserListenerImpl yangModelParser;
         for (Map.Entry<ByteSource, ParseTree> entry : sourceToTree.entrySet()) {
@@ -412,12 +421,12 @@ public final class YangParserImpl implements YangContextParser {
 
     private Map<ByteSource, ModuleBuilder> resolveSubmodules(final Map<ByteSource, ModuleBuilder> builders) {
         Map<ByteSource, ModuleBuilder> modules = new HashMap<>();
-        Map<String, TreeMap<Date, ModuleBuilder>> submodules = new HashMap<>();
+        Map<String, NavigableMap<Date, ModuleBuilder>> submodules = new HashMap<>();
         for (Map.Entry<ByteSource, ModuleBuilder> entry : builders.entrySet()) {
             ModuleBuilder builder = entry.getValue();
             if (builder.isSubmodule()) {
                 String submoduleName = builder.getName();
-                TreeMap<Date, ModuleBuilder> map = submodules.get(submoduleName);
+                NavigableMap<Date, ModuleBuilder> map = submodules.get(submoduleName);
                 if (map == null) {
                     map = new TreeMap<>();
                     map.put(builder.getRevision(), builder);
@@ -439,11 +448,11 @@ public final class YangParserImpl implements YangContextParser {
 
     private Collection<ModuleBuilder> resolveSubmodules(final Collection<ModuleBuilder> builders) {
         Collection<ModuleBuilder> modules = new HashSet<>();
-        Map<String, TreeMap<Date, ModuleBuilder>> submodules = new HashMap<>();
+        Map<String, NavigableMap<Date, ModuleBuilder>> submodules = new HashMap<>();
         for (ModuleBuilder builder : builders) {
             if (builder.isSubmodule()) {
                 String submoduleName = builder.getName();
-                TreeMap<Date, ModuleBuilder> map = submodules.get(submoduleName);
+                NavigableMap<Date, ModuleBuilder> map = submodules.get(submoduleName);
                 if (map == null) {
                     map = new TreeMap<>();
                     map.put(builder.getRevision(), builder);
@@ -474,10 +483,10 @@ public final class YangParserImpl implements YangContextParser {
      * @return collection of module builders with resolved submodules
      */
     private void resolveSubmodules(final ModuleBuilder module,
-            final Map<String, TreeMap<Date, ModuleBuilder>> submodules) {
+            final Map<String, NavigableMap<Date, ModuleBuilder>> submodules) {
         Map<String, Date> includes = module.getIncludedModules();
         for (Map.Entry<String, Date> entry : includes.entrySet()) {
-            TreeMap<Date, ModuleBuilder> subs = submodules.get(entry.getKey());
+            NavigableMap<Date, ModuleBuilder> subs = submodules.get(entry.getKey());
             if (subs == null) {
                 throw new YangParseException("Failed to find references submodule " + entry.getKey() + " in module "
                         + module.getName());
@@ -495,14 +504,14 @@ public final class YangParserImpl implements YangContextParser {
                 }
             }
 
-            if (submodule.getIncludedModules().size() > 0) {
+            if (!submodule.getIncludedModules().isEmpty()) {
                 resolveSubmodules(submodule, submodules);
             }
             addSubmoduleToModule(submodule, module);
         }
     }
 
-    private void addSubmoduleToModule(final ModuleBuilder submodule, final ModuleBuilder module) {
+    private static void addSubmoduleToModule(final ModuleBuilder submodule, final ModuleBuilder module) {
         module.addSubmodule(submodule);
         submodule.setParent(module);
         module.getDirtyNodes().addAll(submodule.getDirtyNodes());
@@ -559,8 +568,8 @@ public final class YangParserImpl implements YangContextParser {
      *            topologically sorted modules
      * @return modules ordered by namespace and revision
      */
-    private static LinkedHashMap<URI, TreeMap<Date, ModuleBuilder>> orderModules(final List<ModuleBuilder> modules) {
-        final LinkedHashMap<URI, TreeMap<Date, ModuleBuilder>> result = new LinkedHashMap<>();
+    private static Map<URI, NavigableMap<Date, ModuleBuilder>> orderModules(final List<ModuleBuilder> modules) {
+        final Map<URI, NavigableMap<Date, ModuleBuilder>> result = new LinkedHashMap<>();
         for (final ModuleBuilder builder : modules) {
             if (builder == null) {
                 continue;
@@ -572,7 +581,7 @@ public final class YangParserImpl implements YangContextParser {
                 rev = new Date(0);
             }
 
-            TreeMap<Date, ModuleBuilder> builderByRevision = result.get(ns);
+            NavigableMap<Date, ModuleBuilder> builderByRevision = result.get(ns);
             if (builderByRevision == null) {
                 builderByRevision = new TreeMap<>();
                 builderByRevision.put(rev, builder);
@@ -602,7 +611,7 @@ public final class YangParserImpl implements YangContextParser {
 
         // if this is submodule, add parent to filtered and pick its imports
         if (main.isSubmodule()) {
-            TreeMap<Date, ModuleBuilder> dependencies = new TreeMap<>();
+            NavigableMap<Date, ModuleBuilder> dependencies = new TreeMap<>();
             for (ModuleBuilder mb : other) {
                 if (mb.getName().equals(main.getBelongsTo())) {
                     dependencies.put(mb.getRevision(), mb);
@@ -622,11 +631,9 @@ public final class YangParserImpl implements YangContextParser {
                             filterImports(builder, other, filtered);
                         }
                     } else {
-                        if (mi.getRevision().equals(builder.getRevision())) {
-                            if (!filtered.contains(builder)) {
-                                filtered.add(builder);
-                                filterImports(builder, other, filtered);
-                            }
+                        if (!filtered.contains(builder) && mi.getRevision().equals(builder.getRevision())) {
+                            filtered.add(builder);
+                            filterImports(builder, other, filtered);
                         }
                     }
                 }
@@ -634,7 +641,7 @@ public final class YangParserImpl implements YangContextParser {
         }
     }
 
-    private Map<ByteSource, ParseTree> parseYangSources(final Collection<ByteSource> sources) throws IOException, YangSyntaxErrorException {
+    private static Map<ByteSource, ParseTree> parseYangSources(final Collection<ByteSource> sources) throws IOException, YangSyntaxErrorException {
         final Map<ByteSource, ParseTree> trees = new HashMap<>();
         for (ByteSource source : sources) {
             try (InputStream stream = source.openStream()) {
@@ -663,6 +670,8 @@ public final class YangParserImpl implements YangContextParser {
      * Mini parser: This parsing context does not validate full YANG module,
      * only parses header up to the revisions and imports.
      *
+     * @param yangStream input stream containing a yang module
+     * @return new instance of YangContext
      * @see org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo
      */
     public static YangContext parseStreamWithoutErrorListeners(final InputStream yangStream) {
@@ -701,7 +710,7 @@ public final class YangParserImpl implements YangContextParser {
      *            all loaded modules
      * @return modules mapped on their builders
      */
-    private Map<ModuleBuilder, Module> build(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private Map<ModuleBuilder, Module> build(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         resolveDirtyNodes(modules);
         resolveAugmentsTargetPath(modules);
         resolveUsesTargetGrouping(modules);
@@ -709,10 +718,11 @@ public final class YangParserImpl implements YangContextParser {
         resolveUsesForNodes(modules);
         resolveAugments(modules);
         resolveIdentities(modules);
+        checkChoiceCasesForDuplicityQNames(modules);
 
         // build
         final Map<ModuleBuilder, Module> result = new LinkedHashMap<>();
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
                 final ModuleBuilder moduleBuilder = childEntry.getValue();
                 final Module module = moduleBuilder.build();
@@ -728,8 +738,8 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveDirtyNodes(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+    private static void resolveDirtyNodes(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
                 final ModuleBuilder module = childEntry.getValue();
                 resolveUnknownNodes(modules, module);
@@ -747,7 +757,7 @@ public final class YangParserImpl implements YangContextParser {
      * @param module
      *            current module
      */
-    private void resolveDirtyNodes(final Map<URI, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+    private static void resolveDirtyNodes(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         final Set<TypeAwareBuilder> dirtyNodes = module.getDirtyNodes();
         if (!dirtyNodes.isEmpty()) {
             for (TypeAwareBuilder nodeToResolve : dirtyNodes) {
@@ -778,10 +788,10 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveAugmentsTargetPath(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private void resolveAugmentsTargetPath(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         // collect augments from all loaded modules
         final List<AugmentationSchemaBuilder> allAugments = new ArrayList<>();
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 allAugments.addAll(inner.getValue().getAllAugments());
             }
@@ -813,8 +823,8 @@ public final class YangParserImpl implements YangContextParser {
         }
     }
 
-    private SchemaPath findUsesAugmentTargetNodePath(DataNodeContainerBuilder usesParent,
-            AugmentationSchemaBuilder augment) {
+    private static SchemaPath findUsesAugmentTargetNodePath(final DataNodeContainerBuilder usesParent,
+            final AugmentationSchemaBuilder augment) {
         QName parentQName = usesParent.getQName();
         final QNameModule qnm;
         if (parentQName == null) {
@@ -864,7 +874,7 @@ public final class YangParserImpl implements YangContextParser {
      * @param augments
      *            augments to check
      */
-    private void checkAugmentMandatoryNodes(final Collection<AugmentationSchemaBuilder> augments) {
+    private static void checkAugmentMandatoryNodes(final Collection<AugmentationSchemaBuilder> augments) {
         for (AugmentationSchemaBuilder augment : augments) {
             URI augmentTargetNs = augment.getTargetPath().getPathFromRoot().iterator().next().getNamespace();
             Date augmentTargetRev = augment.getTargetPath().getPathFromRoot().iterator().next().getRevision();
@@ -891,9 +901,9 @@ public final class YangParserImpl implements YangContextParser {
      *            all loaded modules topologically sorted (based on dependencies
      *            between each other)
      */
-    private void resolveAugments(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private static void resolveAugments(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         List<ModuleBuilder> all = new ArrayList<>();
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 all.add(inner.getValue());
             }
@@ -928,8 +938,8 @@ public final class YangParserImpl implements YangContextParser {
      *            all loaded modules
      * @return true if augment process succeed
      */
-    private boolean resolveUsesAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module,
-            final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private static boolean resolveUsesAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module,
+            final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         if (augment.isResolved()) {
             return true;
         }
@@ -951,8 +961,8 @@ public final class YangParserImpl implements YangContextParser {
             // Conflicting elements in other namespaces are still not present
             // since resolveUsesAugment occurs before augmenting from external
             // modules.
-            potentialTargetNode = Optional.<SchemaNodeBuilder> fromNullable(findSchemaNode(augment.getTargetPath()
-                    .getPathFromRoot(), (SchemaNodeBuilder) parentNode));
+            potentialTargetNode = Optional.<SchemaNodeBuilder> fromNullable(findTargetNode(augment.getTargetPath()
+                    .getPathFromRoot(), parentNode));
         }
 
         if (potentialTargetNode.isPresent()) {
@@ -967,6 +977,7 @@ public final class YangParserImpl implements YangContextParser {
                         "Error in module {} at line {}: Unsupported augment target: {}. Augmentation process skipped.",
                         module.getName(), augment.getLine(), potentialTargetNode);
                 augment.setResolved(true);
+                augment.setUnsupportedTarget(true);
                 return true;
             }
         } else {
@@ -987,8 +998,8 @@ public final class YangParserImpl implements YangContextParser {
      *            all loaded modules
      * @return true if augment process succeed
      */
-    private boolean resolveAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module,
-            final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private static boolean resolveAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module,
+            final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         if (augment.isResolved()) {
             return true;
         }
@@ -1010,8 +1021,8 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveIdentities(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+    private static void resolveIdentities(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 ModuleBuilder module = inner.getValue();
                 final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
@@ -1022,7 +1033,8 @@ public final class YangParserImpl implements YangContextParser {
         }
     }
 
-    private void resolveIdentity(final ModuleBuilder module, final IdentitySchemaNodeBuilder identity) {
+    private static void resolveIdentity(final ModuleBuilder module,
+            final IdentitySchemaNodeBuilder identity) {
         final String baseIdentityName = identity.getBaseIdentityName();
         if (baseIdentityName != null) {
             IdentitySchemaNodeBuilder result = null;
@@ -1030,15 +1042,34 @@ public final class YangParserImpl implements YangContextParser {
                 final int line = identity.getLine();
                 String[] splittedBase = baseIdentityName.split(":");
                 if (splittedBase.length > 2) {
-                    throw new YangParseException(module.getName(), line, "Failed to parse identityref base: "
-                            + baseIdentityName);
+                    throw new YangParseException(module.getName(), line,
+                            "Failed to parse identityref base: "
+                                    + baseIdentityName);
                 }
                 String prefix = splittedBase[0];
                 String name = splittedBase[1];
-                ModuleBuilder dependentModule = BuilderUtils.getModuleByPrefix(module, prefix);
-                result = BuilderUtils.findIdentity(dependentModule.getAddedIdentities(), name);
+
+                if (prefix.equals(module.getPrefix())
+                        && name.equals(identity.getQName().getLocalName())) {
+                    throw new YangParseException(module.getName(),
+                            identity.getLine(),
+                            "Failed to parse base, identity name equals base identity name: "
+                                    + baseIdentityName);
+                }
+
+                ModuleBuilder dependentModule = BuilderUtils.getModuleByPrefix(
+                        module, prefix);
+                result = BuilderUtils.findIdentity(
+                        dependentModule.getAddedIdentities(), name);
             } else {
-                result = BuilderUtils.findIdentity(module.getAddedIdentities(), baseIdentityName);
+                if (baseIdentityName.equals(identity.getQName().getLocalName())) {
+                    throw new YangParseException(module.getName(),
+                            identity.getLine(),
+                            "Failed to parse base, identity name equals base identity name: "
+                                    + baseIdentityName);
+                }
+                result = BuilderUtils.findIdentity(module.getAddedIdentities(),
+                        baseIdentityName);
             }
             identity.setBaseIdentity(result);
         }
@@ -1050,9 +1081,9 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveUsesTargetGrouping(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private static void resolveUsesTargetGrouping(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         final List<UsesNodeBuilder> allUses = new ArrayList<>();
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 allUses.addAll(inner.getValue().getAllUsesNodes());
             }
@@ -1061,10 +1092,6 @@ public final class YangParserImpl implements YangContextParser {
             ModuleBuilder module = BuilderUtils.getParentModule(usesNode);
             final GroupingBuilder targetGroupingBuilder = GroupingUtils.getTargetGroupingFromModules(usesNode, modules,
                     module);
-            if (targetGroupingBuilder == null) {
-                throw new YangParseException(module.getName(), usesNode.getLine(), "Referenced grouping '"
-                        + usesNode.getGroupingPath() + "' not found.");
-            }
             usesNode.setGrouping(targetGroupingBuilder);
         }
     }
@@ -1075,9 +1102,9 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveUsesForGroupings(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private static void resolveUsesForGroupings(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         final Set<GroupingBuilder> allGroupings = new HashSet<>();
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 ModuleBuilder module = inner.getValue();
                 allGroupings.addAll(module.getAllGroupings());
@@ -1099,8 +1126,8 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveUsesForNodes(final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
-        for (Map.Entry<URI, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+    private static void resolveUsesForNodes(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 ModuleBuilder module = inner.getValue();
                 List<UsesNodeBuilder> usesNodes = module.getAllUsesNodes();
@@ -1121,7 +1148,7 @@ public final class YangParserImpl implements YangContextParser {
      * @param modules
      *            all loaded modules
      */
-    private void resolveUses(final UsesNodeBuilder usesNode, final Map<URI, TreeMap<Date, ModuleBuilder>> modules) {
+    private static void resolveUses(final UsesNodeBuilder usesNode, final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
         if (!usesNode.isResolved()) {
             DataNodeContainerBuilder parent = usesNode.getParent();
             ModuleBuilder module = BuilderUtils.getParentModule(parent);
@@ -1144,7 +1171,7 @@ public final class YangParserImpl implements YangContextParser {
         }
     }
 
-    private int nodeAfterUsesIndex(final UsesNodeBuilder usesNode) {
+    private static int nodeAfterUsesIndex(final UsesNodeBuilder usesNode) {
         DataNodeContainerBuilder parent = usesNode.getParent();
         int usesLine = usesNode.getLine();
 
@@ -1155,11 +1182,9 @@ public final class YangParserImpl implements YangContextParser {
 
         DataSchemaNodeBuilder nextNodeAfterUses = null;
         for (DataSchemaNodeBuilder childNode : childNodes) {
-            if (!(childNode.isAddedByUses()) && !(childNode.isAugmenting())) {
-                if (childNode.getLine() > usesLine) {
-                    nextNodeAfterUses = childNode;
-                    break;
-                }
+            if (!childNode.isAddedByUses() && !childNode.isAugmenting() && childNode.getLine() > usesLine) {
+                nextNodeAfterUses = childNode;
+                break;
             }
         }
 
@@ -1180,7 +1205,7 @@ public final class YangParserImpl implements YangContextParser {
      * @param module
      *            current module
      */
-    private void resolveUnknownNodes(final Map<URI, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+    private static void resolveUnknownNodes(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) {
             QName nodeType = usnb.getNodeType();
             String localName = usnb.getNodeType().getLocalName();
@@ -1209,7 +1234,7 @@ public final class YangParserImpl implements YangContextParser {
         }
     }
 
-    private ExtensionBuilder findExtBuilder(final String name, final Collection<ExtensionBuilder> extensions) {
+    private static ExtensionBuilder findExtBuilder(final String name, final Collection<ExtensionBuilder> extensions) {
         for (ExtensionBuilder extension : extensions) {
             if (extension.getQName().getLocalName().equals(name)) {
                 return extension;
@@ -1218,7 +1243,7 @@ public final class YangParserImpl implements YangContextParser {
         return null;
     }
 
-    private ExtensionDefinition findExtDef(final String name, final Collection<ExtensionDefinition> extensions) {
+    private static ExtensionDefinition findExtDef(final String name, final Collection<ExtensionDefinition> extensions) {
         for (ExtensionDefinition extension : extensions) {
             if (extension.getQName().getLocalName().equals(name)) {
                 return extension;
@@ -1227,4 +1252,73 @@ public final class YangParserImpl implements YangContextParser {
         return null;
     }
 
+
+    /**
+     * Traverse through modules and check if choice has choice cases with the
+     * same qname.
+     *
+     * @param modules
+     *            all loaded modules
+     */
+    private void checkChoiceCasesForDuplicityQNames(final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        for (Map.Entry<URI, NavigableMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+            for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
+                final ModuleBuilder moduleBuilder = childEntry.getValue();
+                final Module module = moduleBuilder.build();
+                final List<ChoiceSchemaNode> allChoicesFromModule = getChoicesFrom(module);
+
+                for (ChoiceSchemaNode choiceNode : allChoicesFromModule) {
+                    findDuplicityNodesIn(choiceNode, module, moduleBuilder, modules);
+                }
+            }
+        }
+    }
+
+    private static void findDuplicityNodesIn(final ChoiceSchemaNode choiceNode, final Module module, final ModuleBuilder moduleBuilder,
+            final Map<URI, NavigableMap<Date, ModuleBuilder>> modules) {
+        final Set<QName> duplicityTestSet = new HashSet<>();
+
+        for (ChoiceCaseNode choiceCaseNode : choiceNode.getCases()) {
+
+            for (DataSchemaNode childSchemaNode : choiceCaseNode.getChildNodes()) {
+                if (!duplicityTestSet.add(childSchemaNode.getQName())) {
+                    final Optional<SchemaNodeBuilder> schemaNodeBuilder = BuilderUtils.findSchemaNodeInModule(childSchemaNode.getPath(), moduleBuilder);
+                    final String nameOfSchemaNode = childSchemaNode.getQName().getLocalName();
+                    int lineOfSchemaNode = 0;
+
+                    if (schemaNodeBuilder.isPresent()) {
+                        lineOfSchemaNode = schemaNodeBuilder.get().getLine();
+                    }
+                    throw new YangParseException(module.getName(), lineOfSchemaNode,
+                            String.format("Choice has two nodes case with same qnames - %s", nameOfSchemaNode));
+                }
+            }
+        }
+    }
+
+    private List<ChoiceSchemaNode> getChoicesFrom(final Module module) {
+        final List<ChoiceSchemaNode> allChoices = new ArrayList<>();
+
+        for (DataSchemaNode dataSchemaNode : module.getChildNodes()) {
+            findChoicesIn(dataSchemaNode, allChoices);
+        }
+        return allChoices;
+    }
+
+    private void findChoicesIn(final SchemaNode schemaNode, final Collection<ChoiceSchemaNode> choiceNodes) {
+        if (schemaNode instanceof ContainerSchemaNode) {
+            final ContainerSchemaNode contSchemaNode = (ContainerSchemaNode) schemaNode;
+            for (DataSchemaNode dataSchemaNode : contSchemaNode.getChildNodes()) {
+                findChoicesIn(dataSchemaNode, choiceNodes);
+            }
+        } else if (schemaNode instanceof ListSchemaNode) {
+            final ListSchemaNode listSchemaNode = (ListSchemaNode) schemaNode;
+            for (DataSchemaNode dataSchemaNode : listSchemaNode.getChildNodes()) {
+                findChoicesIn(dataSchemaNode, choiceNodes);
+            }
+        } else if (schemaNode instanceof ChoiceSchemaNode) {
+            choiceNodes.add((ChoiceSchemaNode) schemaNode);
+        }
+    }
+
 }