Fixed qname of nodes defined by uses statement. 86/786/1
authorMartin Vitez <mvitez@cisco.com>
Mon, 5 Aug 2013 07:28:50 +0000 (09:28 +0200)
committerMartin Vitez <mvitez@cisco.com>
Mon, 5 Aug 2013 07:28:50 +0000 (09:28 +0200)
Signed-off-by: Martin Vitez <mvitez@cisco.com>
23 files changed:
yang-maven-plugin/pom.xml
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AnyXmlBuilder.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ChoiceBuilder.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/DeviationBuilder.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/GroupingBuilderImpl.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/LeafSchemaNodeBuilder.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ListSchemaNodeBuilder.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/TypeDefinitionBuilderImpl.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/UnknownSchemaNodeBuilder.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserListenerUtils.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/RefineUtils.java
yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/TypeUtils.java [new file with mode: 0644]
yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/GroupingTest.java
yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TestUtils.java
yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserSimpleTest.java
yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserTest.java
yang-parser-impl/src/test/resources/simple-test/cascade-uses.yang

index 5494e5741e71a2633e40dc773eda14df2c9baca4..1ab0c91b77e118d8cac94141410e5491fa65bd4b 100644 (file)
@@ -94,7 +94,6 @@
                 <artifactId>maven-plugin-plugin</artifactId>
                 <version>3.2</version>
                 <configuration>
-                    <goalPrefix>yangtools</goalPrefix>
                     <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
                 </configuration>
                 <executions>
index fc6d6762bfc575d2a36291287c2faada012bfcf3..c9e8469150eb38376fec568b57e166eae4e1208f 100644 (file)
@@ -38,8 +38,8 @@ public final class AnyXmlBuilder extends AbstractSchemaNodeBuilder implements Da
         constraints = new ConstraintsBuilder(moduleName, line);
     }
 
-    public AnyXmlBuilder(final AnyXmlBuilder builder) {
-        super(builder.getModuleName(), builder.getLine(), builder.getQName());
+    public AnyXmlBuilder(final AnyXmlBuilder builder, final QName qname) {
+        super(builder.getModuleName(), builder.getLine(), qname);
         parent = builder.getParent();
         instance = new AnyXmlSchemaNodeImpl(qname);
         constraints = new ConstraintsBuilder(builder.getConstraints());
index ef7b28b6fd1e66e73d984cd606ba67c1736e8cc5..b4d2fa77738ff7e8a0ded08f8c79270516b049c6 100644 (file)
@@ -34,7 +34,7 @@ import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.util.Comparators;
-import org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils;
+import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 
 public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContainerBuilder implements
@@ -57,7 +57,7 @@ public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContain
     AugmentationSchemaBuilderImpl(final String moduleName, final int line, final String augmentTargetStr) {
         super(moduleName, line, null);
         this.augmentTargetStr = augmentTargetStr;
-        final SchemaPath targetPath = ParserListenerUtils.parseAugmentPath(augmentTargetStr);
+        final SchemaPath targetPath = ParserUtils.parseXPathString(augmentTargetStr);
         dirtyAugmentTarget = targetPath;
         instance = new AugmentationSchemaImpl(targetPath);
     }
index cba4a94e27b1dd2d8c001e17d3173733eb060126..65208431c0ed374ce348337667cf0466a8ad09a7 100644 (file)
@@ -53,8 +53,8 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
         constraints = new ConstraintsBuilder(moduleName, line);
     }
 
-    public ChoiceBuilder(ChoiceBuilder b) {
-        super(b.getModuleName(), b.getLine(), b.getQName());
+    public ChoiceBuilder(ChoiceBuilder b, QName qname) {
+        super(b.getModuleName(), b.getLine(), qname);
         parent = b.getParent();
         instance = new ChoiceNodeImpl(qname);
         constraints = new ConstraintsBuilder(b.getConstraints());
@@ -159,8 +159,7 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
                 caseNode.setAugmenting(false);
             }
             caseBuilder.setPath(caseNode.getPath());
-            SchemaPath newPath = ParserUtils.createSchemaPath(caseNode.getPath(), caseQName.getLocalName(),
-                    caseQName.getNamespace(), caseQName.getRevision(), caseQName.getPrefix());
+            SchemaPath newPath = ParserUtils.createSchemaPath(caseNode.getPath(), caseQName);
             caseNode.setPath(newPath);
             caseBuilder.addChildNode(caseNode);
             addedCases.add(caseBuilder);
index a85400300053d3fe200c94079b0f418cbf1b4698..2abbacdce5e4b074a0409f1425ffdd029467e997 100644 (file)
@@ -72,8 +72,8 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         constraints = new ConstraintsBuilder(moduleName, line);
     }
 
-    public ContainerSchemaNodeBuilder(final ContainerSchemaNodeBuilder b) {
-        super(b.getModuleName(), b.getLine(), b.getQName());
+    public ContainerSchemaNodeBuilder(final ContainerSchemaNodeBuilder b, final QName qname) {
+        super(b.getModuleName(), b.getLine(), qname);
         instance = new ContainerSchemaNodeImpl(b.getQName());
         constraints = new ConstraintsBuilder(b.getConstraints());
         schemaPath = b.getPath();
index 2595af1e7673c304e3fe4b7cdd3ad858231eab95..6cef6238d5cdf9284a031d2c0fffb384007bbd37 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.parser.builder.api.AbstractBuilder;
 import org.opendaylight.yangtools.yang.parser.util.Comparators;
-import org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils;
+import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 
 public final class DeviationBuilder extends AbstractBuilder {
@@ -36,7 +36,7 @@ public final class DeviationBuilder extends AbstractBuilder {
                     "Deviation argument string must be an absolute schema node identifier.");
         }
         this.targetPathStr = targetPathStr;
-        this.targetPath = ParserListenerUtils.parseAugmentPath(targetPathStr);
+        this.targetPath = ParserUtils.parseXPathString(targetPathStr);
         instance = new DeviationImpl();
     }
 
index 90d61c361ab4f802bac05f771be9bceb5535bda2..71a4862aeef7d69a44d35218967ddef1a78c453d 100644 (file)
@@ -52,8 +52,8 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder
         instance = new GroupingDefinitionImpl(qname);
     }
 
-    public GroupingBuilderImpl(GroupingBuilder builder) {
-        super(builder.getModuleName(), builder.getLine(), builder.getQName());
+    public GroupingBuilderImpl(GroupingBuilder builder, QName qname) {
+        super(builder.getModuleName(), builder.getLine(), qname);
         parent = builder.getParent();
         instance = new GroupingDefinitionImpl(qname);
         schemaPath = builder.getPath();
index 0c9153404ab0c18651d02828a488645598a3e3f5..40335b6bfe1f0bdcd673d3b0cd4fd8ed4a4a6cea 100644 (file)
@@ -48,8 +48,8 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder im
         constraints = new ConstraintsBuilder(moduleName, line);
     }
 
-    public LeafListSchemaNodeBuilder(final LeafListSchemaNodeBuilder b) {
-        super(b.getModuleName(), b.getLine(), b.getQName());
+    public LeafListSchemaNodeBuilder(final LeafListSchemaNodeBuilder b, final QName qname) {
+        super(b.getModuleName(), b.getLine(), qname);
         instance = new LeafListSchemaNodeImpl(qname);
 
         type = b.getType();
index 05327e0e6aec2f745e0f0df31542e5de9eae3c90..3ee60d8fd9df73902e64f0011a7ce23d309462ca 100644 (file)
@@ -48,8 +48,8 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implem
         constraints = new ConstraintsBuilder(moduleName, line);
     }
 
-    public LeafSchemaNodeBuilder(final LeafSchemaNodeBuilder b) {
-        super(b.getModuleName(), b.getLine(), b.getQName());
+    public LeafSchemaNodeBuilder(final LeafSchemaNodeBuilder b, final QName qname) {
+        super(b.getModuleName(), b.getLine(), qname);
         instance = new LeafSchemaNodeImpl(qname);
         constraints = new ConstraintsBuilder(b.getConstraints());
         schemaPath = b.getPath();
index 36016a3004ed2e9b63869b5e67b46b7274f465b9..5d6ff0c2ea0d525eb32cb8322f27f86ef7a53cff 100644 (file)
@@ -71,8 +71,8 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
         constraints = new ConstraintsBuilder(moduleName, line);
     }
 
-    public ListSchemaNodeBuilder(final ListSchemaNodeBuilder b) {
-        super(b.getModuleName(), b.getLine(), b.getQName());
+    public ListSchemaNodeBuilder(final ListSchemaNodeBuilder b, final QName qname) {
+        super(b.getModuleName(), b.getLine(), qname);
         instance = new ListSchemaNodeImpl(b.getQName());
         constraints = new ConstraintsBuilder(b.getConstraints());
         schemaPath = b.getPath();
@@ -102,7 +102,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
     public ListSchemaNode build() {
         if (!isBuilt) {
             // process uses
-            for(UsesNodeBuilder use : addedUsesNodes) {
+            for (UsesNodeBuilder use : addedUsesNodes) {
                 addedChildNodes.addAll(use.getTargetChildren());
                 addedGroupings.addAll(use.getTargetGroupings());
                 addedTypedefs.addAll(use.getTargetTypedefs());
index a820f65f032287803a3d3e9256da82459eaa0fc5..a8cd5f4c77b111f81b74ac68e2a990dba8d82dc9 100644 (file)
@@ -58,6 +58,7 @@ import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
     private final ModuleImpl instance;
     private final String name;
+    private final SchemaPath schemaPath;
     private URI namespace;
     private String prefix;
     private Date revision;
@@ -84,6 +85,7 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
     public ModuleBuilder(final String name) {
         super(name, 0, null);
         this.name = name;
+        schemaPath = new SchemaPath(Collections.<QName>emptyList(), true);
         instance = new ModuleImpl(name);
         actualPath.push(this);
     }
@@ -202,7 +204,7 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
 
     @Override
     public SchemaPath getPath() {
-        return null;
+        return schemaPath;
     }
 
     @Override
index 58878a6db3f78d95ebbc5a49731659eff66f7318..7787635658a3720731507e94aa6a1344c8210b34 100644 (file)
@@ -44,8 +44,8 @@ public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder im
         super(moduleName, line, qname);
     }
 
-    public TypeDefinitionBuilderImpl(TypeDefinitionBuilder tdb) {
-        super(tdb.getModuleName(), tdb.getLine(), tdb.getQName());
+    public TypeDefinitionBuilderImpl(TypeDefinitionBuilder tdb, QName qname) {
+        super(tdb.getModuleName(), tdb.getLine(), qname);
         schemaPath = tdb.getPath();
 
         type = tdb.getType();
index 9f360bed647e056c7c11a544aeea76f7498815ec..18b4ec60f46d319fe48e6b3811b2c686d5a8377d 100644 (file)
@@ -30,8 +30,8 @@ public final class UnknownSchemaNodeBuilder extends AbstractSchemaNodeBuilder {
         instance = new UnknownSchemaNodeImpl(qname);
     }
 
-    public UnknownSchemaNodeBuilder(UnknownSchemaNodeBuilder b) {
-        super(b.getModuleName(), b.getLine(), b.getQName());
+    public UnknownSchemaNodeBuilder(UnknownSchemaNodeBuilder b, QName qname) {
+        super(b.getModuleName(), b.getLine(), qname);
         instance = new UnknownSchemaNodeImpl(qname);
         schemaPath = b.getPath();
         description = b.getDescription();
index 93dcadf167133029c52368138e30eab1068b17f4..5dfbe8bf60ea82de602da87596340b7a17d94053 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.yangtools.yang.parser.impl;
 
 import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.*;
+import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.*;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -56,7 +57,6 @@ import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
 import org.opendaylight.yangtools.yang.model.util.IdentityrefType;
-import org.opendaylight.yangtools.yang.model.util.UnknownType;
 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
@@ -67,25 +67,15 @@ import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.AnyXmlBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.DeviationBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.GroupingBuilderImpl;
 import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
 import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
 import org.opendaylight.yangtools.yang.parser.util.RefineHolder;
 import org.opendaylight.yangtools.yang.parser.util.RefineUtils;
-import org.opendaylight.yangtools.yang.parser.util.TypeConstraints;
 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 import org.opendaylight.yangtools.yang.validator.YangModelBasicValidator;
 import org.slf4j.Logger;
@@ -309,9 +299,6 @@ public final class YangParserImpl implements YangModelParser {
         resolveDeviations(modules);
 
         // build
-        // LinkedHashMap MUST be used otherwise the values will not maintain
-        // order!
-        // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html
         final Map<ModuleBuilder, Module> result = new LinkedHashMap<ModuleBuilder, Module>();
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             final Map<Date, Module> modulesByRevision = new HashMap<Date, Module>();
@@ -338,9 +325,6 @@ public final class YangParserImpl implements YangModelParser {
         resolveDeviationsWithContext(modules, context);
 
         // build
-        // LinkedHashMap MUST be used otherwise the values will not maintain
-        // order!
-        // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html
         final Map<ModuleBuilder, Module> result = new LinkedHashMap<ModuleBuilder, Module>();
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             final Map<Date, Module> modulesByRevision = new HashMap<Date, Module>();
@@ -415,211 +399,6 @@ public final class YangParserImpl implements YangModelParser {
         }
     }
 
-    /**
-     * 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
-     */
-    private void resolveType(final TypeAwareBuilder nodeToResolve,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
-        TypeDefinitionBuilder resolvedType = null;
-        final int line = nodeToResolve.getLine();
-        final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
-        final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
-        final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, unknownTypeQName.getPrefix(),
-                line);
-
-        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve, dependentModule,
-                unknownTypeQName.getLocalName(), module.getName(), line);
-
-        if (nodeToResolveType instanceof ExtendedType) {
-            final ExtendedType extType = (ExtendedType) nodeToResolveType;
-            final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, extType,
-                    modules, module, nodeToResolve.getLine());
-            resolvedType = newType;
-        } else {
-            resolvedType = targetTypeBuilder;
-        }
-
-        // validate constraints
-        final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve,
-                new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, null);
-        constraints.validateConstraints();
-
-        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
-     */
-    private void resolveTypeWithContext(final TypeAwareBuilder nodeToResolve,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
-            final SchemaContext context) {
-        TypeDefinitionBuilder resolvedType = null;
-        final int line = nodeToResolve.getLine();
-        final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
-        final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
-        final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(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 = extendedTypeWithNewBaseType(type, extType, 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 {
-            final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve,
-                    dependentModuleBuilder, unknownTypeQName.getLocalName(), module.getName(), line);
-
-            if (nodeToResolveType instanceof ExtendedType) {
-                final ExtendedType extType = (ExtendedType) nodeToResolveType;
-                final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, extType,
-                        modules, module, nodeToResolve.getLine());
-                resolvedType = newType;
-            } else {
-                resolvedType = targetTypeBuilder;
-            }
-
-            // validate constraints
-            final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve, new TypeConstraints(
-                    module.getName(), nodeToResolve.getLine()), modules, module, context);
-            constraints.validateConstraints();
-
-            nodeToResolve.setTypedef(resolvedType);
-        }
-    }
-
-    private 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<TypeDefinition<?>>();
-        for (TypeDefinition<?> unionType : unionTypes) {
-            if (unionType instanceof UnknownType) {
-                final UnknownType ut = (UnknownType) unionType;
-                final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName()
-                        .getPrefix(), union.getLine());
-                final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModule, ut
-                        .getQName().getLocalName(), builder.getName(), union.getLine());
-                union.setTypedef(resolvedType);
-                toRemove.add(ut);
-            } else if (unionType instanceof ExtendedType) {
-                final ExtendedType extType = (ExtendedType) unionType;
-                final TypeDefinition<?> extTypeBase = extType.getBaseType();
-                if (extTypeBase instanceof UnknownType) {
-                    final UnknownType ut = (UnknownType) extTypeBase;
-                    final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName()
-                            .getPrefix(), union.getLine());
-                    final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union, dependentModule,
-                            ut.getQName().getLocalName(), builder.getName(), union.getLine());
-
-                    final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder,
-                            extType, modules, builder, union.getLine());
-
-                    union.setTypedef(newType);
-                    toRemove.add(extType);
-                }
-            }
-        }
-        unionTypes.removeAll(toRemove);
-    }
-
-    private void resolveTypeUnionWithContext(final UnionTypeBuilder union,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder,
-            final SchemaContext context) {
-
-        final List<TypeDefinition<?>> unionTypes = union.getTypes();
-        final List<TypeDefinition<?>> toRemove = new ArrayList<TypeDefinition<?>>();
-        for (TypeDefinition<?> unionType : unionTypes) {
-            if (unionType instanceof UnknownType) {
-                final UnknownType ut = (UnknownType) unionType;
-                final QName utQName = ut.getQName();
-                final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder,
-                        utQName.getPrefix(), union.getLine());
-
-                if (dependentModuleBuilder == null) {
-                    Module dependentModule = findModuleFromContext(context, builder, utQName.getPrefix(),
-                            union.getLine());
-                    Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
-                    TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
-                    union.setType(type);
-                    toRemove.add(ut);
-                } else {
-                    final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModuleBuilder,
-                            utQName.getLocalName(), builder.getName(), union.getLine());
-                    union.setTypedef(resolvedType);
-                    toRemove.add(ut);
-                }
-
-            } else if (unionType instanceof ExtendedType) {
-                final ExtendedType extType = (ExtendedType) unionType;
-                TypeDefinition<?> extTypeBase = extType.getBaseType();
-                if (extTypeBase instanceof UnknownType) {
-                    final UnknownType ut = (UnknownType) extTypeBase;
-                    final QName utQName = ut.getQName();
-                    final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder,
-                            utQName.getPrefix(), union.getLine());
-
-                    if (dependentModuleBuilder == null) {
-                        final Module dependentModule = findModuleFromContext(context, builder, utQName.getPrefix(),
-                                union.getLine());
-                        Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
-                        TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
-                        final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(type, extType, builder, 0);
-
-                        union.setTypedef(newType);
-                        toRemove.add(extType);
-                    } else {
-                        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union,
-                                dependentModuleBuilder, utQName.getLocalName(), builder.getName(), union.getLine());
-
-                        final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder,
-                                extType, modules, builder, union.getLine());
-
-                        union.setTypedef(newType);
-                        toRemove.add(extType);
-                    }
-                }
-            }
-        }
-        unionTypes.removeAll(toRemove);
-    }
-
     /**
      * Go through all augment definitions and resolve them. It is expected that
      * modules are already sorted by their dependencies. This method also finds
@@ -876,8 +655,7 @@ public final class YangParserImpl implements YangModelParser {
     private void resolveUsesNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         final List<UsesNodeBuilder> allModuleUses = module.getAllUsesNodes();
         for (UsesNodeBuilder usesNode : allModuleUses) {
-            // perform uses
-            final int line = usesNode.getLine();
+            // process uses operation
             final GroupingBuilder targetGrouping = getTargetGroupingFromModules(usesNode, modules, module);
             usesNode.setGroupingPath(targetGrouping.getPath());
             processUsesNode(module, usesNode, targetGrouping);
@@ -897,7 +675,7 @@ public final class YangParserImpl implements YangModelParser {
                 if (nodeToRefine instanceof GroupingMember) {
                     ((GroupingMember) nodeToRefine).setAddedByUses(true);
                 }
-                RefineUtils.performRefine(nodeToRefine, refine, line);
+                RefineUtils.performRefine(nodeToRefine, refine);
                 usesNode.addRefineNode(nodeToRefine);
             }
         }
@@ -923,8 +701,6 @@ public final class YangParserImpl implements YangModelParser {
             final ModuleBuilder module, final SchemaContext context) {
         final List<UsesNodeBuilder> moduleUses = module.getAllUsesNodes();
         for (UsesNodeBuilder usesNode : moduleUses) {
-            final int line = usesNode.getLine();
-
             final GroupingBuilder targetGroupingBuilder = getTargetGroupingFromModules(usesNode, modules, module);
             if (targetGroupingBuilder == null) {
                 final GroupingDefinition targetGrouping = getTargetGroupingFromContext(usesNode, module, context);
@@ -945,7 +721,7 @@ public final class YangParserImpl implements YangModelParser {
                     if (nodeToRefine instanceof GroupingMember) {
                         ((GroupingMember) nodeToRefine).setAddedByUses(true);
                     }
-                    RefineUtils.performRefine(nodeToRefine, refine, line);
+                    RefineUtils.performRefine(nodeToRefine, refine);
                     usesNode.addRefineNode(nodeToRefine);
                 }
             } else {
@@ -966,118 +742,13 @@ public final class YangParserImpl implements YangModelParser {
                     if (nodeToRefine instanceof GroupingMember) {
                         ((GroupingMember) nodeToRefine).setAddedByUses(true);
                     }
-                    RefineUtils.performRefine(nodeToRefine, refine, line);
+                    RefineUtils.performRefine(nodeToRefine, refine);
                     usesNode.addRefineNode(nodeToRefine);
                 }
             }
         }
     }
 
-    /**
-     * Search given modules for grouping by name defined in uses node.
-     *
-     * @param usesBuilder
-     *            builder of uses statement
-     * @param modules
-     *            all loaded modules
-     * @param module
-     *            current module
-     * @return grouping with given name if found, null otherwise
-     */
-    private GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
-        final int line = usesBuilder.getLine();
-        final String groupingString = usesBuilder.getGroupingName();
-        String groupingPrefix;
-        String groupingName;
-
-        if (groupingString.contains(":")) {
-            String[] splitted = groupingString.split(":");
-            if (splitted.length != 2 || groupingString.contains("/")) {
-                throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
-            }
-            groupingPrefix = splitted[0];
-            groupingName = splitted[1];
-        } else {
-            groupingPrefix = module.getPrefix();
-            groupingName = groupingString;
-        }
-
-        ModuleBuilder dependentModule = null;
-        if (groupingPrefix.equals(module.getPrefix())) {
-            dependentModule = module;
-        } else {
-            dependentModule = findDependentModuleBuilder(modules, module, groupingPrefix, line);
-        }
-
-        if (dependentModule == null) {
-            return null;
-        }
-
-        GroupingBuilder result = null;
-        Set<GroupingBuilder> groupings = dependentModule.getGroupingBuilders();
-        result = findGroupingBuilder(groupings, groupingName);
-        if (result != null) {
-            return result;
-        }
-
-        Builder parent = usesBuilder.getParent();
-
-        while (parent != null) {
-            if (parent instanceof DataNodeContainerBuilder) {
-                groupings = ((DataNodeContainerBuilder) parent).getGroupingBuilders();
-            } else if (parent instanceof RpcDefinitionBuilder) {
-                groupings = ((RpcDefinitionBuilder) parent).getGroupings();
-            }
-            result = findGroupingBuilder(groupings, groupingName);
-            if (result == null) {
-                parent = parent.getParent();
-            } else {
-                break;
-            }
-        }
-
-        if (result == null) {
-            throw new YangParseException(module.getName(), line, "Referenced 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
-     */
-    private GroupingDefinition getTargetGroupingFromContext(final UsesNodeBuilder usesBuilder,
-            final ModuleBuilder module, final SchemaContext context) {
-        final int line = usesBuilder.getLine();
-        String groupingString = usesBuilder.getGroupingName();
-        String groupingPrefix;
-        String groupingName;
-
-        if (groupingString.contains(":")) {
-            String[] splitted = groupingString.split(":");
-            if (splitted.length != 2 || groupingString.contains("/")) {
-                throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
-            }
-            groupingPrefix = splitted[0];
-            groupingName = splitted[1];
-        } else {
-            groupingPrefix = module.getPrefix();
-            groupingName = groupingString;
-        }
-
-        Module dependentModule = findModuleFromContext(context, module, groupingPrefix, line);
-        return findGroupingDefinition(dependentModule.getGroupings(), groupingName);
-    }
-
     /**
      * Add nodes defined in target grouping to current context.
      *
@@ -1103,67 +774,21 @@ public final class YangParserImpl implements YangModelParser {
             prefix = parentQName.getPrefix();
         }
         SchemaPath parentPath = parent.getPath();
-
-        Set<DataSchemaNodeBuilder> newChildren = new HashSet<>();
-        for (DataSchemaNodeBuilder child : targetGrouping.getChildNodeBuilders()) {
-            if (child != null) {
-                DataSchemaNodeBuilder newChild = null;
-                if (child instanceof AnyXmlBuilder) {
-                    newChild = new AnyXmlBuilder((AnyXmlBuilder) child);
-                } else if (child instanceof ChoiceBuilder) {
-                    newChild = new ChoiceBuilder((ChoiceBuilder) child);
-                } else if (child instanceof ContainerSchemaNodeBuilder) {
-                    newChild = new ContainerSchemaNodeBuilder((ContainerSchemaNodeBuilder) child);
-                } else if (child instanceof LeafListSchemaNodeBuilder) {
-                    newChild = new LeafListSchemaNodeBuilder((LeafListSchemaNodeBuilder) child);
-                } else if (child instanceof LeafSchemaNodeBuilder) {
-                    newChild = new LeafSchemaNodeBuilder((LeafSchemaNodeBuilder) child);
-                } else if (child instanceof ListSchemaNodeBuilder) {
-                    newChild = new ListSchemaNodeBuilder((ListSchemaNodeBuilder) child);
-                }
-
-                if (newChild == null) {
-                    throw new YangParseException(usesNode.getModuleName(), usesNode.getLine(),
-                            "Unknown member of target grouping while resolving uses node.");
-                }
-
-                if (newChild instanceof GroupingMember) {
-                    ((GroupingMember) newChild).setAddedByUses(true);
-                }
-
-                newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName(), namespace, revision,
-                        prefix));
-                newChildren.add(newChild);
-            }
-        }
+        // child nodes
+        Set<DataSchemaNodeBuilder> newChildren = processUsesDataSchemaNode(usesNode,
+                targetGrouping.getChildNodeBuilders(), parentPath, namespace, revision, prefix);
         usesNode.getTargetChildren().addAll(newChildren);
-
-        Set<GroupingBuilder> newGroupings = new HashSet<>();
-        for (GroupingBuilder g : targetGrouping.getGroupingBuilders()) {
-            GroupingBuilder newGrouping = new GroupingBuilderImpl(g);
-            newGrouping.setAddedByUses(true);
-            newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName(), namespace,
-                    revision, prefix));
-            newGroupings.add(newGrouping);
-        }
+        // groupings
+        Set<GroupingBuilder> newGroupings = processUsesGroupings(targetGrouping.getGroupingBuilders(), parentPath,
+                namespace, revision, prefix);
         usesNode.getTargetGroupings().addAll(newGroupings);
-
-        Set<TypeDefinitionBuilder> newTypedefs = new HashSet<>();
-        for (TypeDefinitionBuilder td : targetGrouping.getTypeDefinitionBuilders()) {
-            TypeDefinitionBuilder newType = new TypeDefinitionBuilderImpl(td);
-            newType.setAddedByUses(true);
-            newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName(), namespace, revision, prefix));
-            newTypedefs.add(newType);
-        }
+        // typedefs
+        Set<TypeDefinitionBuilder> newTypedefs = processUsesTypedefs(targetGrouping.getTypeDefinitionBuilders(),
+                parentPath, namespace, revision, prefix);
         usesNode.getTargetTypedefs().addAll(newTypedefs);
-
-        List<UnknownSchemaNodeBuilder> newUnknownNodes = new ArrayList<>();
-        for (UnknownSchemaNodeBuilder un : targetGrouping.getUnknownNodeBuilders()) {
-            UnknownSchemaNodeBuilder newUn = new UnknownSchemaNodeBuilder(un);
-            newUn.setAddedByUses(true);
-            newUn.setPath(createSchemaPath(parentPath, un.getQName().getLocalName(), namespace, revision, prefix));
-            newUnknownNodes.add(newUn);
-        }
+        // unknown nodes
+        List<UnknownSchemaNodeBuilder> newUnknownNodes = processUsesUnknownNodes(
+                targetGrouping.getUnknownNodeBuilders(), parentPath, namespace, revision, prefix);
         usesNode.getTargetUnknownNodes().addAll(newUnknownNodes);
     }
 
@@ -1177,11 +802,39 @@ public final class YangParserImpl implements YangModelParser {
      */
     private void processUsesTarget(final ModuleBuilder module, final UsesNodeBuilder usesNode,
             final GroupingBuilder targetGrouping) {
+        DataNodeContainerBuilder parent = usesNode.getParent();
+        URI namespace = null;
+        Date revision = null;
+        String prefix = null;
+        if (parent instanceof ModuleBuilder) {
+            ModuleBuilder m = (ModuleBuilder) parent;
+            namespace = m.getNamespace();
+            revision = m.getRevision();
+            prefix = m.getPrefix();
+        } else {
+            QName parentQName = parent.getQName();
+            namespace = parentQName.getNamespace();
+            revision = parentQName.getRevision();
+            prefix = parentQName.getPrefix();
+        }
+        SchemaPath parentPath = parent.getPath();
+
         for (UsesNodeBuilder unb : targetGrouping.getUses()) {
-            usesNode.getTargetChildren().addAll(unb.getTargetChildren());
-            usesNode.getTargetGroupings().addAll(unb.getTargetGroupings());
-            usesNode.getTargetTypedefs().addAll(unb.getTargetTypedefs());
-            usesNode.getTargetUnknownNodes().addAll(unb.getTargetUnknownNodes());
+            Set<DataSchemaNodeBuilder> newChildren = processUsesDataSchemaNode(usesNode, unb.getTargetChildren(),
+                    parentPath, namespace, revision, prefix);
+            usesNode.getTargetChildren().addAll(newChildren);
+
+            Set<GroupingBuilder> newGroupings = processUsesGroupings(unb.getTargetGroupings(), parentPath, namespace,
+                    revision, prefix);
+            usesNode.getTargetGroupings().addAll(newGroupings);
+
+            Set<TypeDefinitionBuilder> newTypedefs = processUsesTypedefs(unb.getTargetTypedefs(), parentPath,
+                    namespace, revision, prefix);
+            usesNode.getTargetTypedefs().addAll(newTypedefs);
+
+            List<UnknownSchemaNodeBuilder> newUnknownNodes = processUsesUnknownNodes(unb.getTargetUnknownNodes(),
+                    parentPath, namespace, revision, prefix);
+            usesNode.getTargetUnknownNodes().addAll(newUnknownNodes);
         }
     }
 
@@ -1193,10 +846,10 @@ public final class YangParserImpl implements YangModelParser {
         Date revision = null;
         String prefix = null;
         if (parent instanceof ModuleBuilder) {
-            ModuleBuilder module = (ModuleBuilder) parent;
-            namespace = module.getNamespace();
-            revision = module.getRevision();
-            prefix = module.getPrefix();
+            ModuleBuilder m = (ModuleBuilder) parent;
+            namespace = m.getNamespace();
+            revision = m.getRevision();
+            prefix = m.getPrefix();
         } else {
             QName parentQName = parent.getQName();
             namespace = parentQName.getNamespace();
@@ -1209,30 +862,30 @@ public final class YangParserImpl implements YangModelParser {
         for (DataSchemaNode child : targetGrouping.getChildNodes()) {
             if (child != null) {
                 DataSchemaNodeBuilder newChild = null;
+                QName newQName = new QName(namespace, revision, prefix, child.getQName().getLocalName());
                 if (child instanceof AnyXmlSchemaNode) {
-                    newChild = createAnyXml((AnyXmlSchemaNode) child, moduleName, line);
+                    newChild = createAnyXml((AnyXmlSchemaNode) child, newQName, moduleName, line);
                 } else if (child instanceof ChoiceNode) {
-                    newChild = createChoice((ChoiceNode) child, moduleName, line);
+                    newChild = createChoice((ChoiceNode) child, newQName, moduleName, line);
                 } else if (child instanceof ContainerSchemaNode) {
-                    newChild = createContainer((ContainerSchemaNode) child, moduleName, line);
+                    newChild = createContainer((ContainerSchemaNode) child, newQName, moduleName, line);
                 } else if (child instanceof LeafListSchemaNode) {
-                    newChild = createLeafList((LeafListSchemaNode) child, moduleName, line);
+                    newChild = createLeafList((LeafListSchemaNode) child, newQName, moduleName, line);
                 } else if (child instanceof LeafSchemaNode) {
-                    newChild = createLeafBuilder((LeafSchemaNode) child, moduleName, line);
+                    newChild = createLeafBuilder((LeafSchemaNode) child, newQName, moduleName, line);
                 } else if (child instanceof ListSchemaNode) {
-                    newChild = createList((ListSchemaNode) child, moduleName, line);
+                    newChild = createList((ListSchemaNode) child, newQName, moduleName, line);
                 }
 
                 if (newChild == null) {
                     throw new YangParseException(moduleName, line,
                             "Unknown member of target grouping while resolving uses node.");
                 }
-
                 if (newChild instanceof GroupingMember) {
                     ((GroupingMember) newChild).setAddedByUses(true);
                 }
-                newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName(), namespace, revision,
-                        prefix));
+
+                newChild.setPath(createSchemaPath(parentPath, newQName));
                 newChildren.add(newChild);
             }
         }
@@ -1240,53 +893,35 @@ public final class YangParserImpl implements YangModelParser {
 
         final Set<GroupingBuilder> newGroupings = new HashSet<>();
         for (GroupingDefinition g : targetGrouping.getGroupings()) {
-            GroupingBuilder newGrouping = createGrouping(g, moduleName, line);
+            QName newQName = new QName(namespace, revision, prefix, g.getQName().getLocalName());
+            GroupingBuilder newGrouping = createGrouping(g, newQName, moduleName, line);
             newGrouping.setAddedByUses(true);
-            newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName(), namespace,
-                    revision, prefix));
+            newGrouping.setPath(createSchemaPath(parentPath, newQName));
             newGroupings.add(newGrouping);
         }
         usesNode.getTargetGroupings().addAll(newGroupings);
 
         final Set<TypeDefinitionBuilder> newTypedefs = new HashSet<>();
         for (TypeDefinition<?> td : targetGrouping.getTypeDefinitions()) {
-            TypeDefinitionBuilder newType = createTypedef((ExtendedType) td, moduleName, line);
+            QName newQName = new QName(namespace, revision, prefix, td.getQName().getLocalName());
+            TypeDefinitionBuilder newType = createTypedef((ExtendedType) td, newQName, moduleName, line);
             newType.setAddedByUses(true);
-            newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName(), namespace, revision, prefix));
+            newType.setPath(createSchemaPath(parentPath, newQName));
             newTypedefs.add(newType);
         }
         usesNode.getTargetTypedefs().addAll(newTypedefs);
 
         final List<UnknownSchemaNodeBuilder> newUnknownNodes = new ArrayList<>();
         for (UnknownSchemaNode un : targetGrouping.getUnknownSchemaNodes()) {
-            UnknownSchemaNodeBuilder newNode = createUnknownSchemaNode(un, moduleName, line);
+            QName newQName = new QName(namespace, revision, prefix, un.getQName().getLocalName());
+            UnknownSchemaNodeBuilder newNode = createUnknownSchemaNode(un, newQName, moduleName, line);
             newNode.setAddedByUses(true);
-            newNode.setPath(createSchemaPath(parentPath, un.getQName().getLocalName(), namespace, revision, prefix));
+            newNode.setPath(createSchemaPath(parentPath, newQName));
             newUnknownNodes.add(newNode);
         }
         usesNode.getTargetUnknownNodes().addAll(newUnknownNodes);
     }
 
-    private QName findFullQName(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
-            final IdentityrefTypeBuilder idref) {
-        QName result = null;
-        String baseString = idref.getBaseString();
-        if (baseString.contains(":")) {
-            String[] splittedBase = baseString.split(":");
-            if (splittedBase.length > 2) {
-                throw new YangParseException(module.getName(), idref.getLine(), "Failed to parse identityref base: "
-                        + baseString);
-            }
-            String prefix = splittedBase[0];
-            String name = splittedBase[1];
-            ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix, idref.getLine());
-            result = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), prefix, name);
-        } else {
-            result = new QName(module.getNamespace(), module.getRevision(), module.getPrefix(), baseString);
-        }
-        return result;
-    }
-
     private void resolveUnknownNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) {
             QName nodeType = usnb.getNodeType();
@@ -1333,6 +968,12 @@ public final class YangParserImpl implements YangModelParser {
         }
     }
 
+    /**
+     * Traverse through modules and resolve their deviation statements.
+     *
+     * @param modules
+     *            all loaded modules
+     */
     private void resolveDeviations(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()) {
@@ -1342,6 +983,14 @@ public final class YangParserImpl implements YangModelParser {
         }
     }
 
+    /**
+     * Traverse through module and resolve its deviation statements.
+     *
+     * @param modules
+     *            all loaded modules
+     * @param module
+     *            module in which resolve deviations
+     */
     private void resolveDeviation(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         for (DeviationBuilder dev : module.getDeviations()) {
             int line = dev.getLine();
@@ -1358,6 +1007,15 @@ public final class YangParserImpl implements YangModelParser {
         }
     }
 
+    /**
+     * 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()) {
@@ -1368,6 +1026,17 @@ public final class YangParserImpl implements YangModelParser {
         }
     }
 
+    /**
+     * 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.getDeviations()) {
index 99d3012f2e510e6c926ae72242f44e29a949717a..cd382935825ea53864318fe52c333ce7772e9801 100644 (file)
@@ -264,32 +264,6 @@ public final class ParserListenerUtils {
         return new SchemaPath(path, true);
     }
 
-    /**
-     * Create SchemaPath from given string.
-     *
-     * @param augmentPath
-     *            string representation of path
-     * @return SchemaPath object
-     */
-    public static SchemaPath parseAugmentPath(final String augmentPath) {
-        final boolean absolute = augmentPath.startsWith("/");
-        final String[] splittedPath = augmentPath.split("/");
-        List<QName> path = new ArrayList<QName>();
-        QName name;
-        for (String pathElement : splittedPath) {
-            if (pathElement.length() > 0) {
-                String[] splittedElement = pathElement.split(":");
-                if (splittedElement.length == 1) {
-                    name = new QName(null, null, null, splittedElement[0]);
-                } else {
-                    name = new QName(null, null, splittedElement[0], splittedElement[1]);
-                }
-                path.add(name);
-            }
-        }
-        return new SchemaPath(path, absolute);
-    }
-
     /**
      * Create java.util.List of QName objects from given key definition as
      * string.
index 59f729874ce4ddf59580ed886441446192589c1e..35a60186de06720de1641e42892aa1010e7b168f 100644 (file)
@@ -9,7 +9,9 @@ package org.opendaylight.yangtools.yang.parser.util;
 
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -62,18 +64,8 @@ import org.opendaylight.yangtools.yang.model.util.EnumerationType;
 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
 import org.opendaylight.yangtools.yang.model.util.IdentityrefType;
 import org.opendaylight.yangtools.yang.model.util.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.util.Int16;
-import org.opendaylight.yangtools.yang.model.util.Int32;
-import org.opendaylight.yangtools.yang.model.util.Int64;
-import org.opendaylight.yangtools.yang.model.util.Int8;
 import org.opendaylight.yangtools.yang.model.util.Leafref;
-import org.opendaylight.yangtools.yang.model.util.StringType;
-import org.opendaylight.yangtools.yang.model.util.Uint16;
-import org.opendaylight.yangtools.yang.model.util.Uint32;
-import org.opendaylight.yangtools.yang.model.util.Uint64;
-import org.opendaylight.yangtools.yang.model.util.Uint8;
 import org.opendaylight.yangtools.yang.model.util.UnionType;
-import org.opendaylight.yangtools.yang.model.util.UnknownType;
 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
@@ -104,7 +96,6 @@ import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder.NotificationDefinitionImpl;
 import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
-import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 
 public final class ParserUtils {
@@ -113,23 +104,16 @@ public final class ParserUtils {
     }
 
     /**
-     * Create new SchemaPath from given path and name.
-     *
-     * Append new qname to schema path created from name argument.
+     * Create new SchemaPath from given path and qname.
      *
      * @param schemaPath
-     * @param name
+     * @param qname
      * @return
      */
-    public static SchemaPath createSchemaPath(SchemaPath schemaPath, String name, URI namespace, Date revision, String prefix) {
-        List<QName> path = new ArrayList<QName>();
-        if(schemaPath != null) {
-            path.addAll(schemaPath.getPath());
-        }
-        QName newQName = new QName(namespace, revision, prefix, name);
-        path.add(newQName);
-        boolean abs = schemaPath == null ? true : schemaPath.isAbsolute();
-        return new SchemaPath(path, abs);
+    public static SchemaPath createSchemaPath(SchemaPath schemaPath, QName... qname) {
+        List<QName> path = new ArrayList<>(schemaPath.getPath());
+        path.addAll(Arrays.asList(qname));
+        return new SchemaPath(path, schemaPath.isAbsolute());
     }
 
     /**
@@ -276,53 +260,102 @@ public final class ParserUtils {
         return null;
     }
 
-    /**
-     * Search types for type with given name.
-     *
-     * @param types
-     *            types to search
-     * @param name
-     *            name of type
-     * @return type with given name if present in collection, null otherwise
-     */
-    public static TypeDefinitionBuilder findTypedefBuilderByName(Set<TypeDefinitionBuilder> types, String name) {
-        for (TypeDefinitionBuilder td : types) {
-            if (td.getQName().getLocalName().equals(name)) {
-                return td;
+    public static Set<DataSchemaNodeBuilder> processUsesDataSchemaNode(UsesNodeBuilder usesNode,
+            Set<DataSchemaNodeBuilder> children, SchemaPath parentPath, URI namespace, Date revision, String prefix) {
+        Set<DataSchemaNodeBuilder> newChildren = new HashSet<>();
+        for (DataSchemaNodeBuilder child : children) {
+            if (child != null) {
+                DataSchemaNodeBuilder newChild = null;
+                QName qname = new QName(namespace, revision, prefix, child.getQName().getLocalName());
+                if (child instanceof AnyXmlBuilder) {
+                    newChild = new AnyXmlBuilder((AnyXmlBuilder) child, qname);
+                } else if (child instanceof ChoiceBuilder) {
+                    newChild = new ChoiceBuilder((ChoiceBuilder) child, qname);
+                } else if (child instanceof ContainerSchemaNodeBuilder) {
+                    newChild = new ContainerSchemaNodeBuilder((ContainerSchemaNodeBuilder) child, qname);
+                } else if (child instanceof LeafListSchemaNodeBuilder) {
+                    newChild = new LeafListSchemaNodeBuilder((LeafListSchemaNodeBuilder) child, qname);
+                } else if (child instanceof LeafSchemaNodeBuilder) {
+                    newChild = new LeafSchemaNodeBuilder((LeafSchemaNodeBuilder) child, qname);
+                } else if (child instanceof ListSchemaNodeBuilder) {
+                    newChild = new ListSchemaNodeBuilder((ListSchemaNodeBuilder) child, qname);
+                }
+
+                if (newChild == null) {
+                    throw new YangParseException(usesNode.getModuleName(), usesNode.getLine(),
+                            "Unknown member of target grouping while resolving uses node.");
+                }
+                if (newChild instanceof GroupingMember) {
+                    ((GroupingMember) newChild).setAddedByUses(true);
+                }
+
+                correctNodePath(newChild, parentPath);
+                newChildren.add(newChild);
             }
         }
-        return null;
+        return newChildren;
     }
 
     /**
-     * Find type by name.
+     * Traverse given groupings and create new collection of groupings with
+     * schema path created based on current parent path.
      *
-     * @param types
-     *            collection of types
-     * @param typeName
-     *            type name
-     * @return type with given name if it is present in collection, null
-     *         otherwise
+     * @param groupings
+     * @param parentPath
+     * @param namespace
+     * @param revision
+     * @param prefix
+     * @return collection of new groupings with corrected path
      */
-    public static TypeDefinition<?> findTypeByName(Set<TypeDefinition<?>> types, String typeName) {
-        for (TypeDefinition<?> type : types) {
-            if (type.getQName().getLocalName().equals(typeName)) {
-                return type;
-            }
+    public static Set<GroupingBuilder> processUsesGroupings(Set<GroupingBuilder> groupings, SchemaPath parentPath,
+            URI namespace, Date revision, String prefix) {
+        Set<GroupingBuilder> newGroupings = new HashSet<>();
+        for (GroupingBuilder g : groupings) {
+            QName qname = new QName(namespace, revision, prefix, g.getQName().getLocalName());
+            GroupingBuilder newGrouping = new GroupingBuilderImpl(g, qname);
+            newGrouping.setAddedByUses(true);
+            correctNodePath(newGrouping, parentPath);
+            newGroupings.add(newGrouping);
         }
-        return null;
+        return newGroupings;
+    }
+
+    public static Set<TypeDefinitionBuilder> processUsesTypedefs(Set<TypeDefinitionBuilder> typedefs,
+            SchemaPath parentPath, URI namespace, Date revision, String prefix) {
+        Set<TypeDefinitionBuilder> newTypedefs = new HashSet<>();
+        for (TypeDefinitionBuilder td : typedefs) {
+            QName qname = new QName(namespace, revision, prefix, td.getQName().getLocalName());
+            TypeDefinitionBuilder newType = new TypeDefinitionBuilderImpl(td, qname);
+            newType.setAddedByUses(true);
+            correctNodePath(newType, parentPath);
+            newTypedefs.add(newType);
+        }
+        return newTypedefs;
+    }
+
+    public static List<UnknownSchemaNodeBuilder> processUsesUnknownNodes(List<UnknownSchemaNodeBuilder> unknownNodes,
+            SchemaPath parentPath, URI namespace, Date revision, String prefix) {
+        List<UnknownSchemaNodeBuilder> newUnknownNodes = new ArrayList<>();
+        for (UnknownSchemaNodeBuilder un : unknownNodes) {
+            QName qname = new QName(namespace, revision, prefix, un.getQName().getLocalName());
+            UnknownSchemaNodeBuilder newUn = new UnknownSchemaNodeBuilder(un, qname);
+            newUn.setAddedByUses(true);
+            correctNodePath(newUn, parentPath);
+            newUnknownNodes.add(newUn);
+        }
+        return newUnknownNodes;
     }
 
     /**
-     * Parse uses path.
+     * Parse XPath string.
      *
-     * @param usesPath
+     * @param xpathString
      *            as String
      * @return SchemaPath from given String
      */
-    public static SchemaPath parseUsesPath(final String usesPath) {
-        final boolean absolute = usesPath.startsWith("/");
-        final String[] splittedPath = usesPath.split("/");
+    public static SchemaPath parseXPathString(final String xpathString) {
+        final boolean absolute = xpathString.startsWith("/");
+        final String[] splittedPath = xpathString.split("/");
         final List<QName> path = new ArrayList<QName>();
         QName name;
         for (String pathElement : splittedPath) {
@@ -339,44 +372,6 @@ public final class ParserUtils {
         return new SchemaPath(path, absolute);
     }
 
-    /**
-     * Get node from collection of refined nodes based on qname.
-     *
-     * @param nodeQName
-     *            qname of node
-     * @param refineNodes
-     *            collections of refined nodes
-     * @return node with given qname if present, null otherwise
-     */
-    public static SchemaNodeBuilder getRefined(QName nodeQName, List<SchemaNodeBuilder> refineNodes) {
-        for (SchemaNodeBuilder rn : refineNodes) {
-            if (rn.getQName().equals(nodeQName)) {
-                return rn;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Pull restriction from type and add them to constraints.
-     *
-     * @param type
-     * @param constraints
-     */
-    public static void mergeConstraints(final TypeDefinition<?> type, final TypeConstraints constraints) {
-        if (type instanceof DecimalTypeDefinition) {
-            constraints.addRanges(((DecimalTypeDefinition) type).getRangeStatements());
-            constraints.addFractionDigits(((DecimalTypeDefinition) type).getFractionDigits());
-        } else if (type instanceof IntegerTypeDefinition) {
-            constraints.addRanges(((IntegerTypeDefinition) type).getRangeStatements());
-        } else if (type instanceof StringTypeDefinition) {
-            constraints.addPatterns(((StringTypeDefinition) type).getPatterns());
-            constraints.addLengths(((StringTypeDefinition) type).getLengthStatements());
-        } else if (type instanceof BinaryTypeDefinition) {
-            constraints.addLengths(((BinaryTypeDefinition) type).getLengthConstraints());
-        }
-    }
-
     /**
      * Add all augment's child nodes to given target.
      *
@@ -394,7 +389,7 @@ public final class ParserUtils {
                     ((GroupingMember) builder).setAddedByUses(true);
                 }
             }
-            correctAugmentChildPath(builder, target.getPath());
+            correctNodePath(builder, target.getPath());
             target.addChildNode(builder);
         }
     }
@@ -416,36 +411,36 @@ public final class ParserUtils {
                     ((GroupingMember) builder).setAddedByUses(true);
                 }
             }
-            correctAugmentChildPath(builder, target.getPath());
+            correctNodePath(builder, target.getPath());
             target.addCase(builder);
         }
     }
 
-    private static void correctAugmentChildPath(final DataSchemaNodeBuilder childNode, final SchemaPath parentSchemaPath) {
+    private static void correctNodePath(final SchemaNodeBuilder node, final SchemaPath parentSchemaPath) {
         // set correct path
         List<QName> targetNodePath = new ArrayList<QName>(parentSchemaPath.getPath());
-        targetNodePath.add(childNode.getQName());
-        childNode.setPath(new SchemaPath(targetNodePath, true));
+        targetNodePath.add(node.getQName());
+        node.setPath(new SchemaPath(targetNodePath, true));
 
         // set correct path for all child nodes
-        if (childNode instanceof DataNodeContainerBuilder) {
-            DataNodeContainerBuilder dataNodeContainer = (DataNodeContainerBuilder) childNode;
+        if (node instanceof DataNodeContainerBuilder) {
+            DataNodeContainerBuilder dataNodeContainer = (DataNodeContainerBuilder) node;
             for (DataSchemaNodeBuilder child : dataNodeContainer.getChildNodeBuilders()) {
-                correctAugmentChildPath(child, childNode.getPath());
+                correctNodePath(child, node.getPath());
             }
         }
 
         // set correct path for all cases
-        if (childNode instanceof ChoiceBuilder) {
-            ChoiceBuilder choiceBuilder = (ChoiceBuilder) childNode;
+        if (node instanceof ChoiceBuilder) {
+            ChoiceBuilder choiceBuilder = (ChoiceBuilder) node;
             for (ChoiceCaseBuilder choiceCaseBuilder : choiceBuilder.getCases()) {
-                correctAugmentChildPath(choiceCaseBuilder, childNode.getPath());
+                correctNodePath(choiceCaseBuilder, node.getPath());
             }
         }
 
         // if node can contains type, correct path for this type too
-        if (childNode instanceof TypeAwareBuilder) {
-            TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) childNode;
+        if (node instanceof TypeAwareBuilder) {
+            TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) node;
             correctTypeAwareNodePath(nodeBuilder, parentSchemaPath);
         }
     }
@@ -505,7 +500,7 @@ public final class ParserUtils {
                 return;
             }
 
-            SchemaPath newSchemaPath = createNewSchemaPath(nodeBuilderTypedef.getPath(), nodeBuilderQName,
+            SchemaPath newSchemaPath = createSchemaPath(nodeBuilderTypedef.getPath(), nodeBuilderQName,
                     nodeBuilderTypedef.getQName());
             nodeBuilderTypedef.setPath(newSchemaPath);
         }
@@ -540,7 +535,7 @@ public final class ParserUtils {
 
         if (nodeType != null) {
             QName nodeTypeQName = nodeType.getQName();
-            SchemaPath newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, nodeTypeQName);
+            SchemaPath newSchemaPath = createSchemaPath(parentSchemaPath, nodeQName, nodeTypeQName);
 
             if (nodeType instanceof BinaryTypeDefinition) {
                 BinaryTypeDefinition binType = (BinaryTypeDefinition) nodeType;
@@ -578,11 +573,12 @@ public final class ParserUtils {
                 return new InstanceIdentifier(newSchemaPath, instIdType.getPathStatement(),
                         instIdType.requireInstance());
             } else if (nodeType instanceof StringTypeDefinition) {
-                result = createNewStringType(parentSchemaPath, nodeQName, (StringTypeDefinition) nodeType);
+                result = TypeUtils.createNewStringType(parentSchemaPath, nodeQName, (StringTypeDefinition) nodeType);
             } else if (nodeType instanceof IntegerTypeDefinition) {
-                result = createNewIntType(parentSchemaPath, nodeQName, (IntegerTypeDefinition) nodeType);
+                result = TypeUtils.createNewIntType(parentSchemaPath, nodeQName, (IntegerTypeDefinition) nodeType);
             } else if (nodeType instanceof UnsignedIntegerTypeDefinition) {
-                result = createNewUintType(parentSchemaPath, nodeQName, (UnsignedIntegerTypeDefinition) nodeType);
+                result = TypeUtils.createNewUintType(parentSchemaPath, nodeQName,
+                        (UnsignedIntegerTypeDefinition) nodeType);
             } else if (nodeType instanceof LeafrefTypeDefinition) {
                 result = new Leafref(newSchemaPath, ((LeafrefTypeDefinition) nodeType).getPathStatement());
             } else if (nodeType instanceof UnionTypeDefinition) {
@@ -590,104 +586,26 @@ public final class ParserUtils {
                 return new UnionType(newSchemaPath, unionType.getTypes());
             } else if (nodeType instanceof ExtendedType) {
                 ExtendedType extType = (ExtendedType) nodeType;
-                result = createNewExtendedType(extType, newSchemaPath);
+                result = TypeUtils.createNewExtendedType(extType, newSchemaPath);
             }
         }
         return result;
     }
 
-    /**
-     * Create new ExtendedType based on given type and with schema path.
-     *
-     * @param newPath
-     *            schema path for new type
-     * @param oldType
-     *            type based
-     * @return
-     */
-    private static ExtendedType createNewExtendedType(final ExtendedType oldType, final SchemaPath newPath) {
-        QName qname = oldType.getQName();
-        TypeDefinition<?> baseType = oldType.getBaseType();
-        String desc = oldType.getDescription();
-        String ref = oldType.getReference();
-        ExtendedType.Builder builder = new ExtendedType.Builder(qname, baseType, desc, ref, newPath);
-        builder.status(oldType.getStatus());
-        builder.lengths(oldType.getLengths());
-        builder.patterns(oldType.getPatterns());
-        builder.ranges(oldType.getRanges());
-        builder.fractionDigits(oldType.getFractionDigits());
-        builder.unknownSchemaNodes(oldType.getUnknownSchemaNodes());
-        return builder.build();
-    }
-
-    private static StringTypeDefinition createNewStringType(final SchemaPath schemaPath, final QName nodeQName,
-            final StringTypeDefinition nodeType) {
-        final List<QName> path = schemaPath.getPath();
-        final List<QName> newPath = new ArrayList<QName>(path);
-        newPath.add(nodeQName);
-        newPath.add(nodeType.getQName());
-        final SchemaPath newSchemaPath = new SchemaPath(newPath, schemaPath.isAbsolute());
-        return new StringType(newSchemaPath);
-    }
-
-    private static IntegerTypeDefinition createNewIntType(final SchemaPath schemaPath, final QName nodeQName,
-            final IntegerTypeDefinition type) {
-        final QName typeQName = type.getQName();
-        final SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, typeQName);
-        final String localName = typeQName.getLocalName();
-
-        if ("int8".equals(localName)) {
-            return new Int8(newSchemaPath);
-        } else if ("int16".equals(localName)) {
-            return new Int16(newSchemaPath);
-        } else if ("int32".equals(localName)) {
-            return new Int32(newSchemaPath);
-        } else if ("int64".equals(localName)) {
-            return new Int64(newSchemaPath);
-        } else {
-            return null;
-        }
-    }
-
-    private static UnsignedIntegerTypeDefinition createNewUintType(final SchemaPath schemaPath, final QName nodeQName,
-            final UnsignedIntegerTypeDefinition type) {
-        final QName typeQName = type.getQName();
-        final SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, typeQName);
-        final String localName = typeQName.getLocalName();
-
-        if ("uint8".equals(localName)) {
-            return new Uint8(newSchemaPath);
-        } else if ("uint16".equals(localName)) {
-            return new Uint16(newSchemaPath);
-        } else if ("uint32".equals(localName)) {
-            return new Uint32(newSchemaPath);
-        } else if ("uint64".equals(localName)) {
-            return new Uint64(newSchemaPath);
-        } else {
-            return null;
-        }
-    }
-
-    private static SchemaPath createNewSchemaPath(final SchemaPath schemaPath, final QName currentQName,
-            final QName qname) {
-        List<QName> newPath = new ArrayList<QName>(schemaPath.getPath());
-        newPath.add(currentQName);
-        newPath.add(qname);
-        return new SchemaPath(newPath, schemaPath.isAbsolute());
-    }
-
     /**
      * Create LeafSchemaNodeBuilder from given LeafSchemaNode.
      *
      * @param leaf
      *            leaf from which to create builder
+     * @param qname
+     * @param moduleName
+     *            current module name
      * @param line
      *            line in module
-     * @return builder object from leaf
+     * @return leaf builder based on given leaf node
      */
-    public static LeafSchemaNodeBuilder createLeafBuilder(LeafSchemaNode leaf, String moduleName, int line) {
-        final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(moduleName, line, leaf.getQName(),
-                leaf.getPath());
+    public static LeafSchemaNodeBuilder createLeafBuilder(LeafSchemaNode leaf, QName qname, String moduleName, int line) {
+        final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(moduleName, line, qname, leaf.getPath());
         convertDataSchemaNode(leaf, builder);
         builder.setConfiguration(leaf.isConfiguration());
         final TypeDefinition<?> type = leaf.getType();
@@ -699,9 +617,21 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, String moduleName, int line) {
-        final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(moduleName, line,
-                container.getQName(), container.getPath());
+    /**
+     * Create ContainerSchemaNodeBuilder from given ContainerSchemaNode.
+     *
+     * @param container
+     * @param qname
+     * @param moduleName
+     *            current module name
+     * @param line
+     *            current line in module
+     * @return container builder based on given container node
+     */
+    public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, QName qname,
+            String moduleName, int line) {
+        final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(moduleName, line, qname,
+                container.getPath());
         convertDataSchemaNode(container, builder);
         builder.setConfiguration(container.isConfiguration());
         builder.setUnknownNodes(container.getUnknownSchemaNodes());
@@ -714,8 +644,19 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static ListSchemaNodeBuilder createList(ListSchemaNode list, String moduleName, int line) {
-        ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(moduleName, line, list.getQName(), list.getPath());
+    /**
+     * Create ListSchemaNodeBuilder from given ListSchemaNode.
+     *
+     * @param list
+     * @param qname
+     * @param moduleName
+     *            current module name
+     * @param line
+     *            current line in module
+     * @return list builder based on given list node
+     */
+    public static ListSchemaNodeBuilder createList(ListSchemaNode list, QName qname, String moduleName, int line) {
+        ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(moduleName, line, qname, list.getPath());
         convertDataSchemaNode(list, builder);
         builder.setConfiguration(list.isConfiguration());
         builder.setUnknownNodes(list.getUnknownSchemaNodes());
@@ -728,8 +669,20 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, String moduleName, int line) {
-        final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(moduleName, line, leafList.getQName(),
+    /**
+     * Create LeafListSchemaNodeBuilder from given LeafListSchemaNode.
+     *
+     * @param leafList
+     * @param qname
+     * @param moduleName
+     *            current module name
+     * @param line
+     *            current line in module
+     * @return leaf-list builder based on given leaf-list node
+     */
+    public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, QName qname, String moduleName,
+            int line) {
+        final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(moduleName, line, qname,
                 leafList.getPath());
         convertDataSchemaNode(leafList, builder);
         builder.setConfiguration(leafList.isConfiguration());
@@ -739,8 +692,19 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static ChoiceBuilder createChoice(ChoiceNode choice, String moduleName, int line) {
-        final ChoiceBuilder builder = new ChoiceBuilder(moduleName, line, choice.getQName());
+    /**
+     * Create ChoiceBuilder from given ChoiceNode.
+     *
+     * @param choice
+     * @param qname
+     * @param moduleName
+     *            current module name
+     * @param line
+     *            current line in module
+     * @return choice builder based on given choice node
+     */
+    public static ChoiceBuilder createChoice(ChoiceNode choice, QName qname, String moduleName, int line) {
+        final ChoiceBuilder builder = new ChoiceBuilder(moduleName, line, qname);
         convertDataSchemaNode(choice, builder);
         builder.setConfiguration(choice.isConfiguration());
         builder.setCases(choice.getCases());
@@ -749,16 +713,38 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, String moduleName, int line) {
-        final AnyXmlBuilder builder = new AnyXmlBuilder(moduleName, line, anyxml.getQName(), anyxml.getPath());
+    /**
+     * Create AnyXmlBuilder from given AnyXmlSchemaNode.
+     *
+     * @param anyxml
+     * @param qname
+     * @param moduleName
+     *            current module name
+     * @param line
+     *            current line in module
+     * @return anyxml builder based on given anyxml node
+     */
+    public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, QName qname, String moduleName, int line) {
+        final AnyXmlBuilder builder = new AnyXmlBuilder(moduleName, line, qname, anyxml.getPath());
         convertDataSchemaNode(anyxml, builder);
         builder.setConfiguration(anyxml.isConfiguration());
         builder.setUnknownNodes(anyxml.getUnknownSchemaNodes());
         return builder;
     }
 
-    public static GroupingBuilder createGrouping(GroupingDefinition grouping, String moduleName, int line) {
-        final GroupingBuilderImpl builder = new GroupingBuilderImpl(moduleName, line, grouping.getQName());
+    /**
+     * Create GroupingBuilder from given GroupingDefinition.
+     *
+     * @param grouping
+     * @param qname
+     * @param moduleName
+     *            current module name
+     * @param line
+     *            current line in module
+     * @return grouping builder based on given grouping node
+     */
+    public static GroupingBuilder createGrouping(GroupingDefinition grouping, QName qname, String moduleName, int line) {
+        final GroupingBuilderImpl builder = new GroupingBuilderImpl(moduleName, line, qname);
         builder.setPath(grouping.getPath());
         builder.setChildNodes(grouping.getChildNodes());
         builder.setGroupings(grouping.getGroupings());
@@ -771,8 +757,19 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static TypeDefinitionBuilder createTypedef(ExtendedType typedef, String moduleName, int line) {
-        final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(moduleName, line, typedef.getQName());
+    /**
+     * Create TypeDefinitionBuilder from given ExtendedType.
+     *
+     * @param typedef
+     * @param qname
+     * @param moduleName
+     *            current module name
+     * @param line
+     *            current line in module
+     * @return typedef builder based on given typedef node
+     */
+    public static TypeDefinitionBuilder createTypedef(ExtendedType typedef, QName qname, String moduleName, int line) {
+        final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(moduleName, line, qname);
         builder.setPath(typedef.getPath());
         builder.setDefaultValue(typedef.getDefaultValue());
         builder.setUnits(typedef.getUnits());
@@ -790,9 +787,20 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode unknownNode, String moduleName,
-            int line) {
-        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(moduleName, line, unknownNode.getQName());
+    /**
+     * Create UnknownSchemaNodeBuilder from given UnknownSchemaNode.
+     *
+     * @param unknownNode
+     * @param qname
+     * @param moduleName
+     *            current module name
+     * @param line
+     *            current line in module
+     * @return unknown node builder based on given unknown node
+     */
+    public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode unknownNode, QName qname,
+            String moduleName, int line) {
+        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(moduleName, line, qname);
         builder.setPath(unknownNode.getPath());
         builder.setUnknownNodes(unknownNode.getUnknownSchemaNodes());
         builder.setDescription(unknownNode.getDescription());
@@ -997,222 +1005,62 @@ public final class ParserUtils {
     }
 
     /**
-     * Create new type builder based on old type with new base type.
-     *
-     * @param newBaseType
-     *            new base type builder
-     * @param oldExtendedType
-     *            old type
-     * @param modules
-     *            all loaded modules
-     * @param module
-     *            current module
-     * @param line
-     *            current line in module
-     * @return new type builder based on old type with new base type
-     */
-    public static TypeDefinitionBuilder extendedTypeWithNewBaseTypeBuilder(final TypeDefinitionBuilder newBaseType,
-            final ExtendedType oldExtendedType, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder module, final int line) {
-        final TypeConstraints tc = new TypeConstraints(module.getName(), line);
-        tc.addFractionDigits(oldExtendedType.getFractionDigits());
-        tc.addLengths(oldExtendedType.getLengths());
-        tc.addPatterns(oldExtendedType.getPatterns());
-        tc.addRanges(oldExtendedType.getRanges());
-
-        final TypeConstraints constraints = findConstraintsFromTypeBuilder(newBaseType, tc, modules, module, null);
-        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(module.getModuleName(), line,
-                oldExtendedType.getQName());
-        newType.setTypedef(newBaseType);
-        newType.setPath(oldExtendedType.getPath());
-        newType.setDescription(oldExtendedType.getDescription());
-        newType.setReference(oldExtendedType.getReference());
-        newType.setStatus(oldExtendedType.getStatus());
-        newType.setLengths(constraints.getLength());
-        newType.setPatterns(constraints.getPatterns());
-        newType.setRanges(constraints.getRange());
-        newType.setFractionDigits(constraints.getFractionDigits());
-        newType.setUnits(oldExtendedType.getUnits());
-        newType.setDefaultValue(oldExtendedType.getDefaultValue());
-        newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes());
-        return newType;
-    }
-
-    /**
-     * Create new type builder based on old type with new base type.
+     * Search given modules for grouping by name defined in uses node.
      *
-     * @param newBaseType
-     *            new base type
-     * @param oldExtendedType
-     *            old type
+     * @param usesBuilder
+     *            builder of uses statement
      * @param modules
      *            all loaded modules
      * @param module
      *            current module
-     * @param line
-     *            current line in module
-     * @return new type builder based on old type with new base type
+     * @return grouping with given name if found, null otherwise
      */
-    public static TypeDefinitionBuilder extendedTypeWithNewBaseType(final TypeDefinition<?> newBaseType,
-            final ExtendedType oldExtendedType, final ModuleBuilder module, final int line) {
-        final TypeConstraints tc = new TypeConstraints(module.getName(), line);
-
-        final TypeConstraints constraints = findConstraintsFromTypeDefinition(newBaseType, tc);
-        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(module.getModuleName(), line,
-                oldExtendedType.getQName());
-        newType.setType(newBaseType);
-        newType.setPath(oldExtendedType.getPath());
-        newType.setDescription(oldExtendedType.getDescription());
-        newType.setReference(oldExtendedType.getReference());
-        newType.setStatus(oldExtendedType.getStatus());
-        newType.setLengths(constraints.getLength());
-        newType.setPatterns(constraints.getPatterns());
-        newType.setRanges(constraints.getRange());
-        newType.setFractionDigits(constraints.getFractionDigits());
-        newType.setUnits(oldExtendedType.getUnits());
-        newType.setDefaultValue(oldExtendedType.getDefaultValue());
-        newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes());
-        return newType;
-    }
-
-    /**
-     * Pull restrictions from type and add them to constraints.
-     *
-     * @param typeToResolve
-     *            type from which constraints will be read
-     * @param constraints
-     *            constraints object to which constraints will be added
-     * @return constraints contstraints object containing constraints from given
-     *         type
-     */
-    private static TypeConstraints findConstraintsFromTypeDefinition(final TypeDefinition<?> typeToResolve,
-            final TypeConstraints constraints) {
-        // union type cannot be restricted
-        if (typeToResolve instanceof UnionTypeDefinition) {
-            return constraints;
-        }
-        if (typeToResolve instanceof ExtendedType) {
-            ExtendedType extType = (ExtendedType) typeToResolve;
-            constraints.addFractionDigits(extType.getFractionDigits());
-            constraints.addLengths(extType.getLengths());
-            constraints.addPatterns(extType.getPatterns());
-            constraints.addRanges(extType.getRanges());
-            return findConstraintsFromTypeDefinition(extType.getBaseType(), constraints);
+    public static GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+        final int line = usesBuilder.getLine();
+        final String groupingString = usesBuilder.getGroupingName();
+        String groupingPrefix;
+        String groupingName;
+
+        if (groupingString.contains(":")) {
+            String[] splitted = groupingString.split(":");
+            if (splitted.length != 2 || groupingString.contains("/")) {
+                throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
+            }
+            groupingPrefix = splitted[0];
+            groupingName = splitted[1];
         } else {
-            mergeConstraints(typeToResolve, constraints);
-            return constraints;
+            groupingPrefix = module.getPrefix();
+            groupingName = groupingString;
         }
-    }
-
-    public static TypeConstraints findConstraintsFromTypeBuilder(final TypeAwareBuilder nodeToResolve,
-            final TypeConstraints constraints, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder builder, final SchemaContext context) {
 
-        // union and identityref types cannot be restricted
-        if (nodeToResolve instanceof UnionTypeBuilder || nodeToResolve instanceof IdentityrefTypeBuilder) {
-            return constraints;
-        }
-
-        if (nodeToResolve instanceof TypeDefinitionBuilder) {
-            TypeDefinitionBuilder typedefToResolve = (TypeDefinitionBuilder) nodeToResolve;
-            constraints.addFractionDigits(typedefToResolve.getFractionDigits());
-            constraints.addLengths(typedefToResolve.getLengths());
-            constraints.addPatterns(typedefToResolve.getPatterns());
-            constraints.addRanges(typedefToResolve.getRanges());
-        }
-
-        TypeDefinition<?> type = nodeToResolve.getType();
-        if (type == null) {
-            return findConstraintsFromTypeBuilder(nodeToResolve.getTypedef(), constraints, modules, builder, context);
+        ModuleBuilder dependentModule = null;
+        if (groupingPrefix.equals(module.getPrefix())) {
+            dependentModule = module;
         } else {
-            QName qname = type.getQName();
-            if (type instanceof UnknownType) {
-                ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(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 = findModuleFromContext(context, builder, qname.getPrefix(), nodeToResolve.getLine());
-                    TypeDefinition<?> t = findTypeByName(dm.getTypeDefinitions(), qname.getLocalName());
-                    if (t instanceof ExtendedType) {
-                        ExtendedType extType = (ExtendedType) t;
-                        constraints.addFractionDigits(extType.getFractionDigits());
-                        constraints.addLengths(extType.getLengths());
-                        constraints.addPatterns(extType.getPatterns());
-                        constraints.addRanges(extType.getRanges());
-                        return constraints;
-                    } else {
-                        mergeConstraints(t, constraints);
-                        return constraints;
-                    }
-                } else {
-                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModuleBuilder,
-                            qname.getLocalName(), builder.getName(), nodeToResolve.getLine());
-                    return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModuleBuilder, context);
-                }
-            } else if (type instanceof ExtendedType) {
-                ExtendedType extType = (ExtendedType) type;
-                constraints.addFractionDigits(extType.getFractionDigits());
-                constraints.addLengths(extType.getLengths());
-                constraints.addPatterns(extType.getPatterns());
-                constraints.addRanges(extType.getRanges());
-
-                TypeDefinition<?> base = extType.getBaseType();
-                if (base instanceof UnknownType) {
-                    ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, base.getQName()
-                            .getPrefix(), nodeToResolve.getLine());
-                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModule, base
-                            .getQName().getLocalName(), builder.getName(), nodeToResolve.getLine());
-                    return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModule, context);
-                } else {
-                    // it has to be base yang type
-                    mergeConstraints(type, constraints);
-                    return constraints;
-                }
-            } else {
-                // it is base yang type
-                mergeConstraints(type, constraints);
-                return constraints;
-            }
+            dependentModule = findDependentModuleBuilder(modules, module, groupingPrefix, line);
         }
-    }
-
-    /**
-     * Search for type definition builder by name.
-     *
-     * @param dirtyNodeSchemaPath
-     *            schema path of node which contains unresolved type
-     * @param dependentModule
-     *            module which should contains referenced type
-     * @param typeName
-     *            name of type definition
-     * @param currentModuleName
-     *            name of current module
-     * @param line
-     *            current line in yang model
-     * @return
-     */
-    public static TypeDefinitionBuilder findTypeDefinitionBuilder(final TypeAwareBuilder nodeToResolve,
-            final ModuleBuilder dependentModule, final String typeName, final String currentModuleName, final int line) {
 
-        TypeDefinitionBuilder result = null;
+        if (dependentModule == null) {
+            return null;
+        }
 
-        Set<TypeDefinitionBuilder> typedefs = dependentModule.getTypeDefinitionBuilders();
-        result = findTypedefBuilderByName(typedefs, typeName);
+        GroupingBuilder result = null;
+        Set<GroupingBuilder> groupings = dependentModule.getGroupingBuilders();
+        result = findGroupingBuilder(groupings, groupingName);
         if (result != null) {
             return result;
         }
 
-        Builder parent = nodeToResolve.getParent();
+        Builder parent = usesBuilder.getParent();
+
         while (parent != null) {
             if (parent instanceof DataNodeContainerBuilder) {
-                typedefs = ((DataNodeContainerBuilder) parent).getTypeDefinitionBuilders();
+                groupings = ((DataNodeContainerBuilder) parent).getGroupingBuilders();
             } else if (parent instanceof RpcDefinitionBuilder) {
-                typedefs = ((RpcDefinitionBuilder) parent).getTypeDefinitions();
+                groupings = ((RpcDefinitionBuilder) parent).getGroupings();
             }
-            result = findTypedefBuilderByName(typedefs, typeName);
+            result = findGroupingBuilder(groupings, groupingName);
             if (result == null) {
                 parent = parent.getParent();
             } else {
@@ -1221,7 +1069,62 @@ public final class ParserUtils {
         }
 
         if (result == null) {
-            throw new YangParseException(currentModuleName, line, "Referenced type '" + typeName + "' not found.");
+            throw new YangParseException(module.getName(), line, "Referenced 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();
+        String groupingString = usesBuilder.getGroupingName();
+        String groupingPrefix;
+        String groupingName;
+
+        if (groupingString.contains(":")) {
+            String[] splitted = groupingString.split(":");
+            if (splitted.length != 2 || groupingString.contains("/")) {
+                throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
+            }
+            groupingPrefix = splitted[0];
+            groupingName = splitted[1];
+        } else {
+            groupingPrefix = module.getPrefix();
+            groupingName = groupingString;
+        }
+
+        Module dependentModule = findModuleFromContext(context, module, groupingPrefix, line);
+        return findGroupingDefinition(dependentModule.getGroupings(), groupingName);
+    }
+
+    public static QName findFullQName(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module, final IdentityrefTypeBuilder idref) {
+        QName result = null;
+        String baseString = idref.getBaseString();
+        if (baseString.contains(":")) {
+            String[] splittedBase = baseString.split(":");
+            if (splittedBase.length > 2) {
+                throw new YangParseException(module.getName(), idref.getLine(), "Failed to parse identityref base: "
+                        + baseString);
+            }
+            String prefix = splittedBase[0];
+            String name = splittedBase[1];
+            ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix, idref.getLine());
+            result = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), prefix, name);
+        } else {
+            result = new QName(module.getNamespace(), module.getRevision(), module.getPrefix(), baseString);
         }
         return result;
     }
index 639a7ccce5ecc27dc1bc9410a317d4d70122e182..743b9afb9130a4aa78c716b044bdb55705b0db9a 100644 (file)
@@ -7,21 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.parser.util;
 
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.*;
-
 import java.lang.reflect.Method;
 import java.util.List;
 
-import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
-import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
@@ -43,85 +33,6 @@ public class RefineUtils {
     private RefineUtils() {
     }
 
-    /**
-     * Find original builder of node to refine and return copy of this builder.
-     * <p>
-     * We must create and use a copy of builder to preserve original builder
-     * state, because this object will be refined (modified) and later added to
-     * {@link UsesNodeBuilder}.
-     * </p>
-     *
-     * @param targetGrouping
-     *            builder of grouping which should contains node to refine
-     * @param refine
-     *            refine object containing informations about refine
-     * @param moduleName
-     *            current module name
-     * @return
-     */
-    public static DataSchemaNodeBuilder getRefineNodeFromGroupingBuilder(final GroupingBuilder targetGrouping,
-            final RefineHolder refine, final String moduleName) {
-        DataSchemaNodeBuilder result = null;
-        final Builder lookedUpBuilder = targetGrouping.getDataChildByName(refine.getName());
-        if (lookedUpBuilder == null) {
-            throw new YangParseException(moduleName, refine.getLine(), "Target node '" + refine.getName()
-                    + "' not found");
-        }
-        if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) {
-            result = new LeafSchemaNodeBuilder((LeafSchemaNodeBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof ContainerSchemaNodeBuilder) {
-            result = new ContainerSchemaNodeBuilder((ContainerSchemaNodeBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof ListSchemaNodeBuilder) {
-            result = new ListSchemaNodeBuilder((ListSchemaNodeBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof LeafListSchemaNodeBuilder) {
-            result = new LeafListSchemaNodeBuilder((LeafListSchemaNodeBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof ChoiceBuilder) {
-            result = new ChoiceBuilder((ChoiceBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof AnyXmlBuilder) {
-            result = new AnyXmlBuilder((AnyXmlBuilder) lookedUpBuilder);
-        } else {
-            throw new YangParseException(moduleName, refine.getLine(), "Target '" + refine.getName()
-                    + "' can not be refined");
-        }
-        return result;
-    }
-
-    /**
-     * Create builder object from refine target node.
-     *
-     * @param grouping
-     *            grouping which should contains node to refine
-     * @param refine
-     *            refine object containing informations about refine
-     * @return
-     */
-    public static DataSchemaNodeBuilder getRefineNodeFromGroupingDefinition(final GroupingDefinition grouping,
-            final RefineHolder refine) {
-        final String moduleName = refine.getModuleName();
-        final int line = refine.getLine();
-        DataSchemaNodeBuilder result = null;
-        final Object lookedUpNode = grouping.getDataChildByName(refine.getName());
-        if (lookedUpNode == null) {
-            throw new YangParseException(moduleName, line, "Refine target node '" + refine.getName() + "' not found");
-        }
-        if (lookedUpNode instanceof LeafSchemaNode) {
-            result = createLeafBuilder((LeafSchemaNode) lookedUpNode, moduleName, line);
-        } else if (lookedUpNode instanceof ContainerSchemaNode) {
-            result = createContainer((ContainerSchemaNode) lookedUpNode, moduleName, line);
-        } else if (lookedUpNode instanceof ListSchemaNode) {
-            result = createList((ListSchemaNode) lookedUpNode, moduleName, line);
-        } else if (lookedUpNode instanceof LeafListSchemaNode) {
-            result = createLeafList((LeafListSchemaNode) lookedUpNode, moduleName, line);
-        } else if (lookedUpNode instanceof ChoiceNode) {
-            result = createChoice((ChoiceNode) lookedUpNode, moduleName, line);
-        } else if (lookedUpNode instanceof AnyXmlSchemaNode) {
-            result = createAnyXml((AnyXmlSchemaNode) lookedUpNode, moduleName, line);
-        } else {
-            throw new YangParseException(moduleName, line, "Target '" + refine.getName() + "' can not be refined");
-        }
-        return result;
-    }
-
     public static void refineLeaf(LeafSchemaNodeBuilder leaf, RefineHolder refine) {
         String defaultStr = refine.getDefaultStr();
         Boolean mandatory = refine.isMandatory();
@@ -385,10 +296,9 @@ public class RefineUtils {
      *            builder of node to refine
      * @param refine
      *            refine object containing information about refine process
-     * @param line
-     *            current line in yang model
      */
-    public static void performRefine(SchemaNodeBuilder nodeToRefine, RefineHolder refine, int line) {
+    public static void performRefine(SchemaNodeBuilder nodeToRefine, RefineHolder refine) {
+        final int line = refine.getLine();
         checkRefine(nodeToRefine, refine);
         refineDefault(nodeToRefine, refine);
         if (nodeToRefine instanceof LeafSchemaNodeBuilder) {
diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/TypeUtils.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/TypeUtils.java
new file mode 100644 (file)
index 0000000..69020cb
--- /dev/null
@@ -0,0 +1,624 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.util;
+
+import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.*;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+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.SchemaPath;
+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;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+import org.opendaylight.yangtools.yang.model.util.Int16;
+import org.opendaylight.yangtools.yang.model.util.Int32;
+import org.opendaylight.yangtools.yang.model.util.Int64;
+import org.opendaylight.yangtools.yang.model.util.Int8;
+import org.opendaylight.yangtools.yang.model.util.StringType;
+import org.opendaylight.yangtools.yang.model.util.Uint16;
+import org.opendaylight.yangtools.yang.model.util.Uint32;
+import org.opendaylight.yangtools.yang.model.util.Uint64;
+import org.opendaylight.yangtools.yang.model.util.Uint8;
+import org.opendaylight.yangtools.yang.model.util.UnknownType;
+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.TypeAwareBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
+import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
+
+/**
+ * Utility class which contains helper methods for dealing with type operations.
+ */
+public class TypeUtils {
+
+    private TypeUtils() {
+    }
+
+    /**
+     * 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
+     */
+    public static void resolveType(final TypeAwareBuilder nodeToResolve,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+        TypeDefinitionBuilder resolvedType = null;
+        final int line = nodeToResolve.getLine();
+        final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
+        final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
+        final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, unknownTypeQName.getPrefix(),
+                line);
+
+        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve, dependentModule,
+                unknownTypeQName.getLocalName(), module.getName(), line);
+
+        if (nodeToResolveType instanceof ExtendedType) {
+            final ExtendedType extType = (ExtendedType) nodeToResolveType;
+            final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, extType,
+                    modules, module, nodeToResolve.getLine());
+            resolvedType = newType;
+        } else {
+            resolvedType = targetTypeBuilder;
+        }
+
+        // validate constraints
+        final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve,
+                new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, null);
+        constraints.validateConstraints();
+
+        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) {
+        TypeDefinitionBuilder resolvedType = null;
+        final int line = nodeToResolve.getLine();
+        final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
+        final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
+        final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(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 = extendedTypeWithNewBaseType(type, extType, 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 {
+            final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve,
+                    dependentModuleBuilder, unknownTypeQName.getLocalName(), module.getName(), line);
+
+            if (nodeToResolveType instanceof ExtendedType) {
+                final ExtendedType extType = (ExtendedType) nodeToResolveType;
+                final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, extType,
+                        modules, module, nodeToResolve.getLine());
+                resolvedType = newType;
+            } else {
+                resolvedType = targetTypeBuilder;
+            }
+
+            // validate constraints
+            final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve, new TypeConstraints(
+                    module.getName(), nodeToResolve.getLine()), modules, module, context);
+            constraints.validateConstraints();
+
+            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<TypeDefinition<?>>();
+        for (TypeDefinition<?> unionType : unionTypes) {
+            if (unionType instanceof UnknownType) {
+                final UnknownType ut = (UnknownType) unionType;
+                final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName()
+                        .getPrefix(), union.getLine());
+                final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModule, ut
+                        .getQName().getLocalName(), builder.getName(), union.getLine());
+                union.setTypedef(resolvedType);
+                toRemove.add(ut);
+            } else if (unionType instanceof ExtendedType) {
+                final ExtendedType extType = (ExtendedType) unionType;
+                final TypeDefinition<?> extTypeBase = extType.getBaseType();
+                if (extTypeBase instanceof UnknownType) {
+                    final UnknownType ut = (UnknownType) extTypeBase;
+                    final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName()
+                            .getPrefix(), union.getLine());
+                    final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union, dependentModule,
+                            ut.getQName().getLocalName(), builder.getName(), union.getLine());
+
+                    final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder,
+                            extType, modules, builder, union.getLine());
+
+                    union.setTypedef(newType);
+                    toRemove.add(extType);
+                }
+            }
+        }
+        unionTypes.removeAll(toRemove);
+    }
+
+    public static void resolveTypeUnionWithContext(final UnionTypeBuilder union,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder,
+            final SchemaContext context) {
+
+        final List<TypeDefinition<?>> unionTypes = union.getTypes();
+        final List<TypeDefinition<?>> toRemove = new ArrayList<TypeDefinition<?>>();
+        for (TypeDefinition<?> unionType : unionTypes) {
+            if (unionType instanceof UnknownType) {
+                final UnknownType ut = (UnknownType) unionType;
+                final QName utQName = ut.getQName();
+                final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder,
+                        utQName.getPrefix(), union.getLine());
+
+                if (dependentModuleBuilder == null) {
+                    Module dependentModule = findModuleFromContext(context, builder, utQName.getPrefix(),
+                            union.getLine());
+                    Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
+                    TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
+                    union.setType(type);
+                    toRemove.add(ut);
+                } else {
+                    final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModuleBuilder,
+                            utQName.getLocalName(), builder.getName(), union.getLine());
+                    union.setTypedef(resolvedType);
+                    toRemove.add(ut);
+                }
+
+            } else if (unionType instanceof ExtendedType) {
+                final ExtendedType extType = (ExtendedType) unionType;
+                TypeDefinition<?> extTypeBase = extType.getBaseType();
+                if (extTypeBase instanceof UnknownType) {
+                    final UnknownType ut = (UnknownType) extTypeBase;
+                    final QName utQName = ut.getQName();
+                    final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder,
+                            utQName.getPrefix(), union.getLine());
+
+                    if (dependentModuleBuilder == null) {
+                        final Module dependentModule = findModuleFromContext(context, builder, utQName.getPrefix(),
+                                union.getLine());
+                        Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
+                        TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
+                        final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(type, extType, builder, 0);
+
+                        union.setTypedef(newType);
+                        toRemove.add(extType);
+                    } else {
+                        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union,
+                                dependentModuleBuilder, utQName.getLocalName(), builder.getName(), union.getLine());
+
+                        final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder,
+                                extType, modules, builder, union.getLine());
+
+                        union.setTypedef(newType);
+                        toRemove.add(extType);
+                    }
+                }
+            }
+        }
+        unionTypes.removeAll(toRemove);
+    }
+
+    /**
+     * Search types for type with given name.
+     *
+     * @param types
+     *            types to search
+     * @param name
+     *            name of type
+     * @return type with given name if present in collection, null otherwise
+     */
+    private static TypeDefinitionBuilder findTypedefBuilderByName(Set<TypeDefinitionBuilder> types, String name) {
+        for (TypeDefinitionBuilder td : types) {
+            if (td.getQName().getLocalName().equals(name)) {
+                return td;
+            }
+        }
+        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.
+     *
+     * @param type
+     * @param constraints
+     */
+    private static void mergeConstraints(final TypeDefinition<?> type, final TypeConstraints constraints) {
+        if (type instanceof DecimalTypeDefinition) {
+            constraints.addRanges(((DecimalTypeDefinition) type).getRangeStatements());
+            constraints.addFractionDigits(((DecimalTypeDefinition) type).getFractionDigits());
+        } else if (type instanceof IntegerTypeDefinition) {
+            constraints.addRanges(((IntegerTypeDefinition) type).getRangeStatements());
+        } else if (type instanceof StringTypeDefinition) {
+            constraints.addPatterns(((StringTypeDefinition) type).getPatterns());
+            constraints.addLengths(((StringTypeDefinition) type).getLengthStatements());
+        } else if (type instanceof BinaryTypeDefinition) {
+            constraints.addLengths(((BinaryTypeDefinition) type).getLengthConstraints());
+        }
+    }
+
+    /**
+     * Create new ExtendedType based on given type and with schema path.
+     *
+     * @param newPath
+     *            schema path for new type
+     * @param oldType
+     *            type based
+     * @return
+     */
+    static ExtendedType createNewExtendedType(final ExtendedType oldType, final SchemaPath newPath) {
+        QName qname = oldType.getQName();
+        TypeDefinition<?> baseType = oldType.getBaseType();
+        String desc = oldType.getDescription();
+        String ref = oldType.getReference();
+        ExtendedType.Builder builder = new ExtendedType.Builder(qname, baseType, desc, ref, newPath);
+        builder.status(oldType.getStatus());
+        builder.lengths(oldType.getLengths());
+        builder.patterns(oldType.getPatterns());
+        builder.ranges(oldType.getRanges());
+        builder.fractionDigits(oldType.getFractionDigits());
+        builder.unknownSchemaNodes(oldType.getUnknownSchemaNodes());
+        return builder.build();
+    }
+
+    static StringTypeDefinition createNewStringType(final SchemaPath schemaPath, final QName nodeQName,
+            final StringTypeDefinition nodeType) {
+        final List<QName> path = schemaPath.getPath();
+        final List<QName> newPath = new ArrayList<QName>(path);
+        newPath.add(nodeQName);
+        newPath.add(nodeType.getQName());
+        final SchemaPath newSchemaPath = new SchemaPath(newPath, schemaPath.isAbsolute());
+        return new StringType(newSchemaPath);
+    }
+
+    static IntegerTypeDefinition createNewIntType(final SchemaPath schemaPath, final QName nodeQName,
+            final IntegerTypeDefinition type) {
+        final QName typeQName = type.getQName();
+        final SchemaPath newSchemaPath = createSchemaPath(schemaPath, nodeQName, typeQName);
+        final String localName = typeQName.getLocalName();
+
+        if ("int8".equals(localName)) {
+            return new Int8(newSchemaPath);
+        } else if ("int16".equals(localName)) {
+            return new Int16(newSchemaPath);
+        } else if ("int32".equals(localName)) {
+            return new Int32(newSchemaPath);
+        } else if ("int64".equals(localName)) {
+            return new Int64(newSchemaPath);
+        } else {
+            return null;
+        }
+    }
+
+    static UnsignedIntegerTypeDefinition createNewUintType(final SchemaPath schemaPath, final QName nodeQName,
+            final UnsignedIntegerTypeDefinition type) {
+        final QName typeQName = type.getQName();
+        final SchemaPath newSchemaPath = createSchemaPath(schemaPath, nodeQName, typeQName);
+        final String localName = typeQName.getLocalName();
+
+        if ("uint8".equals(localName)) {
+            return new Uint8(newSchemaPath);
+        } else if ("uint16".equals(localName)) {
+            return new Uint16(newSchemaPath);
+        } else if ("uint32".equals(localName)) {
+            return new Uint32(newSchemaPath);
+        } else if ("uint64".equals(localName)) {
+            return new Uint64(newSchemaPath);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Create new type builder based on old type with new base type.
+     *
+     * @param newBaseType
+     *            new base type builder
+     * @param oldExtendedType
+     *            old type
+     * @param modules
+     *            all loaded modules
+     * @param module
+     *            current module
+     * @param line
+     *            current line in module
+     * @return new type builder based on old type with new base type
+     */
+    private static TypeDefinitionBuilder extendedTypeWithNewBaseTypeBuilder(final TypeDefinitionBuilder newBaseType,
+            final ExtendedType oldExtendedType, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module, final int line) {
+        final TypeConstraints tc = new TypeConstraints(module.getName(), line);
+        tc.addFractionDigits(oldExtendedType.getFractionDigits());
+        tc.addLengths(oldExtendedType.getLengths());
+        tc.addPatterns(oldExtendedType.getPatterns());
+        tc.addRanges(oldExtendedType.getRanges());
+
+        final TypeConstraints constraints = findConstraintsFromTypeBuilder(newBaseType, tc, modules, module, null);
+        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(module.getModuleName(), line,
+                oldExtendedType.getQName());
+        newType.setTypedef(newBaseType);
+        newType.setPath(oldExtendedType.getPath());
+        newType.setDescription(oldExtendedType.getDescription());
+        newType.setReference(oldExtendedType.getReference());
+        newType.setStatus(oldExtendedType.getStatus());
+        newType.setLengths(constraints.getLength());
+        newType.setPatterns(constraints.getPatterns());
+        newType.setRanges(constraints.getRange());
+        newType.setFractionDigits(constraints.getFractionDigits());
+        newType.setUnits(oldExtendedType.getUnits());
+        newType.setDefaultValue(oldExtendedType.getDefaultValue());
+        newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes());
+        return newType;
+    }
+
+    /**
+     * Create new type builder based on old type with new base type.
+     *
+     * @param newBaseType
+     *            new base type
+     * @param oldExtendedType
+     *            old type
+     * @param modules
+     *            all loaded modules
+     * @param module
+     *            current module
+     * @param line
+     *            current line in module
+     * @return new type builder based on old type with new base type
+     */
+    private static TypeDefinitionBuilder extendedTypeWithNewBaseType(final TypeDefinition<?> newBaseType,
+            final ExtendedType oldExtendedType, final ModuleBuilder module, final int line) {
+        final TypeConstraints tc = new TypeConstraints(module.getName(), line);
+
+        final TypeConstraints constraints = findConstraintsFromTypeDefinition(newBaseType, tc);
+        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(module.getModuleName(), line,
+                oldExtendedType.getQName());
+        newType.setType(newBaseType);
+        newType.setPath(oldExtendedType.getPath());
+        newType.setDescription(oldExtendedType.getDescription());
+        newType.setReference(oldExtendedType.getReference());
+        newType.setStatus(oldExtendedType.getStatus());
+        newType.setLengths(constraints.getLength());
+        newType.setPatterns(constraints.getPatterns());
+        newType.setRanges(constraints.getRange());
+        newType.setFractionDigits(constraints.getFractionDigits());
+        newType.setUnits(oldExtendedType.getUnits());
+        newType.setDefaultValue(oldExtendedType.getDefaultValue());
+        newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes());
+        return newType;
+    }
+
+    /**
+     * Pull restrictions from type and add them to constraints.
+     *
+     * @param typeToResolve
+     *            type from which constraints will be read
+     * @param constraints
+     *            constraints object to which constraints will be added
+     * @return constraints contstraints object containing constraints from given
+     *         type
+     */
+    private static TypeConstraints findConstraintsFromTypeDefinition(final TypeDefinition<?> typeToResolve,
+            final TypeConstraints constraints) {
+        // union type cannot be restricted
+        if (typeToResolve instanceof UnionTypeDefinition) {
+            return constraints;
+        }
+        if (typeToResolve instanceof ExtendedType) {
+            ExtendedType extType = (ExtendedType) typeToResolve;
+            constraints.addFractionDigits(extType.getFractionDigits());
+            constraints.addLengths(extType.getLengths());
+            constraints.addPatterns(extType.getPatterns());
+            constraints.addRanges(extType.getRanges());
+            return findConstraintsFromTypeDefinition(extType.getBaseType(), constraints);
+        } else {
+            mergeConstraints(typeToResolve, constraints);
+            return constraints;
+        }
+    }
+
+    private static TypeConstraints findConstraintsFromTypeBuilder(final TypeAwareBuilder nodeToResolve,
+            final TypeConstraints constraints, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder builder, final SchemaContext context) {
+
+        // union and identityref types cannot be restricted
+        if (nodeToResolve instanceof UnionTypeBuilder || nodeToResolve instanceof IdentityrefTypeBuilder) {
+            return constraints;
+        }
+
+        if (nodeToResolve instanceof TypeDefinitionBuilder) {
+            TypeDefinitionBuilder typedefToResolve = (TypeDefinitionBuilder) nodeToResolve;
+            constraints.addFractionDigits(typedefToResolve.getFractionDigits());
+            constraints.addLengths(typedefToResolve.getLengths());
+            constraints.addPatterns(typedefToResolve.getPatterns());
+            constraints.addRanges(typedefToResolve.getRanges());
+        }
+
+        TypeDefinition<?> type = nodeToResolve.getType();
+        if (type == null) {
+            return findConstraintsFromTypeBuilder(nodeToResolve.getTypedef(), constraints, modules, builder, context);
+        } else {
+            QName qname = type.getQName();
+            if (type instanceof UnknownType) {
+                ModuleBuilder dependentModuleBuilder = ParserUtils.findDependentModuleBuilder(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 = ParserUtils.findModuleFromContext(context, builder, qname.getPrefix(),
+                            nodeToResolve.getLine());
+                    TypeDefinition<?> t = findTypeByName(dm.getTypeDefinitions(), qname.getLocalName());
+                    if (t instanceof ExtendedType) {
+                        ExtendedType extType = (ExtendedType) t;
+                        constraints.addFractionDigits(extType.getFractionDigits());
+                        constraints.addLengths(extType.getLengths());
+                        constraints.addPatterns(extType.getPatterns());
+                        constraints.addRanges(extType.getRanges());
+                        return constraints;
+                    } else {
+                        mergeConstraints(t, constraints);
+                        return constraints;
+                    }
+                } else {
+                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModuleBuilder,
+                            qname.getLocalName(), builder.getName(), nodeToResolve.getLine());
+                    return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModuleBuilder, context);
+                }
+            } else if (type instanceof ExtendedType) {
+                ExtendedType extType = (ExtendedType) type;
+                constraints.addFractionDigits(extType.getFractionDigits());
+                constraints.addLengths(extType.getLengths());
+                constraints.addPatterns(extType.getPatterns());
+                constraints.addRanges(extType.getRanges());
+
+                TypeDefinition<?> base = extType.getBaseType();
+                if (base instanceof UnknownType) {
+                    ModuleBuilder dependentModule = ParserUtils.findDependentModuleBuilder(modules, builder, base
+                            .getQName().getPrefix(), nodeToResolve.getLine());
+                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModule, base
+                            .getQName().getLocalName(), builder.getName(), nodeToResolve.getLine());
+                    return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModule, context);
+                } else {
+                    // it has to be base yang type
+                    mergeConstraints(type, constraints);
+                    return constraints;
+                }
+            } else {
+                // it is base yang type
+                mergeConstraints(type, constraints);
+                return constraints;
+            }
+        }
+    }
+
+    /**
+     * Search for type definition builder by name.
+     *
+     * @param dirtyNodeSchemaPath
+     *            schema path of node which contains unresolved type
+     * @param dependentModule
+     *            module which should contains referenced type
+     * @param typeName
+     *            name of type definition
+     * @param currentModuleName
+     *            name of current module
+     * @param line
+     *            current line in module
+     * @return
+     */
+    private static TypeDefinitionBuilder findTypeDefinitionBuilder(final TypeAwareBuilder nodeToResolve,
+            final ModuleBuilder dependentModule, final String typeName, final String currentModuleName, final int line) {
+
+        TypeDefinitionBuilder result = null;
+
+        Set<TypeDefinitionBuilder> typedefs = dependentModule.getTypeDefinitionBuilders();
+        result = findTypedefBuilderByName(typedefs, typeName);
+        if (result != null) {
+            return result;
+        }
+
+        Builder parent = nodeToResolve.getParent();
+        while (parent != null) {
+            if (parent instanceof DataNodeContainerBuilder) {
+                typedefs = ((DataNodeContainerBuilder) parent).getTypeDefinitionBuilders();
+            } else if (parent instanceof RpcDefinitionBuilder) {
+                typedefs = ((RpcDefinitionBuilder) parent).getTypeDefinitions();
+            }
+            result = findTypedefBuilderByName(typedefs, typeName);
+            if (result == null) {
+                parent = parent.getParent();
+            } else {
+                break;
+            }
+        }
+
+        if (result == null) {
+            throw new YangParseException(currentModuleName, line, "Referenced type '" + typeName + "' not found.");
+        }
+        return result;
+    }
+
+}
index c1f4de493db3c735a558a20ecfb0139c53f96d6d..eb7581681d880f4f21c0f3daba80a25a2d3deac7 100644 (file)
@@ -10,6 +10,9 @@ package org.opendaylight.yangtools.yang.parser.impl;
 import static org.junit.Assert.*;
 
 import java.io.FileNotFoundException;
+import java.net.URI;
+import java.text.ParseException;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -319,7 +322,7 @@ public class GroupingTest {
     }
 
     @Test
-    public void testCascadeUses() throws FileNotFoundException {
+    public void testCascadeUses() throws FileNotFoundException, ParseException {
         modules = TestUtils.loadModules(getClass().getResource("/simple-test").getPath());
         Module testModule = TestUtils.findModule(modules, "cascade-uses");
         Set<GroupingDefinition> groupings = testModule.getGroupings();
@@ -351,12 +354,43 @@ public class GroupingTest {
         assertNotNull(gz);
         assertNotNull(gzz);
 
-        assertEquals(6, gu.getChildNodes().size());
-        assertEquals(3, gv.getChildNodes().size());
+        assertEquals(7, gu.getChildNodes().size());
+        assertEquals(4, gv.getChildNodes().size());
         assertEquals(2, gx.getChildNodes().size());
         assertEquals(1, gy.getChildNodes().size());
         assertEquals(1, gz.getChildNodes().size());
         assertEquals(1, gzz.getChildNodes().size());
+
+        URI expectedNS = URI.create("urn:grouping:cascade-uses");
+        Date expectedRev = TestUtils.simpleDateFormat.parse("2013-07-18");
+        String expectedPref = "cu";
+        SchemaPath expectedPath;
+
+        // grouping-V/container-grouping-V
+        ContainerSchemaNode containerV = (ContainerSchemaNode)gv.getDataChildByName("container-grouping-V");
+        assertNotNull(containerV);
+        assertEquals(2, containerV.getChildNodes().size());
+        // grouping-V/container-grouping-V/leaf-grouping-X
+        LeafSchemaNode leafXinContainerV = (LeafSchemaNode)containerV.getDataChildByName("leaf-grouping-X");
+        assertNotNull(leafXinContainerV);
+        expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-V", "container-grouping-V", "leaf-grouping-X");
+        assertEquals(expectedPath, leafXinContainerV.getPath());
+        // grouping-V/container-grouping-V/leaf-grouping-Y
+        LeafSchemaNode leafYinContainerV = (LeafSchemaNode)containerV.getDataChildByName("leaf-grouping-Y");
+        assertNotNull(leafYinContainerV);
+        expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-V", "container-grouping-V", "leaf-grouping-Y");
+        assertEquals(expectedPath, leafYinContainerV.getPath());
+
+        // grouping-X/leaf-grouping-X
+        LeafSchemaNode leafXinGX = (LeafSchemaNode)gx.getDataChildByName("leaf-grouping-X");
+        assertNotNull(leafXinGX);
+        expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-X", "leaf-grouping-X");
+        assertEquals(expectedPath, leafXinGX.getPath());
+        // grouping-X/leaf-grouping-Y
+        LeafSchemaNode leafYinGY = (LeafSchemaNode)gx.getDataChildByName("leaf-grouping-Y");
+        assertNotNull(leafYinGY);
+        expectedPath = TestUtils.createPath(true, expectedNS, expectedRev, expectedPref, "grouping-X", "leaf-grouping-Y");
+        assertEquals(expectedPath, leafYinGY.getPath());
     }
 
 }
index ffa64d273338229a274b2c8023e2a881f8394004..b6ee3dd74d5d9b37a4457ef2ccbb25e1fc66cc2a 100644 (file)
@@ -32,6 +32,8 @@ import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
 
 final class TestUtils {
 
+    static final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
     private TestUtils() {
     }
 
index 484b18bc388f7c93f6695cb38db5009344ab47e6..119fcd7e7443fd22341de7d0398066167035c3bb 100644 (file)
@@ -36,7 +36,6 @@ import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.UsesNode;
 
 public class YangParserSimpleTest {
-
     private final URI snNS = URI.create("urn:opendaylight:simple-nodes");
     private Date snRev;
     private final String snPref = "sn";
index 54fa4ba94d6ae7b1677be7dcae85d8be0aa6a20d..859ba9c9c56f66b12306ef995078b642acbc2c95 100644 (file)
@@ -11,9 +11,7 @@ import static org.junit.Assert.*;
 
 import java.io.FileNotFoundException;
 import java.net.URI;
-import java.text.DateFormat;
 import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -56,7 +54,6 @@ import org.opendaylight.yangtools.yang.model.util.Uint32;
 import org.opendaylight.yangtools.yang.model.util.UnionType;
 
 public class YangParserTest {
-
     private final URI nodesNS = URI.create("urn:simple.nodes.test");
     private final URI typesNS = URI.create("urn:simple.types.test");
     private final URI customNS = URI.create("urn:custom.nodes.test");
@@ -64,14 +61,13 @@ public class YangParserTest {
     private Date typesRev;
     private Date customRev;
 
-    private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
     private Set<Module> modules;
 
     @Before
     public void init() throws FileNotFoundException, ParseException {
-        nodesRev = simpleDateFormat.parse("2013-02-27");
-        typesRev = simpleDateFormat.parse("2013-07-03");
-        customRev = simpleDateFormat.parse("2013-02-27");
+        nodesRev = TestUtils.simpleDateFormat.parse("2013-02-27");
+        typesRev = TestUtils.simpleDateFormat.parse("2013-07-03");
+        customRev = TestUtils.simpleDateFormat.parse("2013-02-27");
 
         modules = TestUtils.loadModules(getClass().getResource("/model").getPath());
         assertEquals(3, modules.size());
index 4dd8d1765b35f1b946c159e0de0025b6fc970ff7..74fa3576f10daf74a9eb0146bf89033b8f3ef83c 100644 (file)
@@ -1,7 +1,7 @@
 module cascade-uses {\r
     \r
-    namespace "urn:grouping:dependencies";\r
-    prefix "sbd";\r
+    namespace "urn:grouping:cascade-uses";\r
+    prefix "cu";\r
 \r
     organization "OPEN DAYLIGHT";\r
     contact "http://www.opendaylight.org/";\r
@@ -21,6 +21,9 @@ module cascade-uses {
         leaf leaf-grouping-V {\r
             type string;\r
         }\r
+        container container-grouping-V {\r
+            uses grouping-X;\r
+        }\r
         uses grouping-Z;\r
         uses grouping-ZZ;\r
     }\r