X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fsal%2Fyang-prototype%2Fcode-generator%2Fyang-model-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fyang%2Fparser%2Fimpl%2FYangParserImpl.java;h=94437170f4be3c8ef91ae774debd26cb1d4f8963;hb=ff1b4a79cca00743a00c3b0b1100bd0ab2b2fb31;hp=ac2b5334fb3ec66e0cf8915fee70101f5da2e8bc;hpb=24d031d133362f3b42eb2bc04173ad0199d39a51;p=controller.git diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java index ac2b5334fb..94437170f4 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java @@ -19,9 +19,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Set; import java.util.TreeMap; @@ -41,9 +41,6 @@ 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; @@ -81,35 +78,80 @@ import org.opendaylight.controller.yang.validator.YangModelBasicValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + public final class YangParserImpl implements YangModelParser { private static final Logger logger = LoggerFactory .getLogger(YangParserImpl.class); @Override - public Set parseYangModels(final List yangFiles) { + public Map parseYangModelsMapped(List yangFiles) { if (yangFiles != null) { - final List inputStreams = new ArrayList(); + final Map inputStreams = Maps.newHashMap(); for (final File yangFile : yangFiles) { try { - inputStreams.add(new FileInputStream(yangFile)); + inputStreams.put(new FileInputStream(yangFile), yangFile); } catch (FileNotFoundException e) { logger.warn("Exception while reading yang file: " + yangFile.getName(), e); } } - final Map> modules = resolveModuleBuilders(inputStreams); - return build(modules); + + Map builderToStreamMap = Maps + .newHashMap(); + + final Map> modules = resolveModuleBuilders( + Lists.newArrayList(inputStreams.keySet()), + builderToStreamMap); + // return new LinkedHashSet(build(modules).values()); + + Map retVal = Maps.newLinkedHashMap(); + Map builderToModuleMap = build(modules); + + for (Entry builderToModule : builderToModuleMap + .entrySet()) { + retVal.put(inputStreams.get(builderToStreamMap + .get(builderToModule.getKey())), builderToModule + .getValue()); + } + + return retVal; } - return Collections.emptySet(); + return Collections.emptyMap(); + } + + @Override + public Set parseYangModels(final List yangFiles) { + return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values()); } @Override public Set parseYangModelsFromStreams( final List yangModelStreams) { - final Map> modules = resolveModuleBuilders(yangModelStreams); - return build(modules); + return Sets.newHashSet(parseYangModelsFromStreamsMapped( + yangModelStreams).values()); + } + + @Override + public Map parseYangModelsFromStreamsMapped( + final List yangModelStreams) { + Map builderToStreamMap = Maps.newHashMap(); + + final Map> modules = resolveModuleBuilders( + yangModelStreams, builderToStreamMap); + Map retVal = Maps.newLinkedHashMap(); + Map builderToModuleMap = build(modules); + + for (Entry builderToModule : builderToModuleMap + .entrySet()) { + retVal.put(builderToStreamMap.get(builderToModule.getKey()), + builderToModule.getValue()); + } + return retVal; } @Override @@ -117,13 +159,11 @@ public final class YangParserImpl implements YangModelParser { return new SchemaContextImpl(modules); } - private Map> resolveModuleBuilders( - final List yangFileStreams) { - // Linked Hash Map MUST be used because Linked Hash Map preserves ORDER - // of items stored in map. - final Map> modules = new LinkedHashMap>(); + private ModuleBuilder[] parseModuleBuilders(List inputStreams, + Map streamToBuilderMap) { + final ParseTreeWalker walker = new ParseTreeWalker(); - final List trees = parseStreams(yangFileStreams); + final List trees = parseStreams(inputStreams); final ModuleBuilder[] builders = new ModuleBuilder[trees.size()]; // validate yang @@ -133,8 +173,25 @@ public final class YangParserImpl implements YangModelParser { for (int i = 0; i < trees.size(); i++) { yangModelParser = new YangParserListenerImpl(); walker.walk(yangModelParser, trees.get(i)); - builders[i] = yangModelParser.getModuleBuilder(); + ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder(); + + // We expect the order of trees and streams has to be the same + streamToBuilderMap.put(moduleBuilder, inputStreams.get(i)); + builders[i] = moduleBuilder; } + return builders; + } + + private Map> resolveModuleBuilders( + final List yangFileStreams, + Map streamToBuilderMap) { + + final ModuleBuilder[] builders = parseModuleBuilders(yangFileStreams, + streamToBuilderMap); + + // Linked Hash Map MUST be used because Linked Hash Map preserves ORDER + // of items stored in map. + final LinkedHashMap> modules = new LinkedHashMap>(); // module dependency graph sorted List sorted = ModuleDependencySort.sort(builders); @@ -171,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); @@ -178,7 +236,7 @@ public final class YangParserImpl implements YangModelParser { return result; } - private Set build( + private Map build( final Map> modules) { // fix unresolved nodes for (Map.Entry> entry : modules @@ -192,10 +250,10 @@ public final class YangParserImpl implements YangModelParser { resolveAugments(modules); // build - // LinkedHashSet MUST be used otherwise the Set will not maintain + // LinkedHashMap MUST be used otherwise the values will not maintain // order! - // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html - final Set result = new LinkedHashSet(); + // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html + final Map result = new LinkedHashMap(); for (Map.Entry> entry : modules .entrySet()) { final Map modulesByRevision = new HashMap(); @@ -204,7 +262,7 @@ public final class YangParserImpl implements YangModelParser { final ModuleBuilder moduleBuilder = childEntry.getValue(); final Module module = moduleBuilder.build(); modulesByRevision.put(childEntry.getKey(), module); - result.add(module); + result.put(moduleBuilder, module); } } return result; @@ -236,222 +294,116 @@ public final class YangParserImpl implements YangModelParser { if (!dirtyNodes.isEmpty()) { for (Map.Entry, 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> unionTypes = union.getTypes(); - final List toRemove = new ArrayList(); - 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, + private void resolveType(final TypeAwareBuilder nodeToResolve, final Map> 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, - final Map> 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> 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()); - - 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 getUnionBuilder( - final TypeAwareBuilder nodeToResolve, - final UnknownType unknownType, - final Map> modules, - final ModuleBuilder module) { + builder, unknownTypeQName.getPrefix(), line); - 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( + 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 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); + resolvedType = targetTypeBuilder; } - - if (!seekByTypedefBuilder) { - tdb.setDescription(old.getDescription()); - tdb.setReference(old.getReference()); - tdb.setStatus(old.getStatus()); - tdb.setDefaultValue(old.getDefaultValue()); - tdb.setUnits(old.getUnits()); - } - return tdb; + nodeToResolve.setTypedef(resolvedType); } - private TypeDefinitionBuilder resolveCopiedBuilder( - final TypeDefinitionBuilder copy, + private void resolveTypeUnion(final UnionTypeBuilder union, final Map> modules, final ModuleBuilder builder) { - if (copy instanceof UnionTypeBuilder) { - final UnionTypeBuilder union = (UnionTypeBuilder) copy; - final List> unionTypes = union.getTypes(); - final List toRemove = new ArrayList(); - 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> unionTypes = union.getTypes(); + final List> toRemove = new ArrayList>(); + 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> 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( @@ -459,72 +411,63 @@ public final class YangParserImpl implements YangModelParser { final TypeConstraints constraints, final Map> 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 ranges = Collections.emptyList(); - List lengths = Collections.emptyList(); - List 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); - 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(); - } - 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); + 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 { - // HANDLE BASE YANG TYPE - mergeConstraints(referencedType, constraints); - return constraints; + 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 { + // it is base yang type + mergeConstraints(type, constraints); + return constraints; + } } } @@ -611,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) @@ -739,7 +682,7 @@ public final class YangParserImpl implements YangModelParser { if (currentQName.getLocalName().equals( lastAugmentPathElement.getLocalName())) { - if(currentParent instanceof ChoiceBuilder) { + if (currentParent instanceof ChoiceBuilder) { ParserUtils.fillAugmentTarget(augmentBuilder, (ChoiceBuilder) currentParent); } else { @@ -818,15 +761,15 @@ public final class YangParserImpl implements YangModelParser { .getUsesNodes(); for (Map.Entry, UsesNodeBuilder> entry : moduleUses .entrySet()) { - final List 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) { @@ -862,6 +805,82 @@ public final class YangParserImpl implements YangModelParser { } } + private GroupingBuilder getTargetGrouping( + final UsesNodeBuilder usesBuilder, + final Map> 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 path = usesBuilder.getPath().getPath(); + GroupingBuilder result = null; + Set groupings = dependentModule.getModuleGroupings(); + result = findGrouping(groupings, groupingName); + + if (result == null) { + Builder currentNode = null; + final List currentPath = new ArrayList(); + 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 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. *

@@ -882,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> 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 @@ -933,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> modules, final ModuleBuilder module) { final String refineNodeName = refine.getName(); - final SchemaPath path = ParserUtils.parseUsesPath(groupingPath); - final List builderPath = new ArrayList(); - 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 grps = builder.getGroupings();