Merge "Parents pom distribution"
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / main / java / org / opendaylight / controller / yang / parser / impl / YangParserImpl.java
index 401189b1d1efbb11a79801c9837fb1053f1f226d..94437170f4be3c8ef91ae774debd26cb1d4f8963 100644 (file)
@@ -41,15 +41,11 @@ import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.DecimalTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition;
-import org.opendaylight.controller.yang.model.api.type.LengthConstraint;
-import org.opendaylight.controller.yang.model.api.type.PatternConstraint;
-import org.opendaylight.controller.yang.model.api.type.RangeConstraint;
 import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition;
 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
 import org.opendaylight.controller.yang.model.util.ExtendedType;
 import org.opendaylight.controller.yang.model.util.IdentityrefType;
 import org.opendaylight.controller.yang.model.util.UnknownType;
-import org.opendaylight.controller.yang.model.util.YangTypesConverter;
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.Builder;
@@ -232,6 +228,7 @@ public final class YangParserImpl implements YangModelParser {
             final YangLexer lexer = new YangLexer(input);
             final CommonTokenStream tokens = new CommonTokenStream(lexer);
             final YangParser parser = new YangParser(tokens);
+
             result = parser.yang();
         } catch (IOException e) {
             logger.warn("Exception while reading yang file: " + yangStream, e);
@@ -297,222 +294,116 @@ public final class YangParserImpl implements YangModelParser {
         if (!dirtyNodes.isEmpty()) {
             for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes
                     .entrySet()) {
-
                 final TypeAwareBuilder nodeToResolve = entry.getValue();
-                // different handling for union types
+
                 if (nodeToResolve instanceof UnionTypeBuilder) {
-                    final UnionTypeBuilder union = (UnionTypeBuilder) nodeToResolve;
-                    final List<TypeDefinition<?>> unionTypes = union.getTypes();
-                    final List<UnknownType> toRemove = new ArrayList<UnknownType>();
-                    for (TypeDefinition<?> td : unionTypes) {
-                        if (td instanceof UnknownType) {
-                            final UnknownType unknownType = (UnknownType) td;
-                            final TypeDefinitionBuilder resolvedType = resolveTypeUnion(
-                                    nodeToResolve, unknownType, modules, module);
-                            union.setTypedef(resolvedType);
-                            toRemove.add(unknownType);
-                        }
-                    }
-                    unionTypes.removeAll(toRemove);
+                    // special handling for union types
+                    resolveTypeUnion((UnionTypeBuilder) nodeToResolve, modules,
+                            module);
                 } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) {
-                    // different handling for identityref types
+                    // special handling for identityref types
                     IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve
                             .getTypedef();
                     nodeToResolve.setType(new IdentityrefType(findFullQName(
                             modules, module, idref), idref.getPath()));
                 } else {
-                    final TypeDefinitionBuilder resolvedType = resolveType(
-                            nodeToResolve, modules, module);
-                    nodeToResolve.setTypedef(resolvedType);
+                    resolveType(nodeToResolve, modules, module);
                 }
             }
         }
     }
 
-    private TypeDefinitionBuilder resolveType(
-            final TypeAwareBuilder nodeToResolve,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder builder) {
-        final TypeConstraints constraints = new TypeConstraints();
-
-        final TypeDefinitionBuilder targetTypeBuilder = getTypeDefinitionBuilderFromDirtyNode(
-                nodeToResolve, modules, builder);
-        final TypeConstraints tConstraints = findConstraints(nodeToResolve,
-                constraints, modules, builder);
-        targetTypeBuilder.setRanges(tConstraints.getRange());
-        targetTypeBuilder.setLengths(tConstraints.getLength());
-        targetTypeBuilder.setPatterns(tConstraints.getPatterns());
-        targetTypeBuilder.setFractionDigits(tConstraints.getFractionDigits());
-
-        return targetTypeBuilder;
-    }
-
-    private TypeDefinitionBuilder resolveTypeUnion(
-            final TypeAwareBuilder typeToResolve,
-            final UnknownType unknownType,
+    private void resolveType(final TypeAwareBuilder nodeToResolve,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder builder) {
-        final TypeConstraints constraints = new TypeConstraints();
-
-        final TypeDefinitionBuilder targetTypeBuilder = getUnionBuilder(
-                typeToResolve, unknownType, modules, builder);
-        final TypeConstraints tConstraints = findConstraints(typeToResolve,
-                constraints, modules, builder);
-        targetTypeBuilder.setRanges(tConstraints.getRange());
-        targetTypeBuilder.setLengths(tConstraints.getLength());
-        targetTypeBuilder.setPatterns(tConstraints.getPatterns());
-        targetTypeBuilder.setFractionDigits(tConstraints.getFractionDigits());
-
-        return targetTypeBuilder;
-    }
-
-    private TypeDefinitionBuilder getTypeDefinitionBuilderFromDirtyNode(
-            final TypeAwareBuilder nodeToResolve,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder module) {
-
-        final UnknownType unknownType = (UnknownType) nodeToResolve.getType();
-        final QName unknownTypeQName = unknownType.getQName();
-
-        // search for module which contains referenced typedef
+        TypeDefinitionBuilder resolvedType = null;
+        final int line = nodeToResolve.getLine();
+        final TypeDefinition<?> typedefType = nodeToResolve.getType();
+        final QName unknownTypeQName = typedefType.getBaseType().getQName();
         final ModuleBuilder dependentModule = findDependentModule(modules,
-                module, unknownTypeQName.getPrefix(), nodeToResolve.getLine());
+                builder, unknownTypeQName.getPrefix(), line);
 
-        final TypeDefinitionBuilder lookedUpBuilder = findTypeDefinitionBuilder(
+        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(
                 nodeToResolve.getPath(), dependentModule,
-                unknownTypeQName.getLocalName(), module.getName(),
-                nodeToResolve.getLine());
-
-        final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
-                lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder);
-        final TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
-                lookedUpBuilderCopy, modules, dependentModule);
-        return resolvedCopy;
-    }
+                unknownTypeQName.getLocalName(), builder.getName(), line);
 
-    private TypeDefinitionBuilder getUnionBuilder(
-            final TypeAwareBuilder nodeToResolve,
-            final UnknownType unknownType,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder module) {
-
-        final TypeDefinition<?> baseTypeToResolve = nodeToResolve.getType();
-        if (baseTypeToResolve != null
-                && !(baseTypeToResolve instanceof UnknownType)) {
-            return (TypeDefinitionBuilder) nodeToResolve;
-        }
-
-        final QName unknownTypeQName = unknownType.getQName();
-        // search for module which contains referenced typedef
-        final ModuleBuilder dependentModule = findDependentModule(modules,
-                module, unknownTypeQName.getPrefix(), nodeToResolve.getLine());
-        final TypeDefinitionBuilder lookedUpBuilder = findTypeDefinitionBuilder(
-                nodeToResolve.getPath(), dependentModule,
-                unknownTypeQName.getLocalName(), module.getName(),
-                nodeToResolve.getLine());
-
-        final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
-                lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder);
-        final TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
-                lookedUpBuilderCopy, modules, dependentModule);
-        return resolvedCopy;
-    }
-
-    private TypeDefinitionBuilder copyTypedefBuilder(
-            final TypeDefinitionBuilder old, final boolean seekByTypedefBuilder) {
-        if (old instanceof UnionTypeBuilder) {
-            final UnionTypeBuilder oldUnion = (UnionTypeBuilder) old;
-            final UnionTypeBuilder newUnion = new UnionTypeBuilder(
-                    old.getLine());
-            for (TypeDefinition<?> td : oldUnion.getTypes()) {
-                newUnion.setType(td);
-            }
-            for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) {
-                newUnion.setTypedef(copyTypedefBuilder(tdb, true));
-            }
-            newUnion.setPath(old.getPath());
-            return newUnion;
-        }
-
-        final QName oldName = old.getQName();
-        final QName newName = new QName(oldName.getNamespace(),
-                oldName.getRevision(), oldName.getPrefix(),
-                oldName.getLocalName());
-        final TypeDefinitionBuilder tdb = new TypeDefinitionBuilderImpl(
-                newName, old.getLine());
-
-        tdb.setRanges(old.getRanges());
-        tdb.setLengths(old.getLengths());
-        tdb.setPatterns(old.getPatterns());
-        tdb.setFractionDigits(old.getFractionDigits());
-        tdb.setPath(old.getPath());
-
-        final TypeDefinition<?> oldType = old.getType();
-        if (oldType == null) {
-            tdb.setTypedef(old.getTypedef());
+        if (typedefType instanceof ExtendedType) {
+            final ExtendedType extType = (ExtendedType) typedefType;
+            final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(
+                    nodeToResolve, targetTypeBuilder, extType, modules, builder);
+            resolvedType = newType;
         } else {
-            tdb.setType(oldType);
-        }
-
-        if (!seekByTypedefBuilder) {
-            tdb.setDescription(old.getDescription());
-            tdb.setReference(old.getReference());
-            tdb.setStatus(old.getStatus());
-            tdb.setDefaultValue(old.getDefaultValue());
-            tdb.setUnits(old.getUnits());
+            resolvedType = targetTypeBuilder;
         }
-        return tdb;
+        nodeToResolve.setTypedef(resolvedType);
     }
 
-    private TypeDefinitionBuilder resolveCopiedBuilder(
-            final TypeDefinitionBuilder copy,
+    private void resolveTypeUnion(final UnionTypeBuilder union,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder builder) {
 
-        if (copy instanceof UnionTypeBuilder) {
-            final UnionTypeBuilder union = (UnionTypeBuilder) copy;
-            final List<TypeDefinition<?>> unionTypes = union.getTypes();
-            final List<UnknownType> toRemove = new ArrayList<UnknownType>();
-            for (TypeDefinition<?> td : unionTypes) {
-                if (td instanceof UnknownType) {
-                    final UnknownType unknownType = (UnknownType) td;
-                    final TypeDefinitionBuilder resolvedType = resolveTypeUnion(
-                            union, unknownType, modules, builder);
-                    union.setTypedef(resolvedType);
-                    toRemove.add(unknownType);
+        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 = findDependentModule(
+                        modules, builder, ut.getQName().getPrefix(),
+                        union.getLine());
+                final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(
+                        union.getPath(), dependentModule, ut.getQName()
+                                .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 ModuleBuilder dependentModule = findDependentModule(
+                            modules, builder, ut.getQName().getPrefix(),
+                            union.getLine());
+                    final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(
+                            union.getPath(), dependentModule, ut.getQName()
+                                    .getLocalName(), builder.getName(),
+                            union.getLine());
+
+                    final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(
+                            targetTypeBuilder, targetTypeBuilder, extType,
+                            modules, builder);
+
+                    union.setTypedef(newType);
+                    toRemove.add(extType);
                 }
             }
-            unionTypes.removeAll(toRemove);
-
-            return union;
         }
+        unionTypes.removeAll(toRemove);
+    }
 
-        final TypeDefinition<?> base = copy.getType();
-        final TypeDefinitionBuilder baseTdb = copy.getTypedef();
-        if (base != null && !(base instanceof UnknownType)) {
-            return copy;
-        } else if (base instanceof UnknownType) {
-            final UnknownType unknownType = (UnknownType) base;
-            final QName unknownTypeQName = unknownType.getQName();
-            final String unknownTypePrefix = unknownTypeQName.getPrefix();
-            final ModuleBuilder dependentModule = findDependentModule(modules,
-                    builder, unknownTypePrefix, copy.getLine());
-            final TypeDefinitionBuilder utBuilder = getTypeDefinitionBuilderFromDirtyNode(
-                    copy, modules, dependentModule);
-            copy.setTypedef(utBuilder);
-            return copy;
-        } else if (base == null && baseTdb != null) {
-            // make a copy of baseTypeDef and call again
-            final TypeDefinitionBuilder baseTdbCopy = copyTypedefBuilder(
-                    baseTdb, true);
-            final TypeDefinitionBuilder baseTdbCopyResolved = resolveCopiedBuilder(
-                    baseTdbCopy, modules, builder);
-            copy.setTypedef(baseTdbCopyResolved);
-            return copy;
-        } else {
-            throw new YangParseException(copy.getLine(),
-                    "Failed to resolve type " + copy.getQName().getLocalName());
-        }
+    private TypeDefinitionBuilder extendedTypeWithNewBaseType(
+            final TypeAwareBuilder nodeToResolve,
+            final TypeDefinitionBuilder newBaseType,
+            final ExtendedType oldExtendedType,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder builder) {
+        final TypeConstraints constraints = findConstraints(nodeToResolve,
+                new TypeConstraints(), modules, builder);
+        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(
+                oldExtendedType.getQName(), nodeToResolve.getLine());
+        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;
     }
 
     private TypeConstraints findConstraints(
@@ -520,77 +411,63 @@ public final class YangParserImpl implements YangModelParser {
             final TypeConstraints constraints,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder builder) {
+
         // union type cannot be restricted
         if (nodeToResolve instanceof UnionTypeBuilder) {
             return constraints;
         }
 
-        // if referenced type is UnknownType again, search recursively with
-        // current constraints
-        final TypeDefinition<?> referencedType = nodeToResolve.getType();
-        List<RangeConstraint> ranges = Collections.emptyList();
-        List<LengthConstraint> lengths = Collections.emptyList();
-        List<PatternConstraint> patterns = Collections.emptyList();
-        Integer fractionDigits = null;
-        if (referencedType == null) {
-            final TypeDefinitionBuilder tdb = nodeToResolve.getTypedef();
-            ranges = tdb.getRanges();
-            constraints.addRanges(ranges);
-            lengths = tdb.getLengths();
-            constraints.addLengths(lengths);
-            patterns = tdb.getPatterns();
-            constraints.addPatterns(patterns);
-            fractionDigits = tdb.getFractionDigits();
-            constraints.setFractionDigits(fractionDigits);
-            return constraints;
-        } else if (referencedType instanceof ExtendedType) {
-            final ExtendedType ext = (ExtendedType) referencedType;
-            ranges = ext.getRanges();
-            constraints.addRanges(ranges);
-            lengths = ext.getLengths();
-            constraints.addLengths(lengths);
-            patterns = ext.getPatterns();
-            constraints.addPatterns(patterns);
-            fractionDigits = ext.getFractionDigits();
-            constraints.setFractionDigits(fractionDigits);
-            if(YangTypesConverter.isBaseYangType(ext.getBaseType().getQName().getLocalName())) {
-                mergeConstraints(ext.getBaseType(), constraints);
-                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 findConstraints(nodeToResolve.getTypedef(), constraints,
+                    modules, builder);
+        } else {
+            if (type instanceof UnknownType) {
+                ModuleBuilder dependentModule = findDependentModule(modules,
+                        builder, type.getQName().getPrefix(),
+                        nodeToResolve.getLine());
+                TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(
+                        nodeToResolve.getPath(), dependentModule, type
+                                .getQName().getLocalName(), builder.getName(),
+                        nodeToResolve.getLine());
+                return findConstraints(tdb, constraints, modules,
+                        dependentModule);
+            } 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 = findDependentModule(
+                            modules, builder, base.getQName().getPrefix(),
+                            nodeToResolve.getLine());
+                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(
+                            nodeToResolve.getPath(), dependentModule, base
+                                    .getQName().getLocalName(),
+                            builder.getName(), nodeToResolve.getLine());
+                    return findConstraints(tdb, constraints, modules,
+                            dependentModule);
+                } else {
+                    // it has to be base yang type
+                    mergeConstraints(type, constraints);
+                    return constraints;
+                }
             } else {
-                return findConstraints(
-                        findTypeDefinitionBuilder(nodeToResolve.getPath(), builder,
-                                ext.getQName().getLocalName(), builder.getName(),
-                                nodeToResolve.getLine()), constraints, modules,
-                        builder);
-            }
-        } else if (referencedType instanceof UnknownType) {
-            final UnknownType unknown = (UnknownType) referencedType;
-            ranges = unknown.getRangeStatements();
-            constraints.addRanges(ranges);
-            lengths = unknown.getLengthStatements();
-            constraints.addLengths(lengths);
-            patterns = unknown.getPatterns();
-            constraints.addPatterns(patterns);
-            fractionDigits = unknown.getFractionDigits();
-            constraints.setFractionDigits(fractionDigits);
-
-            String unknownTypePrefix = unknown.getQName().getPrefix();
-            if (unknownTypePrefix == null || "".equals(unknownTypePrefix)) {
-                unknownTypePrefix = builder.getPrefix();
+                // it is base yang type
+                mergeConstraints(type, constraints);
+                return constraints;
             }
-            final ModuleBuilder dependentModule = findDependentModule(modules,
-                    builder, unknown.getQName().getPrefix(),
-                    nodeToResolve.getLine());
-            final TypeDefinitionBuilder utBuilder = findTypeDefinitionBuilder(
-                    nodeToResolve.getPath(), dependentModule, unknown
-                            .getQName().getLocalName(), builder.getName(),
-                    nodeToResolve.getLine());
-            return findConstraints(utBuilder, constraints, modules,
-                    dependentModule);
-        } else {
-            // HANDLE BASE YANG TYPE
-            mergeConstraints(referencedType, constraints);
-            return constraints;
         }
     }
 
@@ -677,7 +554,7 @@ public final class YangParserImpl implements YangModelParser {
             constraints.addRanges(((DecimalTypeDefinition) referencedType)
                     .getRangeStatements());
             constraints
-                    .setFractionDigits(((DecimalTypeDefinition) referencedType)
+                    .addFractionDigits(((DecimalTypeDefinition) referencedType)
                             .getFractionDigits());
         } else if (referencedType instanceof IntegerTypeDefinition) {
             constraints.addRanges(((IntegerTypeDefinition) referencedType)
@@ -884,15 +761,15 @@ public final class YangParserImpl implements YangModelParser {
                 .getUsesNodes();
         for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses
                 .entrySet()) {
-            final List<String> key = entry.getKey();
             final UsesNodeBuilder usesNode = entry.getValue();
             final int line = usesNode.getLine();
 
-            final String groupingName = key.get(key.size() - 1);
+            GroupingBuilder targetGrouping = getTargetGrouping(usesNode, modules, module);
+            usesNode.setGroupingPath(targetGrouping.getPath());
 
             for (RefineHolder refine : usesNode.getRefines()) {
                 SchemaNodeBuilder refineTarget = getRefineNodeBuilderCopy(
-                        groupingName, refine, modules, module);
+                        targetGrouping, refine, modules, module);
                 ParserUtils.checkRefine(refineTarget, refine);
                 ParserUtils.refineDefault(refineTarget, refine, line);
                 if (refineTarget instanceof LeafSchemaNodeBuilder) {
@@ -928,6 +805,82 @@ public final class YangParserImpl implements YangModelParser {
         }
     }
 
+    private GroupingBuilder getTargetGrouping(
+            final UsesNodeBuilder usesBuilder,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module) {
+        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;
+        }
+
+        ModuleBuilder dependentModule = null;
+        if(groupingPrefix.equals(module.getPrefix())) {
+            dependentModule = module;
+        } else {
+            dependentModule = findDependentModule(modules, module, groupingPrefix, line);
+        }
+
+
+        List<QName> path = usesBuilder.getPath().getPath();
+        GroupingBuilder result = null;
+        Set<GroupingBuilder> groupings = dependentModule.getModuleGroupings();
+        result = findGrouping(groupings, groupingName);
+
+        if (result == null) {
+            Builder currentNode = null;
+            final List<String> currentPath = new ArrayList<String>();
+            currentPath.add(dependentModule.getName());
+
+            for (int i = 0; i < path.size(); i++) {
+                QName qname = path.get(i);
+                currentPath.add(qname.getLocalName());
+                currentNode = dependentModule.getModuleNode(currentPath);
+
+                if (currentNode instanceof RpcDefinitionBuilder) {
+                    groupings = ((RpcDefinitionBuilder) currentNode).getGroupings();
+                } else if (currentNode instanceof DataNodeContainerBuilder) {
+                    groupings = ((DataNodeContainerBuilder) currentNode).getGroupings();
+                } else {
+                    groupings = Collections.emptySet();
+                }
+
+                result = findGrouping(groupings, groupingName);
+                if (result != null) {
+                    break;
+                }
+            }
+        }
+
+        if (result != null) {
+            return result;
+        }
+        throw new YangParseException(module.getName(), line,
+                "Referenced grouping '" + groupingName + "' not found.");
+    }
+
+    private GroupingBuilder findGrouping(Set<GroupingBuilder> groupings,
+            String name) {
+        for (GroupingBuilder grouping : groupings) {
+            if (grouping.getQName().getLocalName().equals(name)) {
+                return grouping;
+            }
+        }
+        return null;
+    }
+
     /**
      * Find original builder of node to refine and return copy of this builder.
      * <p>
@@ -948,11 +901,11 @@ public final class YangParserImpl implements YangModelParser {
      *         otherwise
      */
     private SchemaNodeBuilder getRefineNodeBuilderCopy(
-            final String groupingPath, final RefineHolder refine,
+            final GroupingBuilder targetGrouping, final RefineHolder refine,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
         Builder result = null;
-        final Builder lookedUpBuilder = findRefineTargetBuilder(groupingPath,
+        final Builder lookedUpBuilder = findRefineTargetBuilder(targetGrouping,
                 refine, modules, module);
         if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) {
             result = ParserUtils
@@ -999,28 +952,11 @@ public final class YangParserImpl implements YangModelParser {
      * @return Builder object of refine node if it is present in grouping, null
      *         otherwise
      */
-    private Builder findRefineTargetBuilder(final String groupingPath,
+    private Builder findRefineTargetBuilder(final GroupingBuilder builder,
             final RefineHolder refine,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
         final String refineNodeName = refine.getName();
-        final SchemaPath path = ParserUtils.parseUsesPath(groupingPath);
-        final List<String> builderPath = new ArrayList<String>();
-        String prefix = null;
-        for (QName qname : path.getPath()) {
-            builderPath.add(qname.getLocalName());
-            prefix = qname.getPrefix();
-        }
-        if (prefix == null) {
-            prefix = module.getPrefix();
-        }
-
-        final ModuleBuilder dependentModule = findDependentModule(modules,
-                module, prefix, refine.getLine());
-        builderPath.add(0, dependentModule.getName());
-        final GroupingBuilder builder = dependentModule
-                .getGrouping(builderPath);
-
         Builder result = builder.getChildNode(refineNodeName);
         if (result == null) {
             Set<GroupingBuilder> grps = builder.getGroupings();