BUG-1210: refactored imports handling in parser. 92/8492/7
authorMartin Vitez <mvitez@cisco.com>
Tue, 1 Jul 2014 11:51:34 +0000 (13:51 +0200)
committerMartin Vitez <mvitez@cisco.com>
Tue, 8 Jul 2014 09:22:47 +0000 (11:22 +0200)
Currently builder for module has no information about imported modules. This causes overhead because before resolving any of imported nodes
(uses, typedef, identities, augment path, deviation path...) parser needs to search whole collection of available modules to find target
module of imported node.

This patch adds information about imported modules to ModuleBuilder, so they can be available without search. Searching is performed only
once when resolving imports.

Change-Id: Ifcd4e995431165820c142e486da0466edc6abca0
Signed-off-by: Martin Vitez <mvitez@cisco.com>
13 files changed:
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/BuilderUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/GroupingUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/TypeUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ModuleDependencySort.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserWithContextTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/util/ModuleDependencySortTest.java
yang/yang-parser-impl/src/test/resources/augment-test/augment-in-augment/bar.yang
yang/yang-parser-impl/src/test/resources/context-augment-test/test1.yang
yang/yang-parser-impl/src/test/resources/context-test/test1.yang
yang/yang-parser-impl/src/test/resources/model/bar.yang

index 82a2989076ead671e0324942709798a93624a916..70eb185ca25b3063538a62c2285526d1a96d08ef 100644 (file)
@@ -13,7 +13,6 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
 import com.google.common.collect.Collections2;
 import com.google.common.io.ByteSource;
-
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -124,25 +123,6 @@ public final class BuilderUtils {
         return schemaPath.createChild(qname);
     }
 
-    /**
-     * Get module import referenced by given prefix.
-     *
-     * @param builder
-     *            module to search
-     * @param prefix
-     *            prefix associated with import
-     * @return ModuleImport based on given prefix
-     */
-    private static ModuleImport getModuleImport(final ModuleBuilder builder, final String prefix) {
-        for (ModuleImport mi : builder.getModuleImports()) {
-            if (mi.getPrefix().equals(prefix)) {
-                return mi;
-
-            }
-        }
-        return null;
-    }
-
     /**
      * Find dependent module based on given prefix
      *
@@ -166,7 +146,7 @@ public final class BuilderUtils {
         } else if (prefix.equals(module.getPrefix())) {
             dependentModule = module;
         } else {
-            ModuleImport dependentModuleImport = getModuleImport(module, prefix);
+            ModuleImport dependentModuleImport = module.getImport(prefix);
             if (dependentModuleImport == null) {
                 throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'.");
             }
@@ -194,20 +174,19 @@ public final class BuilderUtils {
      * @param currentModule
      *            current module
      * @param prefix
-     *            current prefix used to reference dependent module
+     *            prefix used to reference dependent module
      * @param line
      *            current line in yang model
-     * @return module based on given prefix if found in context, null otherwise
+     * @return module based on import with given prefix if found in context,
+     *         null otherwise
+     * @throws YangParseException
+     *             if no import found with given prefix
      */
     public static Module findModuleFromContext(final SchemaContext context, final ModuleBuilder currentModule,
             final String prefix, final int line) {
-        if (context == null) {
-            throw new YangParseException(currentModule.getName(), line, "Cannot find module with prefix '" + prefix
-                    + "'.");
-        }
         TreeMap<Date, Module> modulesByRevision = new TreeMap<>();
 
-        ModuleImport dependentModuleImport = BuilderUtils.getModuleImport(currentModule, prefix);
+        ModuleImport dependentModuleImport = currentModule.getImport(prefix);
         if (dependentModuleImport == null) {
             throw new YangParseException(currentModule.getName(), line, "No import found with prefix '" + prefix + "'.");
         }
@@ -230,6 +209,10 @@ public final class BuilderUtils {
         } else {
             result = modulesByRevision.get(dependentModuleRevision);
         }
+        if (result == null) {
+            throw new YangParseException(currentModule.getName(), line, "Module not found for prefix " + prefix);
+        }
+
         return result;
     }
 
@@ -371,33 +354,6 @@ public final class BuilderUtils {
         }
     }
 
-    /**
-     * Set config flag to new value.
-     *
-     * @param node
-     *            node to update
-     * @param config
-     *            new config value
-     */
-    private static void setNodeConfig(final DataSchemaNodeBuilder node, final Boolean config) {
-        if (node instanceof ContainerSchemaNodeBuilder || node instanceof LeafSchemaNodeBuilder
-                || node instanceof LeafListSchemaNodeBuilder || node instanceof ListSchemaNodeBuilder
-                || node instanceof ChoiceBuilder || node instanceof AnyXmlBuilder) {
-            node.setConfiguration(config);
-        }
-        if (node instanceof DataNodeContainerBuilder) {
-            DataNodeContainerBuilder dataNodeChild = (DataNodeContainerBuilder) node;
-            for (DataSchemaNodeBuilder inner : dataNodeChild.getChildNodeBuilders()) {
-                setNodeConfig(inner, config);
-            }
-        } else if (node instanceof ChoiceBuilder) {
-            ChoiceBuilder choiceChild = (ChoiceBuilder) node;
-            for (ChoiceCaseBuilder inner : choiceChild.getCases()) {
-                setNodeConfig(inner, config);
-            }
-        }
-    }
-
     public static DataSchemaNodeBuilder findSchemaNode(final List<QName> path, final SchemaNodeBuilder parentNode) {
         DataSchemaNodeBuilder node = null;
         SchemaNodeBuilder parent = parentNode;
@@ -661,7 +617,7 @@ public final class BuilderUtils {
                 throw new YangParseException(module.getName(), line, "Failed to parse identityref base: " + baseString);
             }
 
-            ModuleBuilder dependentModule = findModuleFromBuilders(modules, module, prefix, line);
+            ModuleBuilder dependentModule = getModuleByPrefix(module, prefix);
             if (dependentModule == null) {
                 return null;
             }
@@ -789,4 +745,12 @@ public final class BuilderUtils {
         }
     }
 
+    public static ModuleBuilder getModuleByPrefix(ModuleBuilder module, String prefix) {
+        if (prefix == null || prefix.isEmpty() || prefix.equals(module.getPrefix())) {
+            return module;
+        } else {
+            return module.getImportedModule(prefix);
+        }
+    }
+
 }
index 59689e16aaafade4b1ae42c5fd7021479629c6be..12dabc1a6a8628f6263a4f93edb367886644e950 100644 (file)
@@ -8,17 +8,12 @@
 package org.opendaylight.yangtools.yang.parser.builder.impl;
 
 import com.google.common.base.Splitter;
-
 import java.util.Comparator;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
-
-import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
@@ -35,13 +30,17 @@ public final class GroupingUtils {
     }
 
     /**
-     * Common string splitter. Given a string representation of a grouping's name, it creates a prefix/name
-     * pair and returns it.
+     * Common string splitter. Given a string representation of a grouping's
+     * name, it creates a prefix/name pair and returns it.
      *
-     * @param groupingString Grouping string reference
-     * @param module Module which we are processing
-     * @param line Module line which we are processing
-     * @return An array of two strings, first one is the module prefix, the second is the grouping name.
+     * @param groupingString
+     *            Grouping string reference
+     * @param module
+     *            Module which we are processing
+     * @param line
+     *            Module line which we are processing
+     * @return An array of two strings, first one is the module prefix, the
+     *         second is the grouping name.
      */
     private static String[] getPrefixAndName(final String groupingString, final ModuleBuilder module, final int line) {
         final String[] ret = new String[2];
@@ -97,15 +96,13 @@ public final class GroupingUtils {
             return null;
         }
 
-        GroupingBuilder result;
         Set<GroupingBuilder> groupings = dependentModule.getGroupingBuilders();
-        result = findGroupingBuilder(groupings, groupingName);
+        GroupingBuilder result = findGroupingBuilder(groupings, groupingName);
         if (result != null) {
             return result;
         }
 
         Builder parent = usesBuilder.getParent();
-
         while (parent != null) {
             if (parent instanceof DataNodeContainerBuilder) {
                 groupings = ((DataNodeContainerBuilder) parent).getGroupingBuilders();
@@ -121,31 +118,11 @@ public final class GroupingUtils {
         }
 
         if (result == null) {
-            throw new YangParseException(module.getName(), line, "Referenced grouping '" + groupingName
-                    + "' not found.");
+            throw new YangParseException(module.getName(), line, "Grouping '" + groupingName + "' not found.");
         }
         return result;
     }
 
-    /**
-     * Search context for grouping by name defined in uses node.
-     *
-     * @param usesBuilder
-     *            builder of uses statement
-     * @param module
-     *            current module
-     * @param context
-     *            SchemaContext containing already resolved modules
-     * @return grouping with given name if found, null otherwise
-     */
-    public static GroupingDefinition getTargetGroupingFromContext(final UsesNodeBuilder usesBuilder,
-            final ModuleBuilder module, final SchemaContext context) {
-        final int line = usesBuilder.getLine();
-        final String[] split = getPrefixAndName(usesBuilder.getGroupingPathAsString(), module, line);
-        Module dependentModule = BuilderUtils.findModuleFromContext(context, module, split[0], line);
-        return findGroupingDefinition(dependentModule.getGroupings(), split[1]);
-    }
-
     /**
      * Find grouping by name.
      *
@@ -164,24 +141,6 @@ public final class GroupingUtils {
         return null;
     }
 
-    /**
-     * Find grouping by name.
-     *
-     * @param groupings
-     *            collection of grouping definitions to search
-     * @param name
-     *            name of grouping
-     * @return grouping with given name if present in collection, null otherwise
-     */
-    private static GroupingDefinition findGroupingDefinition(final Set<GroupingDefinition> groupings, final String name) {
-        for (GroupingDefinition grouping : groupings) {
-            if (grouping.getQName().getLocalName().equals(name)) {
-                return grouping;
-            }
-        }
-        return null;
-    }
-
     /**
      * Perform refinement of uses target grouping nodes. Uses process has to be
      * already performed.
index c434f3397549f3f42b9ca493b0d2da60fc95c74a..d762af57bf7f382c4e722f6253a40a8954f40784 100644 (file)
@@ -16,10 +16,12 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Deque;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 
@@ -76,7 +78,8 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
     private final Deque<Builder> actualPath = new LinkedList<>();
     private final Set<TypeAwareBuilder> dirtyNodes = new HashSet<>();
 
-    final Set<ModuleImport> imports = new HashSet<>();
+    final Map<String, ModuleImport> imports = new HashMap<>();
+    final Map<String, ModuleBuilder> importedModules = new HashMap<>();
 
     private final Set<AugmentationSchema> augments = new LinkedHashSet<>();
     private final List<AugmentationSchemaBuilder> augmentBuilders = new ArrayList<>();
@@ -346,10 +349,23 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         return qnameModule.getRevision();
     }
 
-    protected Set<ModuleImport> getImports() {
+    public ModuleImport getImport(final String prefix) {
+        return imports.get(prefix);
+    }
+
+    public Map<String, ModuleImport> getImports() {
         return imports;
     }
 
+    public ModuleBuilder getImportedModule(final String prefix) {
+        return importedModules.get(prefix);
+    }
+
+    public void addImportedModule(final String prefix, final ModuleBuilder module) {
+        checkPrefix(prefix);
+        importedModules.put(prefix, module);
+    }
+
     protected String getSource() {
         return source;
     }
@@ -391,14 +407,20 @@ public class ModuleBuilder extends AbstractDocumentedDataNodeContainerBuilder im
         this.contact = contact;
     }
 
-    public boolean addModuleImport(final String moduleName, final Date revision, final String prefix) {
+    public void addModuleImport(final String moduleName, final Date revision, final String prefix) {
+        checkPrefix(prefix);
         checkNotSealed();
         final ModuleImport moduleImport = createModuleImport(moduleName, revision, prefix);
-        return imports.add(moduleImport);
+        imports.put(prefix, moduleImport);
     }
 
-    public Set<ModuleImport> getModuleImports() {
-        return imports;
+    private void checkPrefix(final String prefix) {
+        if (prefix == null || prefix.isEmpty()) {
+            throw new IllegalArgumentException("Cannot add imported module with undefined prefix");
+        }
+        if (prefix.equals(this.prefix)) {
+            throw new IllegalArgumentException("Cannot add imported module with prefix equals to module prefix");
+        }
     }
 
     public ExtensionBuilder addExtension(final QName qname, final int line, final SchemaPath path) {
index 4e4bc8cf18c0b0035f89ae29069c08fd8919ee81..d2c3729871227954435671f78d27bece1e06a8f9 100644 (file)
@@ -4,14 +4,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
-
 import java.net.URI;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
-
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
@@ -62,7 +60,7 @@ public final class ModuleImpl extends AbstractDocumentedDataNodeContainer implem
         super(builder);
         this.name = checkNotNull(name, "Missing name");
         this.sourcePath = sourcePath; //TODO: can this be nullable?
-        this.imports = ImmutableSet.copyOf(builder.imports);
+        this.imports = ImmutableSet.<ModuleImport> copyOf(builder.imports.values());
         this.prefix = builder.getPrefix();
 
         this.qnameModule = QNameModule.create(builder.getNamespace(),
index 57fde9439187e49bce254efa7591f14e835d0df5..61b47f2cf5032585b10ce7533692857cd043e282 100644 (file)
@@ -7,9 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.parser.builder.impl;
 
-import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findModuleFromBuilders;
-import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findModuleFromContext;
-
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -17,8 +14,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
@@ -56,97 +51,18 @@ public final class TypeUtils {
      */
     public static void resolveType(final TypeAwareBuilder nodeToResolve,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
-        final int line = nodeToResolve.getLine();
         final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
         final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
-        final ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module,
-                unknownTypeQName.getPrefix(), line);
-
+        final ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, unknownTypeQName.getPrefix());
+        if (dependentModuleBuilder == null) {
+            throw new YangParseException(module.getName(), nodeToResolve.getLine(), "No module found for import "
+                    + unknownTypeQName.getPrefix());
+        }
         TypeDefinitionBuilder resolvedType = findUnknownTypeDefinition(nodeToResolve, dependentModuleBuilder, modules,
                 module);
         nodeToResolve.setTypedef(resolvedType);
     }
 
-    /**
-     * Resolve unknown type of node. It is assumed that type of node is either
-     * UnknownType or ExtendedType with UnknownType as base type.
-     *
-     * @param nodeToResolve
-     *            node with type to resolve
-     * @param modules
-     *            all loaded modules
-     * @param module
-     *            current module
-     * @param context
-     *            SchemaContext containing already resolved modules
-     */
-    public static void resolveTypeWithContext(final TypeAwareBuilder nodeToResolve,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
-            final SchemaContext context) {
-        final int line = nodeToResolve.getLine();
-        final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
-        final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
-        final ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module,
-                unknownTypeQName.getPrefix(), line);
-
-        if (dependentModuleBuilder == null) {
-            final Module dependentModule = findModuleFromContext(context, module, unknownTypeQName.getPrefix(), line);
-            final Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
-            final TypeDefinition<?> type = findTypeByName(types, unknownTypeQName.getLocalName());
-
-            if (nodeToResolveType instanceof ExtendedType) {
-                final ExtendedType extType = (ExtendedType) nodeToResolveType;
-                final TypeDefinitionBuilder newType = extendedTypeWithNewBase(null, type, extType, modules, module,
-                        nodeToResolve.getLine());
-
-                nodeToResolve.setTypedef(newType);
-            } else {
-                if (nodeToResolve instanceof TypeDefinitionBuilder) {
-                    TypeDefinitionBuilder tdb = (TypeDefinitionBuilder) nodeToResolve;
-                    TypeConstraints tc = findConstraintsFromTypeBuilder(nodeToResolve,
-                            new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, context);
-                    tdb.setLengths(tc.getLength());
-                    tdb.setPatterns(tc.getPatterns());
-                    tdb.setRanges(tc.getRange());
-                    tdb.setFractionDigits(tc.getFractionDigits());
-                }
-                nodeToResolve.setType(type);
-            }
-
-        } else {
-            TypeDefinitionBuilder resolvedType = findUnknownTypeDefinition(nodeToResolve, dependentModuleBuilder,
-                    modules, module);
-            nodeToResolve.setTypedef(resolvedType);
-        }
-    }
-
-    public static void resolveTypeUnion(final UnionTypeBuilder union,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder) {
-        final List<TypeDefinition<?>> unionTypes = union.getTypes();
-        final List<TypeDefinition<?>> toRemove = new ArrayList<>();
-        for (TypeDefinition<?> unionType : unionTypes) {
-            if (unionType instanceof UnknownType) {
-                final ModuleBuilder dependentModule = findModuleFromBuilders(modules, builder, unionType.getQName()
-                        .getPrefix(), union.getLine());
-                final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModule, unionType
-                        .getQName().getLocalName(), builder.getName(), union.getLine());
-                union.setTypedef(resolvedType);
-                toRemove.add(unionType);
-            } else if (unionType instanceof ExtendedType && unionType.getBaseType() instanceof UnknownType) {
-                final UnknownType ut = (UnknownType) unionType.getBaseType();
-                final ModuleBuilder dependentModule = findModuleFromBuilders(modules, builder, ut.getQName()
-                        .getPrefix(), union.getLine());
-                final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union, dependentModule, ut
-                        .getQName().getLocalName(), builder.getName(), union.getLine());
-                final TypeDefinitionBuilder newType = extendedTypeWithNewBase(targetTypeBuilder, null,
-                        (ExtendedType) unionType, modules, builder, union.getLine());
-                union.setTypedef(newType);
-                toRemove.add(unionType);
-            }
-        }
-        unionTypes.removeAll(toRemove);
-    }
-
     /**
      * Resolve union type which contains one or more unresolved types.
      *
@@ -156,20 +72,17 @@ public final class TypeUtils {
      *            all loaded modules
      * @param module
      *            current module
-     * @param context
-     *            SchemaContext containing already resolved modules
      */
-    public static void resolveTypeUnionWithContext(final UnionTypeBuilder union,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
-            final SchemaContext context) {
+    public static void resolveTypeUnion(final UnionTypeBuilder union,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         final List<TypeDefinition<?>> unionTypes = union.getTypes();
         final List<TypeDefinition<?>> toRemove = new ArrayList<>();
         for (TypeDefinition<?> unionType : unionTypes) {
             if (unionType instanceof UnknownType) {
-                resolveUnionUnknownType(union, (UnknownType) unionType, modules, module, context);
+                resolveUnionUnknownType(union, (UnknownType) unionType, modules, module);
                 toRemove.add(unionType);
             } else if (unionType instanceof ExtendedType && unionType.getBaseType() instanceof UnknownType) {
-                resolveUnionUnknownType(union, (ExtendedType) unionType, modules, module, context);
+                resolveUnionUnknownType(union, (ExtendedType) unionType, modules, module);
                 toRemove.add(unionType);
             }
         }
@@ -177,46 +90,26 @@ public final class TypeUtils {
     }
 
     private static void resolveUnionUnknownType(final UnionTypeBuilder union, final UnknownType ut,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
-            final SchemaContext context) {
-        final int line = union.getLine();
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         final QName utQName = ut.getQName();
-        final ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, utQName.getPrefix(), line);
-
-        if (dependentModuleBuilder == null) {
-            Module dependentModule = findModuleFromContext(context, module, utQName.getPrefix(), line);
-            Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
-            TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
-            union.setType(type);
-        } else {
-            final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModuleBuilder,
-                    utQName.getLocalName(), module.getName(), union.getLine());
-            union.setTypedef(resolvedType);
-        }
+        final ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, utQName.getPrefix());
+        final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModuleBuilder,
+                utQName.getLocalName(), module.getName(), union.getLine());
+        union.setTypedef(resolvedType);
     }
 
     private static void resolveUnionUnknownType(final UnionTypeBuilder union, final ExtendedType extType,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
-            final SchemaContext context) {
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         final int line = union.getLine();
         final TypeDefinition<?> extTypeBase = extType.getBaseType();
         final UnknownType ut = (UnknownType) extTypeBase;
         final QName utQName = ut.getQName();
-        final ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, utQName.getPrefix(), line);
-
-        if (dependentModuleBuilder == null) {
-            final Module dependentModule = findModuleFromContext(context, module, utQName.getPrefix(), line);
-            Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
-            TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
-            final TypeDefinitionBuilder newType = extendedTypeWithNewBase(null, type, extType, modules, module, 0);
-            union.setTypedef(newType);
-        } else {
-            final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union, dependentModuleBuilder,
-                    utQName.getLocalName(), module.getName(), line);
-            final TypeDefinitionBuilder newType = extendedTypeWithNewBase(targetTypeBuilder, null, extType, modules,
-                    module, line);
-            union.setTypedef(newType);
-        }
+        final ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, utQName.getPrefix());
+        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union, dependentModuleBuilder,
+                utQName.getLocalName(), module.getName(), line);
+        final TypeDefinitionBuilder newType = extendedTypeWithNewBase(targetTypeBuilder, null, extType, modules,
+                module, line);
+        union.setTypedef(newType);
     }
 
     /**
@@ -252,7 +145,7 @@ public final class TypeUtils {
 
         // validate constraints
         final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve,
-                new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, null);
+                new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module);
         constraints.validateConstraints();
 
         return resolvedType;
@@ -276,25 +169,6 @@ public final class TypeUtils {
         return null;
     }
 
-    /**
-     * Find type by name.
-     *
-     * @param types
-     *            collection of types
-     * @param typeName
-     *            type name
-     * @return type with given name if it is present in collection, null
-     *         otherwise
-     */
-    private static TypeDefinition<?> findTypeByName(Set<TypeDefinition<?>> types, String typeName) {
-        for (TypeDefinition<?> type : types) {
-            if (type.getQName().getLocalName().equals(typeName)) {
-                return type;
-            }
-        }
-        return null;
-    }
-
     /**
      * Pull restriction from type and add them to constraints.
      *
@@ -360,7 +234,7 @@ public final class TypeUtils {
             tc.addLengths(oldExtendedType.getLengthConstraints());
             tc.addPatterns(oldExtendedType.getPatternConstraints());
             tc.addRanges(oldExtendedType.getRangeConstraints());
-            constraints = findConstraintsFromTypeBuilder(newBaseTypeBuilder, tc, modules, module, null);
+            constraints = findConstraintsFromTypeBuilder(newBaseTypeBuilder, tc, modules, module);
             newType.setTypedef(newBaseTypeBuilder);
         } else {
             constraints = findConstraintsFromTypeDefinition(newBaseType, tc);
@@ -410,7 +284,7 @@ public final class TypeUtils {
 
     private static TypeConstraints findConstraintsFromTypeBuilder(final TypeAwareBuilder nodeToResolve,
             final TypeConstraints constraints, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder builder, final SchemaContext context) {
+            final ModuleBuilder builder) {
 
         // union and identityref types cannot be restricted
         if (nodeToResolve instanceof UnionTypeBuilder || nodeToResolve instanceof IdentityrefTypeBuilder) {
@@ -427,37 +301,23 @@ public final class TypeUtils {
 
         TypeDefinition<?> type = nodeToResolve.getType();
         if (type == null) {
-            return findConstraintsFromTypeBuilder(nodeToResolve.getTypedef(), constraints, modules, builder, context);
+            return findConstraintsFromTypeBuilder(nodeToResolve.getTypedef(), constraints, modules, builder);
         } else {
             QName qname = type.getQName();
             if (type instanceof UnknownType) {
-                ModuleBuilder dependentModuleBuilder = BuilderUtils.findModuleFromBuilders(modules, builder,
-                        qname.getPrefix(), nodeToResolve.getLine());
-                if (dependentModuleBuilder == null) {
-                    if (context == null) {
-                        throw new YangParseException(builder.getName(), nodeToResolve.getLine(),
-                                "Failed to resolved type constraints.");
-                    }
-                    Module dm = BuilderUtils.findModuleFromContext(context, builder, qname.getPrefix(),
-                            nodeToResolve.getLine());
-                    TypeDefinition<?> t = findTypeByName(dm.getTypeDefinitions(), qname.getLocalName());
-                    return mergeConstraints(t, constraints);
-
-                } else {
-                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModuleBuilder,
-                            qname.getLocalName(), builder.getName(), nodeToResolve.getLine());
-                    return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModuleBuilder, context);
-                }
+                ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(builder, qname.getPrefix());
+                TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModuleBuilder,
+                        qname.getLocalName(), builder.getName(), nodeToResolve.getLine());
+                return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModuleBuilder);
             } else if (type instanceof ExtendedType) {
                 mergeConstraints(type, constraints);
 
                 TypeDefinition<?> base = ((ExtendedType) type).getBaseType();
                 if (base instanceof UnknownType) {
-                    ModuleBuilder dependentModule = BuilderUtils.findModuleFromBuilders(modules, builder, base
-                            .getQName().getPrefix(), nodeToResolve.getLine());
+                    ModuleBuilder dependentModule = BuilderUtils.getModuleByPrefix(builder, base.getQName().getPrefix());
                     TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModule, base
                             .getQName().getLocalName(), builder.getName(), nodeToResolve.getLine());
-                    return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModule, context);
+                    return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModule);
                 } else {
                     // it has to be base yang type
                     return mergeConstraints(type, constraints);
index cea011edcbd4652a155d15b8185ad1d457e637a8..83d605f1290ca058700c488662bb86c4a62ca880 100644 (file)
@@ -15,22 +15,18 @@ import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.f
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findSchemaNodeInModule;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.processAugmentation;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.setNodeAddedByUses;
-import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapChildNode;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapChildNodes;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapGroupings;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapTypedefs;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapUnknownNodes;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveType;
 import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeUnion;
-import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeUnionWithContext;
-import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeWithContext;
 
 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;
 import java.io.IOException;
 import java.io.InputStream;
@@ -47,9 +43,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
-
 import javax.annotation.concurrent.Immutable;
-
 import org.antlr.v4.runtime.ANTLRInputStream;
 import org.antlr.v4.runtime.CommonTokenStream;
 import org.antlr.v4.runtime.tree.ParseTree;
@@ -59,15 +53,12 @@ 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.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
 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;
@@ -126,7 +117,7 @@ public final class YangParserImpl implements YangContextParser {
 
     @Override
     public SchemaContext parseFile(final File yangFile, final File directory) throws IOException,
-    YangSyntaxErrorException {
+            YangSyntaxErrorException {
         Preconditions.checkState(yangFile.exists(), yangFile + " does not exists");
         Preconditions.checkState(directory.exists(), directory + " does not exists");
         Preconditions.checkState(directory.isDirectory(), directory + " is not a directory");
@@ -158,7 +149,7 @@ public final class YangParserImpl implements YangContextParser {
 
         // module builders sorted by dependencies
         List<ModuleBuilder> sortedBuilders = ModuleDependencySort.sort(resolved);
-        LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> modules = orderModules(sortedBuilders);
+        LinkedHashMap<String, TreeMap<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()])));
@@ -191,7 +182,7 @@ public final class YangParserImpl implements YangContextParser {
 
     @Override
     public SchemaContext parseFiles(final Collection<File> yangFiles, final SchemaContext context) throws IOException,
-    YangSyntaxErrorException {
+            YangSyntaxErrorException {
         if (yangFiles == null) {
             return resolveSchemaContext(Collections.<Module> emptySet());
         }
@@ -213,7 +204,7 @@ public final class YangParserImpl implements YangContextParser {
 
     @Override
     public SchemaContext parseSources(final Collection<ByteSource> sources) throws IOException,
-    YangSyntaxErrorException {
+            YangSyntaxErrorException {
         Collection<Module> unsorted = parseYangModelSources(sources).values();
         Set<Module> sorted = new LinkedHashSet<>(
                 ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
@@ -238,8 +229,10 @@ public final class YangParserImpl implements YangContextParser {
             return resolveSchemaContext(Collections.<Module> emptySet());
         }
 
-        final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(sources, context);
-        final Set<Module> unsorted = new LinkedHashSet<>(buildWithContext(modules, context).values());
+        final List<ModuleBuilder> sorted = resolveModuleBuilders(sources, context);
+        final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, context);
+
+        final Set<Module> unsorted = new LinkedHashSet<>(build(modules).values());
         if (context != null) {
             for (Module m : context.getModules()) {
                 if (!unsorted.contains(m)) {
@@ -252,6 +245,33 @@ public final class YangParserImpl implements YangContextParser {
         return resolveSchemaContext(result);
     }
 
+    private LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> resolveModulesWithImports(List<ModuleBuilder> sorted,
+            SchemaContext context) {
+        final LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> modules = orderModules(sorted);
+        for (ModuleBuilder module : sorted) {
+            if (module != null) {
+                for (ModuleImport imp : module.getImports().values()) {
+                    String prefix = imp.getPrefix();
+                    ModuleBuilder targetModule = findModuleFromBuilders(modules, module, prefix, 0);
+                    if (targetModule == null) {
+                        Module result = findModuleFromContext(context, module, prefix, 0);
+                        targetModule = new ModuleBuilder(result);
+                        TreeMap<Date, ModuleBuilder> map = modules.get(prefix);
+                        if (map == null) {
+                            map = new TreeMap<>();
+                            map.put(targetModule.getRevision(), targetModule);
+                            modules.put(targetModule.getName(), map);
+                        } else {
+                            map.put(targetModule.getRevision(), targetModule);
+                        }
+                    }
+                    module.addImportedModule(prefix, targetModule);
+                }
+            }
+        }
+        return modules;
+    }
+
     @Override
     public Map<File, Module> parseYangModelsMapped(final Collection<File> yangFiles) {
         if (yangFiles == null || yangFiles.isEmpty()) {
@@ -325,7 +345,7 @@ public final class YangParserImpl implements YangContextParser {
     }
 
     private Map<ByteSource, Module> parseYangModelSources(final Collection<ByteSource> sources) throws IOException,
-    YangSyntaxErrorException {
+            YangSyntaxErrorException {
         if (sources == null || sources.isEmpty()) {
             return Collections.emptyMap();
         }
@@ -333,7 +353,7 @@ public final class YangParserImpl implements YangContextParser {
         Map<ByteSource, ModuleBuilder> sourceToBuilder = resolveSources(sources);
         // sort and check for duplicates
         List<ModuleBuilder> sorted = ModuleDependencySort.sort(sourceToBuilder.values());
-        Map<String, TreeMap<Date, ModuleBuilder>> modules = orderModules(sorted);
+        Map<String, TreeMap<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());
@@ -357,8 +377,8 @@ public final class YangParserImpl implements YangContextParser {
      * @throws YangSyntaxErrorException
      */
     // TODO: remove ByteSource result after removing YangModelParser
-    private Map<ByteSource, ModuleBuilder> resolveSources(final Collection<ByteSource> streams)
-            throws IOException, YangSyntaxErrorException {
+    private Map<ByteSource, ModuleBuilder> resolveSources(final Collection<ByteSource> streams) throws IOException,
+            YangSyntaxErrorException {
         Map<ByteSource, ModuleBuilder> builders = parseSourcesToBuilders(streams);
         return resolveSubmodules(builders);
     }
@@ -376,8 +396,9 @@ public final class YangParserImpl implements YangContextParser {
         for (Map.Entry<ByteSource, ParseTree> entry : sourceToTree.entrySet()) {
             ByteSource source = entry.getKey();
             String path = null; // TODO refactor to Optional
-            //TODO refactor so that path can be retrieved without opening stream: NamedInputStream -> NamedByteSource ?
-            try(InputStream stream = source.openStream()) {
+            // TODO refactor so that path can be retrieved without opening
+            // stream: NamedInputStream -> NamedByteSource ?
+            try (InputStream stream = source.openStream()) {
                 if (stream instanceof NamedInputStream) {
                     path = stream.toString();
                 }
@@ -446,7 +467,7 @@ public final class YangParserImpl implements YangContextParser {
     private void addSubmoduleToModule(final ModuleBuilder submodule, final ModuleBuilder module) {
         submodule.setParent(module);
         module.getDirtyNodes().addAll(submodule.getDirtyNodes());
-        module.getModuleImports().addAll(submodule.getModuleImports());
+        module.getImports().putAll(submodule.getImports());
         module.getAugments().addAll(submodule.getAugments());
         module.getAugmentBuilders().addAll(submodule.getAugmentBuilders());
         module.getAllAugments().addAll(submodule.getAllAugments());
@@ -476,9 +497,8 @@ public final class YangParserImpl implements YangContextParser {
         module.getAllUnknownNodes().addAll(submodule.getAllUnknownNodes());
     }
 
-    private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(
-            final Collection<ByteSource> yangFileStreams, final SchemaContext context) throws IOException,
-            YangSyntaxErrorException {
+    private List<ModuleBuilder> resolveModuleBuilders(final Collection<ByteSource> yangFileStreams,
+            final SchemaContext context) throws IOException, YangSyntaxErrorException {
         Map<ByteSource, ModuleBuilder> parsedBuilders = resolveSources(yangFileStreams);
         ModuleBuilder[] builders = new ModuleBuilder[parsedBuilders.size()];
         parsedBuilders.values().toArray(builders);
@@ -490,14 +510,14 @@ public final class YangParserImpl implements YangContextParser {
         } else {
             sorted = ModuleDependencySort.sortWithContext(context, builders);
         }
-        return orderModules(sorted);
+        return sorted;
     }
 
     /**
      * Order modules by name and revision.
      *
      * @param modules
-     *            modules to order
+     *            topologically sorted modules
      * @return modules ordered by name and revision
      */
     private LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> orderModules(final List<ModuleBuilder> modules) {
@@ -514,9 +534,11 @@ public final class YangParserImpl implements YangContextParser {
             TreeMap<Date, ModuleBuilder> builderByRevision = result.get(builderName);
             if (builderByRevision == null) {
                 builderByRevision = new TreeMap<>();
+                builderByRevision.put(builderRevision, builder);
+                result.put(builderName, builderByRevision);
+            } else {
+                builderByRevision.put(builderRevision, builder);
             }
-            builderByRevision.put(builderRevision, builder);
-            result.put(builderName, builderByRevision);
         }
         return result;
     }
@@ -534,7 +556,7 @@ public final class YangParserImpl implements YangContextParser {
      */
     private void filterImports(final ModuleBuilder main, final Collection<ModuleBuilder> other,
             final Collection<ModuleBuilder> filtered) {
-        Set<ModuleImport> imports = main.getModuleImports();
+        Map<String, ModuleImport> imports = main.getImports();
 
         // if this is submodule, add parent to filtered and pick its imports
         if (main.isSubmodule()) {
@@ -546,10 +568,10 @@ public final class YangParserImpl implements YangContextParser {
             }
             ModuleBuilder parent = dependencies.get(dependencies.firstKey());
             filtered.add(parent);
-            imports.addAll(parent.getModuleImports());
+            imports.putAll(parent.getImports());
         }
 
-        for (ModuleImport mi : imports) {
+        for (ModuleImport mi : imports.values()) {
             for (ModuleBuilder builder : other) {
                 if (mi.getModuleName().equals(builder.getModuleName())) {
                     if (mi.getRevision() == null) {
@@ -571,7 +593,7 @@ public final class YangParserImpl implements YangContextParser {
     }
 
     private Map<ByteSource, ParseTree> parseYangSources(final Collection<ByteSource> sources) throws IOException,
-    YangSyntaxErrorException {
+            YangSyntaxErrorException {
         final Map<ByteSource, ParseTree> trees = new HashMap<>();
         for (ByteSource source : sources) {
             trees.put(source, parseYangSource(source));
@@ -598,8 +620,9 @@ 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.
+     * Mini parser: This parsing context does not validate full YANG module,
+     * only parses header up to the revisions and imports.
+     *
      * @see org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo
      */
     public static YangContext parseStreamWithoutErrorListeners(final InputStream yangStream) {
@@ -640,11 +663,11 @@ public final class YangParserImpl implements YangContextParser {
      */
     private Map<ModuleBuilder, Module> build(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
         resolveDirtyNodes(modules);
-        resolveAugmentsTargetPath(modules, null);
-        resolveUsesTargetGrouping(modules, null);
-        resolveUsesForGroupings(modules, null);
-        resolveUsesForNodes(modules, null);
-        resolveAugments(modules, null);
+        resolveAugmentsTargetPath(modules);
+        resolveUsesTargetGrouping(modules);
+        resolveUsesForGroupings(modules);
+        resolveUsesForNodes(modules);
+        resolveAugments(modules);
         resolveIdentities(modules);
         resolveDeviations(modules);
 
@@ -660,52 +683,6 @@ public final class YangParserImpl implements YangContextParser {
         return result;
     }
 
-    /**
-     * Creates builder-to-module map based on given modules. Method first
-     * resolve unresolved type references, instantiate groupings through uses
-     * statements and perform augmentation.
-     *
-     * Node resolving must be performed in following order:
-     * <ol>
-     * <li>
-     * unresolved type references</li>
-     * <li>
-     * uses in groupings</li>
-     * <li>
-     * uses in other nodes</li>
-     * <li>
-     * augments</li>
-     * </ol>
-     *
-     * @param modules
-     *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules
-     * @return modules mapped on their builders
-     */
-    private Map<ModuleBuilder, Module> buildWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final SchemaContext context) {
-        resolvedDirtyNodesWithContext(modules, context);
-        resolveAugmentsTargetPath(modules, context);
-        resolveUsesTargetGrouping(modules, context);
-        resolveUsesForGroupings(modules, context);
-        resolveUsesForNodes(modules, context);
-        resolveAugments(modules, context);
-        resolveIdentitiesWithContext(modules, context);
-        resolveDeviationsWithContext(modules, context);
-
-        // build
-        final Map<ModuleBuilder, Module> result = new LinkedHashMap<>();
-        for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
-            for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
-                final ModuleBuilder moduleBuilder = childEntry.getValue();
-                final Module module = moduleBuilder.build();
-                result.put(moduleBuilder, module);
-            }
-        }
-        return result;
-    }
-
     /**
      * Resolve all unresolved type references.
      *
@@ -722,25 +699,6 @@ public final class YangParserImpl implements YangContextParser {
         }
     }
 
-    /**
-     * Resolve all unresolved type references.
-     *
-     * @param modules
-     *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules
-     */
-    private void resolvedDirtyNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final SchemaContext context) {
-        for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
-            for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
-                final ModuleBuilder module = childEntry.getValue();
-                resolveUnknownNodesWithContext(modules, module, context);
-                resolveDirtyNodesWithContext(modules, module, context);
-            }
-        }
-    }
-
     /**
      * Search for dirty nodes (node which contains UnknownType) and resolve
      * unknown types.
@@ -774,39 +732,14 @@ public final class YangParserImpl implements YangContextParser {
         }
     }
 
-    private void resolveDirtyNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder module, final SchemaContext context) {
-        final Set<TypeAwareBuilder> dirtyNodes = module.getDirtyNodes();
-        if (!dirtyNodes.isEmpty()) {
-            for (TypeAwareBuilder nodeToResolve : dirtyNodes) {
-                if (nodeToResolve instanceof UnionTypeBuilder) {
-                    // special handling for union types
-                    resolveTypeUnionWithContext((UnionTypeBuilder) nodeToResolve, modules, module, context);
-                } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) {
-                    // special handling for identityref types
-                    IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef();
-                    IdentitySchemaNodeBuilder identity = findBaseIdentity(modules, module, idref.getBaseString(),
-                            idref.getLine());
-                    idref.setBaseIdentity(identity);
-                    nodeToResolve.setType(idref.build());
-                } else {
-                    resolveTypeWithContext(nodeToResolve, modules, module, context);
-                }
-            }
-        }
-    }
-
     /**
      * Traverse through augmentations of modules and fix their child nodes
      * schema path.
      *
      * @param modules
      *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules
      */
-    private void resolveAugmentsTargetPath(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final SchemaContext context) {
+    private void resolveAugmentsTargetPath(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
         // collect augments from all loaded modules
         final List<AugmentationSchemaBuilder> allAugments = new ArrayList<>();
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
@@ -816,7 +749,7 @@ public final class YangParserImpl implements YangContextParser {
         }
 
         for (AugmentationSchemaBuilder augment : allAugments) {
-            setCorrectAugmentTargetPath(modules, augment, context);
+            setCorrectAugmentTargetPath(modules, augment);
         }
     }
 
@@ -827,13 +760,11 @@ public final class YangParserImpl implements YangContextParser {
      *            all loaded modules
      * @param augment
      *            augment to resolve
-     * @param context
-     *            SchemaContext containing already resolved modules
      */
     private void setCorrectAugmentTargetPath(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final AugmentationSchemaBuilder augment, final SchemaContext context) {
+            final AugmentationSchemaBuilder augment) {
         ModuleBuilder module = BuilderUtils.getParentModule(augment);
-        SchemaPath oldSchemaPath = augment.getTargetPath();
+        Iterable<QName> oldPath = augment.getTargetPath().getPathFromRoot();
         List<QName> newPath = new ArrayList<>();
 
         Builder parent = augment.getParent();
@@ -841,9 +772,9 @@ public final class YangParserImpl implements YangContextParser {
             DataNodeContainerBuilder usesParent = ((UsesNodeBuilder) parent).getParent();
             newPath.addAll(usesParent.getPath().getPath());
 
-            final QName baseQName = usesParent.getQName();
+            QName baseQName = usesParent.getQName();
             final QNameModule qnm;
-            final String prefix;
+            String prefix;
             if (baseQName == null) {
                 ModuleBuilder m = BuilderUtils.getParentModule(usesParent);
                 qnm = m.getQNameModule();
@@ -853,27 +784,20 @@ public final class YangParserImpl implements YangContextParser {
                 prefix = baseQName.getPrefix();
             }
 
-            for (QName qn : oldSchemaPath.getPathFromRoot()) {
+            for (QName qn : oldPath) {
                 newPath.add(QName.create(qnm, prefix, qn.getLocalName()));
             }
         } else {
-            Iterable<QName> oldPath = oldSchemaPath.getPathFromRoot();
             for (QName qn : oldPath) {
                 QNameModule qnm = module.getQNameModule();
                 String localPrefix = qn.getPrefix();
                 if (localPrefix != null && !localPrefix.isEmpty()) {
-                    ModuleBuilder currentModule = BuilderUtils.findModuleFromBuilders(modules, module, localPrefix,
-                            augment.getLine());
+                    ModuleBuilder currentModule = BuilderUtils.getModuleByPrefix(module, localPrefix);
                     if (currentModule == null) {
-                        Module m = BuilderUtils.findModuleFromContext(context, module, localPrefix, augment.getLine());
-                        if (m == null) {
-                            throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix "
-                                    + localPrefix + " not found.");
-                        }
-                        qnm = m.getQNameModule();
-                    } else {
-                        qnm = currentModule.getQNameModule();
+                        throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix "
+                                + localPrefix + " not found.");
                     }
+                    qnm = currentModule.getQNameModule();
                 }
                 newPath.add(new QName(qnm.getNamespace(), qnm.getRevision(), localPrefix, qn.getLocalName()));
             }
@@ -941,11 +865,10 @@ public final class YangParserImpl implements YangContextParser {
      * Go through all augment definitions and resolve them.
      *
      * @param modules
-     *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules
+     *            all loaded modules topologically sorted (based on dependencies
+     *            between each other)
      */
-    private void resolveAugments(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context) {
+    private void resolveAugments(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
         List<ModuleBuilder> all = new ArrayList<>();
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
@@ -953,21 +876,14 @@ public final class YangParserImpl implements YangContextParser {
             }
         }
 
-        List<ModuleBuilder> sorted;
-        if (context == null) {
-            sorted = ModuleDependencySort.sort(all.toArray(new ModuleBuilder[all.size()]));
-        } else {
-            sorted = ModuleDependencySort.sortWithContext(context, all.toArray(new ModuleBuilder[all.size()]));
-        }
-
-        for (ModuleBuilder mb : sorted) {
+        for (ModuleBuilder mb : all) {
             if (mb != null) {
                 List<AugmentationSchemaBuilder> augments = mb.getAllAugments();
                 checkAugmentMandatoryNodes(augments);
                 Collections.sort(augments, Comparators.AUGMENT_COMP);
                 for (AugmentationSchemaBuilder augment : augments) {
                     if (!(augment.isResolved())) {
-                        boolean resolved = resolveAugment(augment, mb, modules, context);
+                        boolean resolved = resolveAugment(augment, mb, modules);
                         if (!resolved) {
                             throw new YangParseException(augment.getModuleName(), augment.getLine(),
                                     "Error in augment parsing: failed to find augment target: " + augment);
@@ -987,12 +903,10 @@ public final class YangParserImpl implements YangContextParser {
      *            current module
      * @param modules
      *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules
      * @return true if augment process succeed
      */
     private boolean resolveUsesAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context) {
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
         if (augment.isResolved()) {
             return true;
         }
@@ -1006,12 +920,14 @@ public final class YangParserImpl implements YangContextParser {
             // We lookup in data namespace to find correct augmentation target
             potentialTargetNode = findSchemaNodeInModule(resolvedTargetPath, (ModuleBuilder) parentNode);
         } else {
-            // Uses is used in local context (be it data namespace or grouping namespace,
+            // Uses is used in local context (be it data namespace or grouping
+            // namespace,
             // since all nodes via uses are imported to localName, it is safe to
             // to proceed only with local names.
             //
             // Conflicting elements in other namespaces are still not present
-            // since resolveUsesAugment occurs before augmenting from external modules.
+            // since resolveUsesAugment occurs before augmenting from external
+            // modules.
             potentialTargetNode = Optional.<SchemaNodeBuilder> fromNullable(findSchemaNode(augment.getTargetPath()
                     .getPath(), (SchemaNodeBuilder) parentNode));
         }
@@ -1043,18 +959,16 @@ public final class YangParserImpl implements YangContextParser {
      *            current module
      * @param modules
      *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules
      * @return true if augment process succeed
      */
     private boolean resolveAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context) {
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
         if (augment.isResolved()) {
             return true;
         }
 
-        QName targetPath = augment.getTargetPath().getPathFromRoot().iterator().next();
-        ModuleBuilder targetModule = findTargetModule(targetPath, module, modules, context, augment.getLine());
+        QName targetModuleName = augment.getTargetPath().getPathFromRoot().iterator().next();
+        ModuleBuilder targetModule = BuilderUtils.getModuleByPrefix(module, targetModuleName.getPrefix());
         if (targetModule == null) {
             throw new YangParseException(module.getModuleName(), augment.getLine(), "Failed to resolve augment "
                     + augment);
@@ -1063,80 +977,12 @@ public final class YangParserImpl implements YangContextParser {
         return processAugmentation(augment, targetModule);
     }
 
-    /**
-     * Find module from loaded modules or from context based on given qname. If
-     * module is found in context, create wrapper over this module and add it to
-     * collection of loaded modules.
-     *
-     * @param qname
-     * @param module
-     *            current module
-     * @param modules
-     *            all loaded modules
-     * @param context
-     *            schema context
-     * @param line
-     *            current line
-     * @return
-     */
-    private ModuleBuilder findTargetModule(final QName qname, final ModuleBuilder module,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context, final int line) {
-        ModuleBuilder targetModule;
-
-        String prefix = qname.getPrefix();
-        if (prefix == null || prefix.isEmpty()) {
-            targetModule = module;
-        } else {
-            targetModule = findModuleFromBuilders(modules, module, qname.getPrefix(), line);
-        }
-
-        if (targetModule == null && context != null) {
-            Module m = findModuleFromContext(context, module, prefix, line);
-            targetModule = new ModuleBuilder(m);
-            DataSchemaNode firstNode = m.getDataChildByName(qname.getLocalName());
-            DataSchemaNodeBuilder firstNodeWrapped = wrapChildNode(targetModule.getModuleName(), line, firstNode,
-                    targetModule.getPath(), firstNode.getQName());
-            targetModule.addChildNode(firstNodeWrapped);
-
-            TreeMap<Date, ModuleBuilder> map = new TreeMap<>();
-            map.put(targetModule.getRevision(), targetModule);
-            modules.put(targetModule.getModuleName(), map);
-        }
-
-        return targetModule;
-    }
-
-    private ModuleBuilder findTargetModule(final String prefix, final ModuleBuilder module,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context, final int line) {
-        ModuleBuilder targetModule;
-
-        if (prefix == null || prefix.equals("")) {
-            targetModule = module;
-        } else {
-            targetModule = findModuleFromBuilders(modules, module, prefix, line);
-        }
-
-        if (targetModule == null && context != null) {
-            Module m = findModuleFromContext(context, module, prefix, line);
-            if (m != null) {
-                targetModule = new ModuleBuilder(m);
-                TreeMap<Date, ModuleBuilder> map = new TreeMap<>();
-                map.put(targetModule.getRevision(), targetModule);
-                modules.put(targetModule.getModuleName(), map);
-            }
-        }
-
-        return targetModule;
-    }
-
     /**
      * Go through identity statements defined in current module and resolve
-     * their 'base' statement if present.
+     * their 'base' statement.
      *
      * @param modules
-     *            all modules
-     * @param module
-     *            module being resolved
+     *            all loaded modules
      */
     private void resolveIdentities(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
@@ -1144,68 +990,32 @@ public final class YangParserImpl implements YangContextParser {
                 ModuleBuilder module = inner.getValue();
                 final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
                 for (IdentitySchemaNodeBuilder identity : identities) {
-                    final String baseIdentityName = identity.getBaseIdentityName();
-                    final int line = identity.getLine();
-                    if (baseIdentityName != null) {
-                        IdentitySchemaNodeBuilder baseIdentity = findBaseIdentity(modules, module, baseIdentityName,
-                                line);
-                        if (baseIdentity == null) {
-                            throw new YangParseException(module.getName(), identity.getLine(),
-                                    "Failed to find base identity");
-                        } else {
-                            identity.setBaseIdentity(baseIdentity);
-                        }
-                    }
+                    resolveIdentity(modules, module, identity);
                 }
-
             }
         }
     }
 
-    /**
-     * Go through identity statements defined in current module and resolve
-     * their 'base' statement. Method tries to find base identity in given
-     * modules. If base identity is not found, method will search it in context.
-     *
-     * @param modules
-     *            all loaded modules
-     * @param module
-     *            current module
-     * @param context
-     *            SchemaContext containing already resolved modules
-     */
-    private void resolveIdentitiesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final SchemaContext context) {
-        for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
-            for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
-                ModuleBuilder module = inner.getValue();
-                final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
-                for (IdentitySchemaNodeBuilder identity : identities) {
-                    final String baseIdentityName = identity.getBaseIdentityName();
-                    final int line = identity.getLine();
-                    if (baseIdentityName != null) {
-
-                        IdentitySchemaNodeBuilder result = null;
-                        if (baseIdentityName.indexOf(':') != -1) {
-                            final Iterator<String> split = COLON_SPLITTER.split(baseIdentityName).iterator();
-                            final String prefix = split.next();
-                            final String name = split.next();
-                            if (split.hasNext()) {
-                                throw new YangParseException(module.getName(), line,
-                                        "Failed to parse identityref base: " + baseIdentityName);
-                            }
-
-                            ModuleBuilder dependentModule = findTargetModule(prefix, module, modules, context, line);
-                            if (dependentModule != null) {
-                                result = BuilderUtils.findIdentity(dependentModule.getAddedIdentities(), name);
-                            }
-                        } else {
-                            result = BuilderUtils.findIdentity(module.getAddedIdentities(), baseIdentityName);
-                        }
-                        identity.setBaseIdentity(result);
-                    }
+    private void resolveIdentity(final Map<String, TreeMap<Date, ModuleBuilder>> modules, ModuleBuilder module,
+            final IdentitySchemaNodeBuilder identity) {
+        final String baseIdentityName = identity.getBaseIdentityName();
+        if (baseIdentityName != null) {
+            IdentitySchemaNodeBuilder result = null;
+            if (baseIdentityName.contains(":")) {
+                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);
                 }
+                String prefix = splittedBase[0];
+                String name = splittedBase[1];
+                ModuleBuilder dependentModule = BuilderUtils.getModuleByPrefix(module, prefix);
+                result = BuilderUtils.findIdentity(dependentModule.getAddedIdentities(), name);
+            } else {
+                result = BuilderUtils.findIdentity(module.getAddedIdentities(), baseIdentityName);
             }
+            identity.setBaseIdentity(result);
         }
     }
 
@@ -1214,12 +1024,8 @@ public final class YangParserImpl implements YangContextParser {
      *
      * @param modules
      *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules or null if
-     *            context is not available
      */
-    private void resolveUsesTargetGrouping(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final SchemaContext context) {
+    private void resolveUsesTargetGrouping(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
         final List<UsesNodeBuilder> allUses = new ArrayList<>();
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
@@ -1231,17 +1037,10 @@ public final class YangParserImpl implements YangContextParser {
             final GroupingBuilder targetGroupingBuilder = GroupingUtils.getTargetGroupingFromModules(usesNode, modules,
                     module);
             if (targetGroupingBuilder == null) {
-                if (context == null) {
-                    throw new YangParseException(module.getName(), usesNode.getLine(), "Referenced grouping '"
-                            + usesNode.getGroupingPathAsString() + "' not found.");
-                } else {
-                    GroupingDefinition targetGroupingDefinition = GroupingUtils.getTargetGroupingFromContext(usesNode,
-                            module, context);
-                    usesNode.setGroupingDefinition(targetGroupingDefinition);
-                }
-            } else {
-                usesNode.setGrouping(targetGroupingBuilder);
+                throw new YangParseException(module.getName(), usesNode.getLine(), "Referenced grouping '"
+                        + usesNode.getGroupingPathAsString() + "' not found.");
             }
+            usesNode.setGrouping(targetGroupingBuilder);
         }
     }
 
@@ -1250,11 +1049,8 @@ public final class YangParserImpl implements YangContextParser {
      *
      * @param modules
      *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules
      */
-    private void resolveUsesForGroupings(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final SchemaContext context) {
+    private void resolveUsesForGroupings(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
         final Set<GroupingBuilder> allGroupings = new HashSet<>();
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
@@ -1267,7 +1063,7 @@ public final class YangParserImpl implements YangContextParser {
             List<UsesNodeBuilder> usesNodes = new ArrayList<>(GroupingSort.getAllUsesNodes(gb));
             Collections.sort(usesNodes, new GroupingUtils.UsesComparator());
             for (UsesNodeBuilder usesNode : usesNodes) {
-                resolveUses(usesNode, modules, context);
+                resolveUses(usesNode, modules);
             }
         }
     }
@@ -1277,18 +1073,15 @@ public final class YangParserImpl implements YangContextParser {
      *
      * @param modules
      *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules
      */
-    private void resolveUsesForNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final SchemaContext context) {
+    private void resolveUsesForNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
                 ModuleBuilder module = inner.getValue();
                 List<UsesNodeBuilder> usesNodes = module.getAllUsesNodes();
                 Collections.sort(usesNodes, new GroupingUtils.UsesComparator());
                 for (UsesNodeBuilder usesNode : usesNodes) {
-                    resolveUses(usesNode, modules, context);
+                    resolveUses(usesNode, modules);
                 }
             }
         }
@@ -1302,11 +1095,8 @@ public final class YangParserImpl implements YangContextParser {
      *            uses node to resolve
      * @param modules
      *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules
      */
-    private void resolveUses(final UsesNodeBuilder usesNode, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final SchemaContext context) {
+    private void resolveUses(final UsesNodeBuilder usesNode, final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
         if (!usesNode.isResolved()) {
             DataNodeContainerBuilder parent = usesNode.getParent();
             ModuleBuilder module = BuilderUtils.getParentModule(parent);
@@ -1315,7 +1105,7 @@ public final class YangParserImpl implements YangContextParser {
                 resolveUsesWithContext(usesNode);
                 usesNode.setResolved(true);
                 for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) {
-                    resolveUsesAugment(augment, module, modules, context);
+                    resolveUsesAugment(augment, module, modules);
                 }
             } else {
                 parent.getChildNodeBuilders().addAll(target.instantiateChildNodes(parent));
@@ -1324,7 +1114,7 @@ public final class YangParserImpl implements YangContextParser {
                 parent.getUnknownNodes().addAll(target.instantiateUnknownNodes(parent));
                 usesNode.setResolved(true);
                 for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) {
-                    resolveUsesAugment(augment, module, modules, context);
+                    resolveUsesAugment(augment, module, modules);
                 }
             }
             GroupingUtils.performRefine(usesNode);
@@ -1336,10 +1126,6 @@ public final class YangParserImpl implements YangContextParser {
      *
      * @param usesNode
      *            uses node to resolve
-     * @param modules
-     *            all loaded modules
-     * @param context
-     *            SchemaContext containing already resolved modules
      */
     private void resolveUsesWithContext(final UsesNodeBuilder usesNode) {
         final int line = usesNode.getLine();
@@ -1391,8 +1177,8 @@ public final class YangParserImpl implements YangContextParser {
     }
 
     /**
-     * Try to find extension builder describing this unknown node and assign it
-     * to unknown node builder.
+     * Try to find extension describing this unknown node and assign it to
+     * unknown node builder.
      *
      * @param modules
      *            all loaded modules
@@ -1402,69 +1188,44 @@ public final class YangParserImpl implements YangContextParser {
     private void resolveUnknownNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) {
             QName nodeType = usnb.getNodeType();
-            try {
-                ModuleBuilder dependentModule = findModuleFromBuilders(modules, module, nodeType.getPrefix(),
-                        usnb.getLine());
-                for (ExtensionBuilder extension : dependentModule.getAddedExtensions()) {
-                    if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) {
-                        usnb.setNodeType(extension.getQName());
-                        usnb.setExtensionBuilder(extension);
-                        break;
-                    }
+            ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, nodeType.getPrefix());
+            ExtensionBuilder extBuilder = findExtBuilder(nodeType.getLocalName(),
+                    dependentModuleBuilder.getAddedExtensions());
+            if (extBuilder == null) {
+                ExtensionDefinition extDef = findExtDef(nodeType.getLocalName(), dependentModuleBuilder.getExtensions());
+                if (extDef == null) {
+                    LOG.warn(
+                            "Error in module {} at line {}: Failed to resolve node {}: no such extension definition found.",
+                            module.getName(), usnb.getLine(), usnb);
+                } else {
+                    usnb.setNodeType(new QName(extDef.getQName().getNamespace(), extDef.getQName().getRevision(),
+                            nodeType.getPrefix(), extDef.getQName().getLocalName()));
+                    usnb.setExtensionDefinition(extDef);
                 }
-            } catch (YangParseException e) {
-                throw new YangParseException(module.getName(), usnb.getLine(), "Failed to resolve node " + usnb
-                        + ": no such extension definition found.", e);
+            } else {
+                usnb.setNodeType(new QName(extBuilder.getQName().getNamespace(), extBuilder.getQName().getRevision(),
+                        nodeType.getPrefix(), extBuilder.getQName().getLocalName()));
+                usnb.setExtensionBuilder(extBuilder);
             }
         }
     }
 
-    /**
-     * Try to find extension builder describing this unknown node and assign it
-     * to unknown node builder. If extension is not found in loaded modules, try
-     * to find it in context.
-     *
-     * @param modules
-     *            all loaded modules
-     * @param module
-     *            current module
-     * @param context
-     *            SchemaContext containing already resolved modules
-     */
-    private void resolveUnknownNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder module, final SchemaContext context) {
-        for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) {
-            QName nodeType = usnb.getNodeType();
-            try {
-                ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, nodeType.getPrefix(),
-                        usnb.getLine());
-
-                if (dependentModuleBuilder == null) {
-                    Module dependentModule = findModuleFromContext(context, module, nodeType.getPrefix(),
-                            usnb.getLine());
-                    for (ExtensionDefinition e : dependentModule.getExtensionSchemaNodes()) {
-                        if (e.getQName().getLocalName().equals(nodeType.getLocalName())) {
-                            usnb.setNodeType(new QName(e.getQName().getNamespace(), e.getQName().getRevision(),
-                                    nodeType.getPrefix(), e.getQName().getLocalName()));
-                            usnb.setExtensionDefinition(e);
-                            break;
-                        }
-                    }
-                } else {
-                    for (ExtensionBuilder extension : dependentModuleBuilder.getAddedExtensions()) {
-                        if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) {
-                            usnb.setExtensionBuilder(extension);
-                            break;
-                        }
-                    }
-                }
-
-            } catch (YangParseException e) {
-                throw new YangParseException(module.getName(), usnb.getLine(), "Failed to resolve node " + usnb
-                        + ": no such extension definition found.", e);
+    private ExtensionBuilder findExtBuilder(final String name, final Collection<ExtensionBuilder> extensions) {
+        for (ExtensionBuilder extension : extensions) {
+            if (extension.getQName().getLocalName().equals(name)) {
+                return extension;
             }
+        }
+        return null;
+    }
 
+    private ExtensionDefinition findExtDef(final String name, final Collection<ExtensionDefinition> extensions) {
+        for (ExtensionDefinition extension : extensions) {
+            if (extension.getQName().getLocalName().equals(name)) {
+                return extension;
+            }
         }
+        return null;
     }
 
     /**
@@ -1492,7 +1253,6 @@ public final class YangParserImpl implements YangContextParser {
      */
     private void resolveDeviation(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         for (DeviationBuilder dev : module.getDeviationBuilders()) {
-            int line = dev.getLine();
             SchemaPath targetPath = dev.getTargetPath();
             Iterable<QName> path = targetPath.getPathFromRoot();
             QName q0 = path.iterator().next();
@@ -1501,80 +1261,11 @@ public final class YangParserImpl implements YangContextParser {
                 prefix = module.getPrefix();
             }
 
-            ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, prefix, line);
+            ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, prefix);
             processDeviation(dev, dependentModuleBuilder, path, module);
         }
     }
 
-    /**
-     * Traverse through modules and resolve their deviation statements with
-     * given context.
-     *
-     * @param modules
-     *            all loaded modules
-     * @param context
-     *            already resolved context
-     */
-    private void resolveDeviationsWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final SchemaContext context) {
-        for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
-            for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
-                ModuleBuilder b = inner.getValue();
-                resolveDeviationWithContext(modules, b, context);
-            }
-        }
-    }
-
-    /**
-     * Traverse through module and resolve its deviation statements with given
-     * context.
-     *
-     * @param modules
-     *            all loaded modules
-     * @param module
-     *            module in which resolve deviations
-     * @param context
-     *            already resolved context
-     */
-    private void resolveDeviationWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder module, final SchemaContext context) {
-        for (DeviationBuilder dev : module.getDeviationBuilders()) {
-            int line = dev.getLine();
-            SchemaPath targetPath = dev.getTargetPath();
-            Iterable<QName> path = targetPath.getPathFromRoot();
-            QName q0 = path.iterator().next();
-            String prefix = q0.getPrefix();
-            if (prefix == null) {
-                prefix = module.getPrefix();
-            }
-
-            ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, prefix, line);
-            if (dependentModuleBuilder == null) {
-                Object currentParent = findModuleFromContext(context, module, prefix, line);
-
-                for (QName q : path) {
-                    if (currentParent == null) {
-                        throw new YangParseException(module.getName(), line, FAIL_DEVIATION_TARGET);
-                    }
-                    String name = q.getLocalName();
-                    if (currentParent instanceof DataNodeContainer) {
-                        currentParent = ((DataNodeContainer) currentParent).getDataChildByName(name);
-                    }
-                }
-
-                if (currentParent == null) {
-                    throw new YangParseException(module.getName(), line, FAIL_DEVIATION_TARGET);
-                }
-                if (currentParent instanceof SchemaNode) {
-                    dev.setTargetPath(((SchemaNode) currentParent).getPath());
-                }
-
-            } else {
-                processDeviation(dev, dependentModuleBuilder, path, module);
-            }
-        }
-    }
-
     /**
      * Correct deviation target path in deviation builder.
      *
index d962c3cfa96caa216e33796a182cce91a0d6a4ef..728a1698a864579818cb9a2648ccc6dec4ea25b6 100644 (file)
@@ -153,7 +153,7 @@ public final class ModuleDependencySort {
 
             String fromName;
             Date fromRevision;
-            Set<ModuleImport> imports;
+            Collection<ModuleImport> imports;
             URI ns;
 
             if (mmb.isModule()) {
@@ -166,7 +166,7 @@ public final class ModuleDependencySort {
                 ModuleBuilder moduleBuilder = mmb.getModuleBuilder();
                 fromName = moduleBuilder.getName();
                 fromRevision = moduleBuilder.getRevision();
-                imports = moduleBuilder.getModuleImports();
+                imports = moduleBuilder.getImports().values();
                 ns = moduleBuilder.getNamespace();
             }
 
index 8c4e130cbc9e54657036c25219192d1ef67c5f9a..16ebf9e4ce91559f1fa68b5c1d80e530f16b7e53 100644 (file)
@@ -21,11 +21,12 @@ import java.net.URI;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
@@ -332,32 +333,22 @@ public class YangParserWithContextTest {
         assertNotNull(un.getExtensionDefinition());
     }
 
-    @Ignore
     @Test
     public void testAugment() throws Exception {
         // load first module
-        SchemaContext context;
         String resource = "/context-augment-test/test4.yang";
-
-        try (InputStream stream = new FileInputStream(new File(getClass().getResource(resource).toURI()))) {
-            context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
-        }
+        SchemaContext context = parser.parseFiles(Collections.singleton(new File(getClass().getResource(resource)
+                .toURI())));
 
         // load another modules and parse them against already existing context
-        Set<Module> modules;
-        try (InputStream stream1 = new FileInputStream(new File(getClass().getResource(
-                "/context-augment-test/test1.yang").toURI()));
-                InputStream stream2 = new FileInputStream(new File(getClass().getResource(
-                        "/context-augment-test/test2.yang").toURI()));
-                InputStream stream3 = new FileInputStream(new File(getClass().getResource(
-                        "/context-augment-test/test3.yang").toURI()))) {
-            List<InputStream> input = Lists.newArrayList(stream1, stream2, stream3);
-            modules = TestUtils.loadModulesWithContext(input, context);
-        }
+        File test1 = new File(getClass().getResource("/context-augment-test/test1.yang").toURI());
+        File test2 = new File(getClass().getResource("/context-augment-test/test2.yang").toURI());
+        File test3 = new File(getClass().getResource("/context-augment-test/test3.yang").toURI());
+        Set<Module> modules = parser.parseFiles(Arrays.asList(test1, test2, test3), context).getModules();
         assertNotNull(modules);
 
-        Module t3 = TestUtils.findModule(modules, "test4");
-        ContainerSchemaNode interfaces = (ContainerSchemaNode) t3.getDataChildByName("interfaces");
+        Module t4 = TestUtils.findModule(modules, "test4");
+        ContainerSchemaNode interfaces = (ContainerSchemaNode) t4.getDataChildByName("interfaces");
         ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
 
         // test augmentation process
index edacfc55727f3d48d42eb0790d21a6c4f39374c0..b1d9e9f0781804effdf90dc03137866c2f62d723 100644 (file)
@@ -20,6 +20,7 @@ import java.text.SimpleDateFormat;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -169,8 +170,9 @@ public class ModuleDependencySortTest {
     private void mockDependency(final ModuleBuilder a, final ModuleBuilder b) {
         ModuleImport imprt = mock(ModuleImport.class);
         doReturn(b.getName()).when(imprt).getModuleName();
+        doReturn(b.getName()).when(imprt).getPrefix();
         doReturn(b.getRevision()).when(imprt).getRevision();
-        a.getModuleImports().add(imprt);
+        a.getImports().put(b.getName(), imprt);
     }
 
     private void mockDependency(final Module a, final Module b) {
@@ -183,8 +185,8 @@ public class ModuleDependencySortTest {
     private ModuleBuilder mockModuleBuilder(final String name, final Date rev) {
         ModuleBuilder a = mock(ModuleBuilder.class);
         doReturn(name).when(a).getName();
-        Set<ModuleImport> set = Sets.newHashSet();
-        doReturn(set).when(a).getModuleImports();
+        Map<String, ModuleImport> map = new HashMap<>();
+        doReturn(map).when(a).getImports();
         if (rev != null) {
             doReturn(rev).when(a).getRevision();
         }
index 733e1003678fb9f5e9df1070df2f0d504c2b70db..514bc5e2c4a17efe43a668b863cbb62d5b64c9ee 100644 (file)
@@ -10,6 +10,12 @@ module bar {
         reference " WILL BE DEFINED LATER";
     }
 
+    extension opendaylight {
+        argument "name" {
+            yin-element "true";
+        }
+    }
+
     container interfaces {
         grouping ifEntry {
             container augment-holder;
index 04468fbffcec9369af3063fad6e4e0dae7c60760..18d81a807d75a7ab2c0f1479111784e585294321 100644 (file)
@@ -24,7 +24,7 @@ module test1 {
         revision 2013-06-18 {
     }
 
-    augment "/t4:interfaces/t4:ifEntry/t2:augment-holder/t3:schemas" {
+    augment "/t4:interfaces/t4:ifEntry/t3:augment-holder/t2:schemas" {
         when "if:ifType='ds0'";
         leaf id {
             type string;
index 1ba514279d03683e1158fde3e71c916c4ad8e369..8a4743f27b704643e2579526e416ad24c2958a77 100644 (file)
@@ -22,7 +22,7 @@ module test1 {
 
     leaf id {
         type inet:port-number {
-            range "0..65536";
+            range "0..65535";
         }
     }
 
index db9ac6d356e4bf671aa30abec586c727100e2603..56de7b6f29c45c19fa06630c9a06297669a7558d 100644 (file)
@@ -97,4 +97,10 @@ module bar {
         }
     }
 
+    extension opendaylight {
+        argument "name" {
+            yin-element "true";
+        }
+    }
+
 }