X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fimpl%2FYangParserImpl.java;h=f6d4d67cbbe1c3f2b2a53062546106aa6204f8c4;hb=4587d90bedeb11e0c100759dcd812a0a809f9f9c;hp=38b282de69c362bc8511c2bd002e718ad0dcad23;hpb=934fa2f832135385a1ef05377a5b43527f4049a1;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java index 38b282de69..f6d4d67cbb 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; @@ -29,7 +30,6 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; -import com.google.common.base.Preconditions; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; @@ -54,6 +54,7 @@ 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.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.DeviationBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.ExtensionBuilder; @@ -62,6 +63,7 @@ import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilde import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder; 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.GroupingSort; import org.opendaylight.yangtools.yang.parser.util.GroupingUtils; import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort; import org.opendaylight.yangtools.yang.parser.util.ParserUtils; @@ -70,6 +72,7 @@ import org.opendaylight.yangtools.yang.validator.YangModelBasicValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -95,7 +98,7 @@ public final class YangParserImpl implements YangModelParser { try { yangFileStream = new FileInputStream(yangFile); streamToFileMap.put(yangFileStream, yangFile); - } catch(FileNotFoundException e) { + } catch (FileNotFoundException e) { LOG.warn("Exception while reading yang file: " + yangFile.getName(), e); } @@ -108,13 +111,13 @@ public final class YangParserImpl implements YangModelParser { if (dependency.isFile()) { streamToFileMap.put(new FileInputStream(dependency), dependency); } - } catch(FileNotFoundException e) { + } catch (FileNotFoundException e) { LOG.warn("Exception while reading yang file: " + fileName, e); } } - Map parsedBuilders = parseModuleBuilders( - new ArrayList<>(streamToFileMap.keySet()), new HashMap()); + Map parsedBuilders = parseModuleBuilders(new ArrayList<>(streamToFileMap.keySet()), + new HashMap()); ModuleBuilder main = parsedBuilders.get(yangFileStream); List moduleBuilders = new ArrayList<>(); @@ -251,7 +254,7 @@ public final class YangParserImpl implements YangModelParser { new YangModelBasicValidator(walker).validate(new ArrayList<>(trees.values())); YangParserListenerImpl yangModelParser; - for(Map.Entry entry : trees.entrySet()) { + for (Map.Entry entry : trees.entrySet()) { yangModelParser = new YangParserListenerImpl(); walker.walk(yangModelParser, entry.getValue()); ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder(); @@ -354,9 +357,10 @@ public final class YangParserImpl implements YangModelParser { final CommonTokenStream tokens = new CommonTokenStream(lexer); final YangParser parser = new YangParser(tokens); parser.removeErrorListeners(); - parser.addErrorListener(new YangErrorListener()); - + YangErrorListener errorListener = new YangErrorListener(); + parser.addErrorListener(errorListener); result = parser.yang(); + errorListener.validate(); } catch (IOException e) { LOG.warn("Exception while reading yang file: " + yangStream, e); } @@ -365,12 +369,12 @@ public final class YangParserImpl implements YangModelParser { private Map build(final Map> modules) { // fix unresolved nodes + resolveDirtyNodes(modules); resolveAugmentsTargetPath(modules, null); resolveUsesTargetGrouping(modules, null); - resolveDirtyNodes(modules); + resolveUsesForGroupings(modules, null); + resolveUsesForNodes(modules, null); resolveAugments(modules); - resolveUses(modules, false); - resolvedUsesPostProcessing(modules, false); resolveDeviations(modules); // build @@ -388,12 +392,12 @@ public final class YangParserImpl implements YangModelParser { private Map buildWithContext(final Map> modules, final SchemaContext context) { // fix unresolved nodes + resolvedDirtyNodesWithContext(modules, context); resolveAugmentsTargetPath(modules, context); resolveUsesTargetGrouping(modules, context); - resolvedDirtyNodesWithContext(modules, context); + resolveUsesForGroupings(modules, context); + resolveUsesForNodes(modules, context); resolveAugmentsWithContext(modules, context); - resolveUses(modules, true); - resolvedUsesPostProcessing(modules, true); resolveDeviationsWithContext(modules, context); // build @@ -456,7 +460,7 @@ public final class YangParserImpl implements YangModelParser { throw new YangParseException(module.getName(), idref.getLine(), "Failed to find base identity"); } idref.setBaseIdentity(identity); - nodeToResolve.setType(idref.build()); + nodeToResolve.setType(idref.build(null)); } else { resolveType(nodeToResolve, modules, module); } @@ -478,7 +482,7 @@ public final class YangParserImpl implements YangModelParser { IdentitySchemaNodeBuilder identity = findBaseIdentity(modules, module, idref.getBaseString(), idref.getLine()); idref.setBaseIdentity(identity); - nodeToResolve.setType(idref.build()); + nodeToResolve.setType(idref.build(null)); } else { resolveTypeWithContext(nodeToResolve, modules, module, context); } @@ -513,32 +517,72 @@ public final class YangParserImpl implements YangModelParser { SchemaPath oldSchemaPath = augment.getTargetPath(); List oldPath = oldSchemaPath.getPath(); List newPath = new ArrayList<>(); - for (QName qn : oldPath) { - URI ns = module.getNamespace(); - Date rev = module.getRevision(); - String pref = module.getPrefix(); - String localPrefix = qn.getPrefix(); - if (localPrefix != null && !("".equals(localPrefix))) { - ModuleBuilder currentModule = ParserUtils.findModuleFromBuilders(modules, module, localPrefix, - augment.getLine()); - if (currentModule == null) { - Module m = ParserUtils.findModuleFromContext(context, module, localPrefix, augment.getLine()); - if (m == null) { - throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix " - + localPrefix + " not found."); + + Builder parent = augment.getParent(); + if (parent instanceof UsesNodeBuilder) { + DataNodeContainerBuilder usesParent = ((UsesNodeBuilder) parent).getParent(); + newPath.addAll(usesParent.getPath().getPath()); + + URI ns; + Date revision; + String prefix; + QName baseQName = usesParent.getQName(); + if (baseQName == null) { + ModuleBuilder m = ParserUtils.getParentModule(usesParent); + ns = m.getNamespace(); + revision = m.getRevision(); + prefix = m.getPrefix(); + } else { + ns = baseQName.getNamespace(); + revision = baseQName.getRevision(); + prefix = baseQName.getPrefix(); + } + + for (QName qn : oldSchemaPath.getPath()) { + newPath.add(new QName(ns, revision, prefix, qn.getLocalName())); + } + } else { + + for (QName qn : oldPath) { + URI ns = module.getNamespace(); + Date rev = module.getRevision(); + String pref = module.getPrefix(); + String localPrefix = qn.getPrefix(); + if (localPrefix != null && !("".equals(localPrefix))) { + ModuleBuilder currentModule = ParserUtils.findModuleFromBuilders(modules, module, localPrefix, + augment.getLine()); + if (currentModule == null) { + Module m = ParserUtils.findModuleFromContext(context, module, localPrefix, augment.getLine()); + if (m == null) { + throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix " + + localPrefix + " not found."); + } + ns = m.getNamespace(); + rev = m.getRevision(); + pref = m.getPrefix(); + } else { + ns = currentModule.getNamespace(); + rev = currentModule.getRevision(); + pref = currentModule.getPrefix(); } - ns = m.getNamespace(); - rev = m.getRevision(); - pref = m.getPrefix(); - } else { - ns = currentModule.getNamespace(); - rev = currentModule.getRevision(); - pref = currentModule.getPrefix(); } + newPath.add(new QName(ns, rev, pref, qn.getLocalName())); } - newPath.add(new QName(ns, rev, pref, qn.getLocalName())); } augment.setTargetNodeSchemaPath(new SchemaPath(newPath, augment.getTargetPath().isAbsolute())); + + for (DataSchemaNodeBuilder childNode : augment.getChildNodeBuilders()) { + correctPathForAugmentNodes(childNode, augment.getTargetNodeSchemaPath()); + } + } + + private void correctPathForAugmentNodes(DataSchemaNodeBuilder node, SchemaPath parentPath) { + node.setPath(ParserUtils.createSchemaPath(parentPath, node.getQName())); + if (node instanceof DataNodeContainerBuilder) { + for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) node).getChildNodeBuilders()) { + correctPathForAugmentNodes(child, node.getPath()); + } + } } /** @@ -607,7 +651,8 @@ public final class YangParserImpl implements YangModelParser { for (DataSchemaNodeBuilder childNode : augment.getChildNodeBuilders()) { if (childNode.getConstraints().isMandatory()) { throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Error in augment parsing: cannot augment mandatory node"); + "Error in augment parsing: cannot augment mandatory node " + + childNode.getQName().getLocalName()); } } } @@ -832,73 +877,89 @@ public final class YangParserImpl implements YangModelParser { } } - /** - * Copy data from uses target. Augmentations have to be resolved already. - * - * @param modules - * all loaded modules - * @param resolveWithContext - * boolean value which says whether - * {@link GroupingUtils#collectUsesDataFromContext(UsesNodeBuilder) - * collectUsesDataFromContext} should be used for processing of - * individual uses node. - */ - private void resolveUses(final Map> modules, final boolean resolveWithContext) { + private void resolveUsesForGroupings(final Map> modules, final SchemaContext context) { + final Set allGroupings = new HashSet<>(); for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry inner : entry.getValue().entrySet()) { ModuleBuilder module = inner.getValue(); - boolean dataCollected = module.isAllUsesDataCollected(); - - List usesNodes; - while (!dataCollected) { - usesNodes = new ArrayList<>(module.getAllUsesNodes()); - for (UsesNodeBuilder usesNode : usesNodes) { - if (!usesNode.isDataCollected()) { - if (resolveWithContext && usesNode.getGroupingBuilder() == null) { - GroupingUtils.collectUsesDataFromContext(usesNode); - } else { - GroupingUtils.collectUsesData(usesNode); - } - } - } - dataCollected = module.isAllUsesDataCollected(); - } + allGroupings.addAll(module.getAllGroupings()); + } + } + final List sorted = GroupingSort.sort(allGroupings); + for (GroupingBuilder gb : sorted) { + List usesNodes = new ArrayList<>(GroupingSort.getAllUsesNodes(gb)); + Collections.sort(usesNodes, new GroupingUtils.UsesComparator()); + for (UsesNodeBuilder usesNode : usesNodes) { + resolveUses(usesNode, modules, context); } } } - /** - * Update uses parent and perform refinement. - * - * @param modules - * all loaded modules - * @param resolveWithContext - * boolean value which says whether - * {@link GroupingUtils#collectUsesDataFromContext(UsesNodeBuilder) - * collectUsesDataFromContext} should be used for processing of - * individual uses node. - */ - private void resolvedUsesPostProcessing(final Map> modules, - final boolean resolveWithContext) { - // new loop is must because in collecting data process new uses could - // be created - final List allModulesUses = new ArrayList<>(); + private void resolveUsesForNodes(final Map> modules, final SchemaContext context) { for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry inner : entry.getValue().entrySet()) { - allModulesUses.addAll(inner.getValue().getAllUsesNodes()); + ModuleBuilder module = inner.getValue(); + List usesNodes = module.getAllUsesNodes(); + Collections.sort(usesNodes, new GroupingUtils.UsesComparator()); + for (UsesNodeBuilder usesNode : usesNodes) { + resolveUses(usesNode, modules, context); + } } } + } - for (UsesNodeBuilder usesNode : allModulesUses) { - GroupingUtils.updateUsesParent(usesNode); - GroupingUtils.performRefine(usesNode); - } + private void resolveUses(UsesNodeBuilder usesNode, + final Map> modules, final SchemaContext context) { + if (!usesNode.isResolved()) { + final int line = usesNode.getLine(); + DataNodeContainerBuilder parent = usesNode.getParent(); + ModuleBuilder module = ParserUtils.getParentModule(parent); + GroupingBuilder target = GroupingUtils.getTargetGroupingFromModules(usesNode, modules, module); + if (target == null) { + URI ns = null; + Date rev = null; + String prefix = null; + if (parent instanceof AugmentationSchemaBuilder || parent instanceof ModuleBuilder) { + ns = module.getNamespace(); + rev = module.getRevision(); + prefix = module.getPrefix(); + } else { + ns = ((DataSchemaNodeBuilder) parent).getQName().getNamespace(); + rev = ((DataSchemaNodeBuilder) parent).getQName().getRevision(); + prefix = ((DataSchemaNodeBuilder) parent).getQName().getPrefix(); + } - if (!resolveWithContext) { - for (UsesNodeBuilder usesNode : allModulesUses) { - if (usesNode.isCopy()) { - usesNode.getParent().getUsesNodes().remove(usesNode); + Set childNodes = GroupingUtils.getTargetGroupingDefinitionNodesWithNewNamespace( + usesNode, ns, rev, prefix, module.getName(), line); + parent.getChildNodeBuilders().addAll(childNodes); + Set typedefs = GroupingUtils + .getTargetGroupingDefinitionTypedefsWithNewNamespace(usesNode, ns, rev, prefix, + module.getName(), line); + parent.getTypeDefinitionBuilders().addAll(typedefs); + Set groupings = GroupingUtils.getTargetGroupingDefinitionGroupingsWithNewNamespace( + usesNode, ns, rev, prefix, module.getName(), line); + parent.getGroupingBuilders().addAll(groupings); + List unknownNodes = GroupingUtils + .getTargetGroupingDefinitionUnknownNodesWithNewNamespace(usesNode, ns, rev, prefix, + module.getName(), line); + parent.getUnknownNodeBuilders().addAll(unknownNodes); + usesNode.setResolved(true); + + for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) { + processAugmentationOnContext(augment, augment.getTargetPath().getPath(), module, prefix, context); } + GroupingUtils.performRefine(usesNode); + } else { + parent.getChildNodeBuilders().addAll(target.instantiateChildNodes(parent)); + parent.getTypeDefinitionBuilders().addAll(target.instantiateTypedefs(parent)); + parent.getGroupingBuilders().addAll(target.instantiateGroupings(parent)); + parent.getUnknownNodeBuilders().addAll(target.instantiateUnknownNodes(parent)); + usesNode.setResolved(true); + + for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) { + processAugmentation(augment, parent, augment.getTargetPath().getPath()); + } + GroupingUtils.performRefine(usesNode); } } } @@ -928,8 +989,8 @@ public final class YangParserImpl implements YangModelParser { for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) { QName nodeType = usnb.getNodeType(); try { - ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, - nodeType.getPrefix(), usnb.getLine()); + ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, nodeType.getPrefix(), + usnb.getLine()); if (dependentModuleBuilder == null) { Module dependentModule = findModuleFromContext(context, module, nodeType.getPrefix(),