X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fimpl%2FYangParserImpl.java;h=d80c31bba8ba48f69d13de75a9e800e570e08cf2;hb=364e85967bafce41b84ab2ead45295178a8292bc;hp=77d390f8f7a9aeb0742590d1e71e3aaadc92299d;hpb=fdf5ee9c3cde2766380c27703055251084ddf61d;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 77d390f8f7..d80c31bba8 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 @@ -15,24 +15,22 @@ import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.f import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findSchemaNodeInModule; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.processAugmentation; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.setNodeAddedByUses; -import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapChildNode; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapChildNodes; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapGroupings; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapTypedefs; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapUnknownNodes; import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveType; import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeUnion; -import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeUnionWithContext; -import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeWithContext; import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import com.google.common.base.Splitter; import com.google.common.collect.HashBiMap; import com.google.common.io.ByteSource; + import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -45,6 +43,9 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; + +import javax.annotation.concurrent.Immutable; + import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; @@ -54,15 +55,12 @@ import org.opendaylight.yangtools.antlrv4.code.gen.YangParser; import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; -import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; import org.opendaylight.yangtools.yang.model.api.ModuleImport; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser; import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException; @@ -98,10 +96,16 @@ import org.opendaylight.yangtools.yang.parser.util.YangParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Immutable public final class YangParserImpl implements YangContextParser { private static final Logger LOG = LoggerFactory.getLogger(YangParserImpl.class); - private static final String FAIL_DEVIATION_TARGET = "Failed to find deviation target."; + private static final Splitter COLON_SPLITTER = Splitter.on(':'); + private static final YangParserImpl INSTANCE = new YangParserImpl(); + + public static YangParserImpl getInstance() { + return INSTANCE; + } @Override @Deprecated @@ -147,7 +151,7 @@ public final class YangParserImpl implements YangContextParser { // module builders sorted by dependencies List sortedBuilders = ModuleDependencySort.sort(resolved); - LinkedHashMap> modules = orderModules(sortedBuilders); + LinkedHashMap> modules = resolveModulesWithImports(sortedBuilders, null); Collection unsorted = build(modules).values(); Set result = new LinkedHashSet<>( ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()]))); @@ -186,8 +190,7 @@ public final class YangParserImpl implements YangContextParser { } Collection sources = BuilderUtils.filesToByteSources(yangFiles); - SchemaContext result = parseSources(sources, context); - return result; + return parseSources(sources, context); } @Override @@ -228,8 +231,10 @@ public final class YangParserImpl implements YangContextParser { return resolveSchemaContext(Collections. emptySet()); } - final Map> modules = resolveModuleBuilders(sources, context); - final Set unsorted = new LinkedHashSet<>(buildWithContext(modules, context).values()); + final List sorted = resolveModuleBuilders(sources, context); + final Map> modules = resolveModulesWithImports(sorted, context); + + final Set unsorted = new LinkedHashSet<>(build(modules).values()); if (context != null) { for (Module m : context.getModules()) { if (!unsorted.contains(m)) { @@ -242,6 +247,33 @@ public final class YangParserImpl implements YangContextParser { return resolveSchemaContext(result); } + private LinkedHashMap> resolveModulesWithImports(final List sorted, + final SchemaContext context) { + final LinkedHashMap> modules = orderModules(sorted); + for (ModuleBuilder module : sorted) { + if (module != null) { + for (ModuleImport imp : module.getImports().values()) { + String prefix = imp.getPrefix(); + ModuleBuilder targetModule = findModuleFromBuilders(modules, module, prefix, 0); + if (targetModule == null) { + Module result = findModuleFromContext(context, module, prefix, 0); + targetModule = new ModuleBuilder(result); + TreeMap map = modules.get(prefix); + if (map == null) { + map = new TreeMap<>(); + map.put(targetModule.getRevision(), targetModule); + modules.put(targetModule.getName(), map); + } else { + map.put(targetModule.getRevision(), targetModule); + } + } + module.addImportedModule(prefix, targetModule); + } + } + } + return modules; + } + @Override public Map parseYangModelsMapped(final Collection yangFiles) { if (yangFiles == null || yangFiles.isEmpty()) { @@ -323,8 +355,7 @@ public final class YangParserImpl implements YangContextParser { Map sourceToBuilder = resolveSources(sources); // sort and check for duplicates List sorted = ModuleDependencySort.sort(sourceToBuilder.values()); - BuilderUtils.setSourceToBuilder(sourceToBuilder); - Map> modules = orderModules(sorted); + Map> modules = resolveModulesWithImports(sorted, null); Map builderToModule = build(modules); Map builderToSource = HashBiMap.create(sourceToBuilder).inverse(); sorted = ModuleDependencySort.sort(builderToModule.keySet()); @@ -347,11 +378,11 @@ public final class YangParserImpl implements YangContextParser { * parsed from stream * @throws YangSyntaxErrorException */ + // TODO: remove ByteSource result after removing YangModelParser private Map resolveSources(final Collection streams) throws IOException, YangSyntaxErrorException { Map builders = parseSourcesToBuilders(streams); - Map result = resolveSubmodules(builders); - return result; + return resolveSubmodules(builders); } private Map parseSourcesToBuilders(final Collection sources) @@ -366,24 +397,20 @@ public final class YangParserImpl implements YangContextParser { YangParserListenerImpl yangModelParser; for (Map.Entry entry : sourceToTree.entrySet()) { ByteSource source = entry.getKey(); - String path = null; - InputStream stream = source.openStream(); - if (stream instanceof NamedInputStream) { - path = stream.toString(); - } - try { - stream.close(); - } catch (IOException e) { - LOG.warn("Failed to close stream {}", stream); + String path = null; // TODO refactor to Optional + // TODO refactor so that path can be retrieved without opening + // stream: NamedInputStream -> NamedByteSource ? + try (InputStream stream = source.openStream()) { + if (stream instanceof NamedInputStream) { + path = stream.toString(); + } } - yangModelParser = new YangParserListenerImpl(path); walker.walk(yangModelParser, entry.getValue()); ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder(); + moduleBuilder.setSource(source); sourceToBuilder.put(source, moduleBuilder); } - - BuilderUtils.setSourceToBuilder(sourceToBuilder); return sourceToBuilder; } @@ -442,7 +469,7 @@ public final class YangParserImpl implements YangContextParser { private void addSubmoduleToModule(final ModuleBuilder submodule, final ModuleBuilder module) { submodule.setParent(module); module.getDirtyNodes().addAll(submodule.getDirtyNodes()); - module.getModuleImports().addAll(submodule.getModuleImports()); + module.getImports().putAll(submodule.getImports()); module.getAugments().addAll(submodule.getAugments()); module.getAugmentBuilders().addAll(submodule.getAugmentBuilders()); module.getAllAugments().addAll(submodule.getAllAugments()); @@ -472,9 +499,8 @@ public final class YangParserImpl implements YangContextParser { module.getAllUnknownNodes().addAll(submodule.getAllUnknownNodes()); } - private Map> resolveModuleBuilders( - final Collection yangFileStreams, final SchemaContext context) throws IOException, - YangSyntaxErrorException { + private List resolveModuleBuilders(final Collection yangFileStreams, + final SchemaContext context) throws IOException, YangSyntaxErrorException { Map parsedBuilders = resolveSources(yangFileStreams); ModuleBuilder[] builders = new ModuleBuilder[parsedBuilders.size()]; parsedBuilders.values().toArray(builders); @@ -486,14 +512,14 @@ public final class YangParserImpl implements YangContextParser { } else { sorted = ModuleDependencySort.sortWithContext(context, builders); } - return orderModules(sorted); + return sorted; } /** * Order modules by name and revision. * * @param modules - * modules to order + * topologically sorted modules * @return modules ordered by name and revision */ private LinkedHashMap> orderModules(final List modules) { @@ -510,9 +536,11 @@ public final class YangParserImpl implements YangContextParser { TreeMap builderByRevision = result.get(builderName); if (builderByRevision == null) { builderByRevision = new TreeMap<>(); + builderByRevision.put(builderRevision, builder); + result.put(builderName, builderByRevision); + } else { + builderByRevision.put(builderRevision, builder); } - builderByRevision.put(builderRevision, builder); - result.put(builderName, builderByRevision); } return result; } @@ -530,7 +558,7 @@ public final class YangParserImpl implements YangContextParser { */ private void filterImports(final ModuleBuilder main, final Collection other, final Collection filtered) { - Set imports = main.getModuleImports(); + Map imports = main.getImports(); // if this is submodule, add parent to filtered and pick its imports if (main.isSubmodule()) { @@ -542,10 +570,10 @@ public final class YangParserImpl implements YangContextParser { } ModuleBuilder parent = dependencies.get(dependencies.firstKey()); filtered.add(parent); - imports.addAll(parent.getModuleImports()); + imports.putAll(parent.getImports()); } - for (ModuleImport mi : imports) { + for (ModuleImport mi : imports.values()) { for (ModuleBuilder builder : other) { if (mi.getModuleName().equals(builder.getModuleName())) { if (mi.getRevision() == null) { @@ -593,6 +621,12 @@ public final class YangParserImpl implements YangContextParser { } } + /** + * Mini parser: This parsing context does not validate full YANG module, + * only parses header up to the revisions and imports. + * + * @see org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo + */ public static YangContext parseStreamWithoutErrorListeners(final InputStream yangStream) { YangContext result = null; try { @@ -631,11 +665,11 @@ public final class YangParserImpl implements YangContextParser { */ private Map build(final Map> modules) { resolveDirtyNodes(modules); - resolveAugmentsTargetPath(modules, null); - resolveUsesTargetGrouping(modules, null); - resolveUsesForGroupings(modules, null); - resolveUsesForNodes(modules, null); - resolveAugments(modules, null); + resolveAugmentsTargetPath(modules); + resolveUsesTargetGrouping(modules); + resolveUsesForGroupings(modules); + resolveUsesForNodes(modules); + resolveAugments(modules); resolveIdentities(modules); resolveDeviations(modules); @@ -651,52 +685,6 @@ public final class YangParserImpl implements YangContextParser { return result; } - /** - * Creates builder-to-module map based on given modules. Method first - * resolve unresolved type references, instantiate groupings through uses - * statements and perform augmentation. - * - * Node resolving must be performed in following order: - *
    - *
  1. - * unresolved type references
  2. - *
  3. - * uses in groupings
  4. - *
  5. - * uses in other nodes
  6. - *
  7. - * augments
  8. - *
- * - * @param modules - * all loaded modules - * @param context - * SchemaContext containing already resolved modules - * @return modules mapped on their builders - */ - private Map buildWithContext(final Map> modules, - final SchemaContext context) { - resolvedDirtyNodesWithContext(modules, context); - resolveAugmentsTargetPath(modules, context); - resolveUsesTargetGrouping(modules, context); - resolveUsesForGroupings(modules, context); - resolveUsesForNodes(modules, context); - resolveAugments(modules, context); - resolveIdentitiesWithContext(modules, context); - resolveDeviationsWithContext(modules, context); - - // build - final Map result = new LinkedHashMap<>(); - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry childEntry : entry.getValue().entrySet()) { - final ModuleBuilder moduleBuilder = childEntry.getValue(); - final Module module = moduleBuilder.build(); - result.put(moduleBuilder, module); - } - } - return result; - } - /** * Resolve all unresolved type references. * @@ -713,25 +701,6 @@ public final class YangParserImpl implements YangContextParser { } } - /** - * Resolve all unresolved type references. - * - * @param modules - * all loaded modules - * @param context - * SchemaContext containing already resolved modules - */ - private void resolvedDirtyNodesWithContext(final Map> modules, - final SchemaContext context) { - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry childEntry : entry.getValue().entrySet()) { - final ModuleBuilder module = childEntry.getValue(); - resolveUnknownNodesWithContext(modules, module, context); - resolveDirtyNodesWithContext(modules, module, context); - } - } - } - /** * Search for dirty nodes (node which contains UnknownType) and resolve * unknown types. @@ -765,39 +734,14 @@ public final class YangParserImpl implements YangContextParser { } } - private void resolveDirtyNodesWithContext(final Map> modules, - final ModuleBuilder module, final SchemaContext context) { - final Set dirtyNodes = module.getDirtyNodes(); - if (!dirtyNodes.isEmpty()) { - for (TypeAwareBuilder nodeToResolve : dirtyNodes) { - if (nodeToResolve instanceof UnionTypeBuilder) { - // special handling for union types - resolveTypeUnionWithContext((UnionTypeBuilder) nodeToResolve, modules, module, context); - } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) { - // special handling for identityref types - IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef(); - IdentitySchemaNodeBuilder identity = findBaseIdentity(modules, module, idref.getBaseString(), - idref.getLine()); - idref.setBaseIdentity(identity); - nodeToResolve.setType(idref.build()); - } else { - resolveTypeWithContext(nodeToResolve, modules, module, context); - } - } - } - } - /** * Traverse through augmentations of modules and fix their child nodes * schema path. * * @param modules * all loaded modules - * @param context - * SchemaContext containing already resolved modules */ - private void resolveAugmentsTargetPath(final Map> modules, - final SchemaContext context) { + private void resolveAugmentsTargetPath(final Map> modules) { // collect augments from all loaded modules final List allAugments = new ArrayList<>(); for (Map.Entry> entry : modules.entrySet()) { @@ -807,7 +751,7 @@ public final class YangParserImpl implements YangContextParser { } for (AugmentationSchemaBuilder augment : allAugments) { - setCorrectAugmentTargetPath(modules, augment, context); + setCorrectAugmentTargetPath(modules, augment); } } @@ -818,13 +762,11 @@ public final class YangParserImpl implements YangContextParser { * all loaded modules * @param augment * augment to resolve - * @param context - * SchemaContext containing already resolved modules */ private void setCorrectAugmentTargetPath(final Map> modules, - final AugmentationSchemaBuilder augment, final SchemaContext context) { + final AugmentationSchemaBuilder augment) { ModuleBuilder module = BuilderUtils.getParentModule(augment); - SchemaPath oldSchemaPath = augment.getTargetPath(); + Iterable oldPath = augment.getTargetPath().getPathFromRoot(); List newPath = new ArrayList<>(); Builder parent = augment.getParent(); @@ -832,48 +774,34 @@ public final class YangParserImpl implements YangContextParser { DataNodeContainerBuilder usesParent = ((UsesNodeBuilder) parent).getParent(); newPath.addAll(usesParent.getPath().getPath()); - URI ns; - Date revision; - String prefix; QName baseQName = usesParent.getQName(); + final QNameModule qnm; + String prefix; if (baseQName == null) { ModuleBuilder m = BuilderUtils.getParentModule(usesParent); - ns = m.getNamespace(); - revision = m.getRevision(); + qnm = m.getQNameModule(); prefix = m.getPrefix(); } else { - ns = baseQName.getNamespace(); - revision = baseQName.getRevision(); + qnm = baseQName.getModule(); prefix = baseQName.getPrefix(); } - final QNameModule qm = QNameModule.create(ns, revision); - for (QName qn : oldSchemaPath.getPathFromRoot()) { - newPath.add(QName.create(qm, prefix, qn.getLocalName())); + for (QName qn : oldPath) { + newPath.add(QName.create(qnm, prefix, qn.getLocalName())); } } else { - Iterable oldPath = oldSchemaPath.getPathFromRoot(); for (QName qn : oldPath) { - URI ns = module.getNamespace(); - Date rev = module.getRevision(); + QNameModule qnm = module.getQNameModule(); String localPrefix = qn.getPrefix(); - if (localPrefix != null && !("".equals(localPrefix))) { - ModuleBuilder currentModule = BuilderUtils.findModuleFromBuilders(modules, module, localPrefix, - augment.getLine()); + if (localPrefix != null && !localPrefix.isEmpty()) { + ModuleBuilder currentModule = BuilderUtils.getModuleByPrefix(module, localPrefix); if (currentModule == null) { - Module m = BuilderUtils.findModuleFromContext(context, module, localPrefix, augment.getLine()); - if (m == null) { - throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix " - + localPrefix + " not found."); - } - ns = m.getNamespace(); - rev = m.getRevision(); - } else { - ns = currentModule.getNamespace(); - rev = currentModule.getRevision(); + throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix " + + localPrefix + " not found."); } + qnm = currentModule.getQNameModule(); } - newPath.add(new QName(ns, rev, localPrefix, qn.getLocalName())); + newPath.add(QName.create(qnm, localPrefix, qn.getLocalName())); } } augment.setTargetNodeSchemaPath(SchemaPath.create(newPath, true)); @@ -939,11 +867,10 @@ public final class YangParserImpl implements YangContextParser { * Go through all augment definitions and resolve them. * * @param modules - * all loaded modules - * @param context - * SchemaContext containing already resolved modules + * all loaded modules topologically sorted (based on dependencies + * between each other) */ - private void resolveAugments(final Map> modules, final SchemaContext context) { + private void resolveAugments(final Map> modules) { List all = new ArrayList<>(); for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry inner : entry.getValue().entrySet()) { @@ -951,21 +878,14 @@ public final class YangParserImpl implements YangContextParser { } } - List sorted; - if (context == null) { - sorted = ModuleDependencySort.sort(all.toArray(new ModuleBuilder[all.size()])); - } else { - sorted = ModuleDependencySort.sortWithContext(context, all.toArray(new ModuleBuilder[all.size()])); - } - - for (ModuleBuilder mb : sorted) { + for (ModuleBuilder mb : all) { if (mb != null) { List augments = mb.getAllAugments(); checkAugmentMandatoryNodes(augments); - Collections.sort(augments, Comparators.AUGMENT_COMP); + Collections.sort(augments, Comparators.AUGMENT_BUILDER_COMP); for (AugmentationSchemaBuilder augment : augments) { if (!(augment.isResolved())) { - boolean resolved = resolveAugment(augment, mb, modules, context); + boolean resolved = resolveAugment(augment, mb, modules); if (!resolved) { throw new YangParseException(augment.getModuleName(), augment.getLine(), "Error in augment parsing: failed to find augment target: " + augment); @@ -985,12 +905,10 @@ public final class YangParserImpl implements YangContextParser { * current module * @param modules * all loaded modules - * @param context - * SchemaContext containing already resolved modules * @return true if augment process succeed */ private boolean resolveUsesAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module, - final Map> modules, final SchemaContext context) { + final Map> modules) { if (augment.isResolved()) { return true; } @@ -1004,12 +922,14 @@ public final class YangParserImpl implements YangContextParser { // We lookup in data namespace to find correct augmentation target potentialTargetNode = findSchemaNodeInModule(resolvedTargetPath, (ModuleBuilder) parentNode); } else { - // Uses is used in local context (be it data namespace or grouping namespace, + // Uses is used in local context (be it data namespace or grouping + // namespace, // since all nodes via uses are imported to localName, it is safe to // to proceed only with local names. // // Conflicting elements in other namespaces are still not present - // since resolveUsesAugment occurs before augmenting from external modules. + // since resolveUsesAugment occurs before augmenting from external + // modules. potentialTargetNode = Optional. fromNullable(findSchemaNode(augment.getTargetPath() .getPath(), (SchemaNodeBuilder) parentNode)); } @@ -1041,18 +961,16 @@ public final class YangParserImpl implements YangContextParser { * current module * @param modules * all loaded modules - * @param context - * SchemaContext containing already resolved modules * @return true if augment process succeed */ private boolean resolveAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module, - final Map> modules, final SchemaContext context) { + final Map> modules) { if (augment.isResolved()) { return true; } - QName targetPath = augment.getTargetPath().getPathFromRoot().iterator().next(); - ModuleBuilder targetModule = findTargetModule(targetPath, module, modules, context, augment.getLine()); + QName targetModuleName = augment.getTargetPath().getPathFromRoot().iterator().next(); + ModuleBuilder targetModule = BuilderUtils.getModuleByPrefix(module, targetModuleName.getPrefix()); if (targetModule == null) { throw new YangParseException(module.getModuleName(), augment.getLine(), "Failed to resolve augment " + augment); @@ -1061,80 +979,12 @@ public final class YangParserImpl implements YangContextParser { return processAugmentation(augment, targetModule); } - /** - * Find module from loaded modules or from context based on given qname. If - * module is found in context, create wrapper over this module and add it to - * collection of loaded modules. - * - * @param qname - * @param module - * current module - * @param modules - * all loaded modules - * @param context - * schema context - * @param line - * current line - * @return - */ - private ModuleBuilder findTargetModule(final QName qname, final ModuleBuilder module, - final Map> modules, final SchemaContext context, final int line) { - ModuleBuilder targetModule = null; - - String prefix = qname.getPrefix(); - if (prefix == null || prefix.equals("")) { - targetModule = module; - } else { - targetModule = findModuleFromBuilders(modules, module, qname.getPrefix(), line); - } - - if (targetModule == null && context != null) { - Module m = findModuleFromContext(context, module, prefix, line); - targetModule = new ModuleBuilder(m); - DataSchemaNode firstNode = m.getDataChildByName(qname.getLocalName()); - DataSchemaNodeBuilder firstNodeWrapped = wrapChildNode(targetModule.getModuleName(), line, firstNode, - targetModule.getPath(), firstNode.getQName()); - targetModule.addChildNode(firstNodeWrapped); - - TreeMap map = new TreeMap<>(); - map.put(targetModule.getRevision(), targetModule); - modules.put(targetModule.getModuleName(), map); - } - - return targetModule; - } - - private ModuleBuilder findTargetModule(final String prefix, final ModuleBuilder module, - final Map> modules, final SchemaContext context, final int line) { - ModuleBuilder targetModule = null; - - if (prefix == null || prefix.equals("")) { - targetModule = module; - } else { - targetModule = findModuleFromBuilders(modules, module, prefix, line); - } - - if (targetModule == null && context != null) { - Module m = findModuleFromContext(context, module, prefix, line); - if (m != null) { - targetModule = new ModuleBuilder(m); - TreeMap map = new TreeMap<>(); - map.put(targetModule.getRevision(), targetModule); - modules.put(targetModule.getModuleName(), map); - } - } - - return targetModule; - } - /** * Go through identity statements defined in current module and resolve - * their 'base' statement if present. + * their 'base' statement. * * @param modules - * all modules - * @param module - * module being resolved + * all loaded modules */ private void resolveIdentities(final Map> modules) { for (Map.Entry> entry : modules.entrySet()) { @@ -1142,67 +992,32 @@ public final class YangParserImpl implements YangContextParser { ModuleBuilder module = inner.getValue(); final Set identities = module.getAddedIdentities(); for (IdentitySchemaNodeBuilder identity : identities) { - final String baseIdentityName = identity.getBaseIdentityName(); - final int line = identity.getLine(); - if (baseIdentityName != null) { - IdentitySchemaNodeBuilder baseIdentity = findBaseIdentity(modules, module, baseIdentityName, - line); - if (baseIdentity == null) { - throw new YangParseException(module.getName(), identity.getLine(), - "Failed to find base identity"); - } else { - identity.setBaseIdentity(baseIdentity); - } - } + resolveIdentity(modules, module, identity); } - } } } - /** - * Go through identity statements defined in current module and resolve - * their 'base' statement. Method tries to find base identity in given - * modules. If base identity is not found, method will search it in context. - * - * @param modules - * all loaded modules - * @param module - * current module - * @param context - * SchemaContext containing already resolved modules - */ - private void resolveIdentitiesWithContext(final Map> modules, - final SchemaContext context) { - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - ModuleBuilder module = inner.getValue(); - final Set identities = module.getAddedIdentities(); - for (IdentitySchemaNodeBuilder identity : identities) { - final String baseIdentityName = identity.getBaseIdentityName(); - final int line = identity.getLine(); - if (baseIdentityName != null) { - - IdentitySchemaNodeBuilder result = null; - if (baseIdentityName.contains(":")) { - String[] splittedBase = baseIdentityName.split(":"); - if (splittedBase.length > 2) { - throw new YangParseException(module.getName(), line, - "Failed to parse identityref base: " + baseIdentityName); - } - String prefix = splittedBase[0]; - String name = splittedBase[1]; - ModuleBuilder dependentModule = findTargetModule(prefix, module, modules, context, line); - if (dependentModule != null) { - result = BuilderUtils.findIdentity(dependentModule.getAddedIdentities(), name); - } - } else { - result = BuilderUtils.findIdentity(module.getAddedIdentities(), baseIdentityName); - } - identity.setBaseIdentity(result); - } + private void resolveIdentity(final Map> modules, final ModuleBuilder module, + final IdentitySchemaNodeBuilder identity) { + final String baseIdentityName = identity.getBaseIdentityName(); + if (baseIdentityName != null) { + IdentitySchemaNodeBuilder result = null; + if (baseIdentityName.contains(":")) { + final int line = identity.getLine(); + String[] splittedBase = baseIdentityName.split(":"); + if (splittedBase.length > 2) { + throw new YangParseException(module.getName(), line, "Failed to parse identityref base: " + + baseIdentityName); } + String prefix = splittedBase[0]; + String name = splittedBase[1]; + ModuleBuilder dependentModule = BuilderUtils.getModuleByPrefix(module, prefix); + result = BuilderUtils.findIdentity(dependentModule.getAddedIdentities(), name); + } else { + result = BuilderUtils.findIdentity(module.getAddedIdentities(), baseIdentityName); } + identity.setBaseIdentity(result); } } @@ -1211,12 +1026,8 @@ public final class YangParserImpl implements YangContextParser { * * @param modules * all loaded modules - * @param context - * SchemaContext containing already resolved modules or null if - * context is not available */ - private void resolveUsesTargetGrouping(final Map> modules, - final SchemaContext context) { + private void resolveUsesTargetGrouping(final Map> modules) { final List allUses = new ArrayList<>(); for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry inner : entry.getValue().entrySet()) { @@ -1228,17 +1039,10 @@ public final class YangParserImpl implements YangContextParser { final GroupingBuilder targetGroupingBuilder = GroupingUtils.getTargetGroupingFromModules(usesNode, modules, module); if (targetGroupingBuilder == null) { - if (context == null) { - throw new YangParseException(module.getName(), usesNode.getLine(), "Referenced grouping '" - + usesNode.getGroupingPathAsString() + "' not found."); - } else { - GroupingDefinition targetGroupingDefinition = GroupingUtils.getTargetGroupingFromContext(usesNode, - module, context); - usesNode.setGroupingDefinition(targetGroupingDefinition); - } - } else { - usesNode.setGrouping(targetGroupingBuilder); + throw new YangParseException(module.getName(), usesNode.getLine(), "Referenced grouping '" + + usesNode.getGroupingPathAsString() + "' not found."); } + usesNode.setGrouping(targetGroupingBuilder); } } @@ -1247,11 +1051,8 @@ public final class YangParserImpl implements YangContextParser { * * @param modules * all loaded modules - * @param context - * SchemaContext containing already resolved modules */ - private void resolveUsesForGroupings(final Map> modules, - final SchemaContext context) { + private void resolveUsesForGroupings(final Map> modules) { final Set allGroupings = new HashSet<>(); for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry inner : entry.getValue().entrySet()) { @@ -1264,7 +1065,7 @@ public final class YangParserImpl implements YangContextParser { List usesNodes = new ArrayList<>(GroupingSort.getAllUsesNodes(gb)); Collections.sort(usesNodes, new GroupingUtils.UsesComparator()); for (UsesNodeBuilder usesNode : usesNodes) { - resolveUses(usesNode, modules, context); + resolveUses(usesNode, modules); } } } @@ -1274,18 +1075,15 @@ public final class YangParserImpl implements YangContextParser { * * @param modules * all loaded modules - * @param context - * SchemaContext containing already resolved modules */ - private void resolveUsesForNodes(final Map> modules, - final SchemaContext context) { + private void resolveUsesForNodes(final Map> modules) { for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry inner : entry.getValue().entrySet()) { ModuleBuilder module = inner.getValue(); List usesNodes = module.getAllUsesNodes(); Collections.sort(usesNodes, new GroupingUtils.UsesComparator()); for (UsesNodeBuilder usesNode : usesNodes) { - resolveUses(usesNode, modules, context); + resolveUses(usesNode, modules); } } } @@ -1299,11 +1097,8 @@ public final class YangParserImpl implements YangContextParser { * uses node to resolve * @param modules * all loaded modules - * @param context - * SchemaContext containing already resolved modules */ - private void resolveUses(final UsesNodeBuilder usesNode, final Map> modules, - final SchemaContext context) { + private void resolveUses(final UsesNodeBuilder usesNode, final Map> modules) { if (!usesNode.isResolved()) { DataNodeContainerBuilder parent = usesNode.getParent(); ModuleBuilder module = BuilderUtils.getParentModule(parent); @@ -1312,7 +1107,7 @@ public final class YangParserImpl implements YangContextParser { resolveUsesWithContext(usesNode); usesNode.setResolved(true); for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) { - resolveUsesAugment(augment, module, modules, context); + resolveUsesAugment(augment, module, modules); } } else { parent.getChildNodeBuilders().addAll(target.instantiateChildNodes(parent)); @@ -1321,7 +1116,7 @@ public final class YangParserImpl implements YangContextParser { parent.getUnknownNodes().addAll(target.instantiateUnknownNodes(parent)); usesNode.setResolved(true); for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) { - resolveUsesAugment(augment, module, modules, context); + resolveUsesAugment(augment, module, modules); } } GroupingUtils.performRefine(usesNode); @@ -1333,59 +1128,50 @@ public final class YangParserImpl implements YangContextParser { * * @param usesNode * uses node to resolve - * @param modules - * all loaded modules - * @param context - * SchemaContext containing already resolved modules */ private void resolveUsesWithContext(final UsesNodeBuilder usesNode) { final int line = usesNode.getLine(); DataNodeContainerBuilder parent = usesNode.getParent(); ModuleBuilder module = BuilderUtils.getParentModule(parent); SchemaPath parentPath; - URI ns = null; - Date rev = null; - String pref = null; + + final QName parentQName; if (parent instanceof AugmentationSchemaBuilder || parent instanceof ModuleBuilder) { - ns = module.getNamespace(); - rev = module.getRevision(); - pref = module.getPrefix(); + parentQName = QName.create(module.getQNameModule(), module.getPrefix(), "dummy"); if (parent instanceof AugmentationSchemaBuilder) { parentPath = ((AugmentationSchemaBuilder) parent).getTargetNodeSchemaPath(); } else { - parentPath = ((ModuleBuilder) parent).getPath(); + parentPath = parent.getPath(); } } else { - ns = ((DataSchemaNodeBuilder) parent).getQName().getNamespace(); - rev = ((DataSchemaNodeBuilder) parent).getQName().getRevision(); - pref = ((DataSchemaNodeBuilder) parent).getQName().getPrefix(); - parentPath = ((DataSchemaNodeBuilder) parent).getPath(); + parentQName = parent.getQName(); + parentPath = parent.getPath(); } GroupingDefinition gd = usesNode.getGroupingDefinition(); Set childNodes = wrapChildNodes(module.getModuleName(), line, gd.getChildNodes(), - parentPath, ns, rev, pref); + parentPath, parentQName); parent.getChildNodeBuilders().addAll(childNodes); for (DataSchemaNodeBuilder childNode : childNodes) { setNodeAddedByUses(childNode); } - Set typedefs = wrapTypedefs(module.getModuleName(), line, gd, parentPath, ns, rev, pref); + Set typedefs = wrapTypedefs(module.getModuleName(), line, gd, parentPath, parentQName); parent.getTypeDefinitionBuilders().addAll(typedefs); for (TypeDefinitionBuilder typedef : typedefs) { setNodeAddedByUses(typedef); } Set groupings = wrapGroupings(module.getModuleName(), line, usesNode.getGroupingDefinition() - .getGroupings(), parentPath, ns, rev, pref); + .getGroupings(), parentPath, parentQName); parent.getGroupingBuilders().addAll(groupings); for (GroupingBuilder gb : groupings) { setNodeAddedByUses(gb); } List unknownNodes = wrapUnknownNodes(module.getModuleName(), line, - gd.getUnknownSchemaNodes(), parentPath, ns, rev, pref); + gd.getUnknownSchemaNodes(), parentPath, parentQName); parent.getUnknownNodes().addAll(unknownNodes); for (UnknownSchemaNodeBuilder un : unknownNodes) { un.setAddedByUses(true); @@ -1393,8 +1179,8 @@ public final class YangParserImpl implements YangContextParser { } /** - * Try to find extension builder describing this unknown node and assign it - * to unknown node builder. + * Try to find extension describing this unknown node and assign it to + * unknown node builder. * * @param modules * all loaded modules @@ -1404,69 +1190,44 @@ public final class YangParserImpl implements YangContextParser { private void resolveUnknownNodes(final Map> modules, final ModuleBuilder module) { for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) { QName nodeType = usnb.getNodeType(); - try { - ModuleBuilder dependentModule = findModuleFromBuilders(modules, module, nodeType.getPrefix(), - usnb.getLine()); - for (ExtensionBuilder extension : dependentModule.getAddedExtensions()) { - if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) { - usnb.setNodeType(extension.getQName()); - usnb.setExtensionBuilder(extension); - break; - } + ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, nodeType.getPrefix()); + ExtensionBuilder extBuilder = findExtBuilder(nodeType.getLocalName(), + dependentModuleBuilder.getAddedExtensions()); + if (extBuilder == null) { + ExtensionDefinition extDef = findExtDef(nodeType.getLocalName(), dependentModuleBuilder.getExtensions()); + if (extDef == null) { + LOG.warn( + "Error in module {} at line {}: Failed to resolve node {}: no such extension definition found.", + module.getName(), usnb.getLine(), usnb); + } else { + usnb.setNodeType(new QName(extDef.getQName().getNamespace(), extDef.getQName().getRevision(), + nodeType.getPrefix(), extDef.getQName().getLocalName())); + usnb.setExtensionDefinition(extDef); } - } catch (YangParseException e) { - throw new YangParseException(module.getName(), usnb.getLine(), "Failed to resolve node " + usnb - + ": no such extension definition found.", e); + } else { + usnb.setNodeType(QName.create(extBuilder.getQName().getModule(), + nodeType.getPrefix(), extBuilder.getQName().getLocalName())); + usnb.setExtensionBuilder(extBuilder); } } } - /** - * Try to find extension builder describing this unknown node and assign it - * to unknown node builder. If extension is not found in loaded modules, try - * to find it in context. - * - * @param modules - * all loaded modules - * @param module - * current module - * @param context - * SchemaContext containing already resolved modules - */ - private void resolveUnknownNodesWithContext(final Map> modules, - final ModuleBuilder module, final SchemaContext context) { - for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) { - QName nodeType = usnb.getNodeType(); - try { - ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, nodeType.getPrefix(), - usnb.getLine()); - - if (dependentModuleBuilder == null) { - Module dependentModule = findModuleFromContext(context, module, nodeType.getPrefix(), - usnb.getLine()); - for (ExtensionDefinition e : dependentModule.getExtensionSchemaNodes()) { - if (e.getQName().getLocalName().equals(nodeType.getLocalName())) { - usnb.setNodeType(new QName(e.getQName().getNamespace(), e.getQName().getRevision(), - nodeType.getPrefix(), e.getQName().getLocalName())); - usnb.setExtensionDefinition(e); - break; - } - } - } else { - for (ExtensionBuilder extension : dependentModuleBuilder.getAddedExtensions()) { - if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) { - usnb.setExtensionBuilder(extension); - break; - } - } - } - - } catch (YangParseException e) { - throw new YangParseException(module.getName(), usnb.getLine(), "Failed to resolve node " + usnb - + ": no such extension definition found.", e); + private ExtensionBuilder findExtBuilder(final String name, final Collection extensions) { + for (ExtensionBuilder extension : extensions) { + if (extension.getQName().getLocalName().equals(name)) { + return extension; } + } + return null; + } + private ExtensionDefinition findExtDef(final String name, final Collection extensions) { + for (ExtensionDefinition extension : extensions) { + if (extension.getQName().getLocalName().equals(name)) { + return extension; + } } + return null; } /** @@ -1494,7 +1255,6 @@ public final class YangParserImpl implements YangContextParser { */ private void resolveDeviation(final Map> modules, final ModuleBuilder module) { for (DeviationBuilder dev : module.getDeviationBuilders()) { - int line = dev.getLine(); SchemaPath targetPath = dev.getTargetPath(); Iterable path = targetPath.getPathFromRoot(); QName q0 = path.iterator().next(); @@ -1503,80 +1263,11 @@ public final class YangParserImpl implements YangContextParser { prefix = module.getPrefix(); } - ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, prefix, line); + ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, prefix); processDeviation(dev, dependentModuleBuilder, path, module); } } - /** - * Traverse through modules and resolve their deviation statements with - * given context. - * - * @param modules - * all loaded modules - * @param context - * already resolved context - */ - private void resolveDeviationsWithContext(final Map> modules, - final SchemaContext context) { - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - ModuleBuilder b = inner.getValue(); - resolveDeviationWithContext(modules, b, context); - } - } - } - - /** - * Traverse through module and resolve its deviation statements with given - * context. - * - * @param modules - * all loaded modules - * @param module - * module in which resolve deviations - * @param context - * already resolved context - */ - private void resolveDeviationWithContext(final Map> modules, - final ModuleBuilder module, final SchemaContext context) { - for (DeviationBuilder dev : module.getDeviationBuilders()) { - int line = dev.getLine(); - SchemaPath targetPath = dev.getTargetPath(); - Iterable path = targetPath.getPathFromRoot(); - QName q0 = path.iterator().next(); - String prefix = q0.getPrefix(); - if (prefix == null) { - prefix = module.getPrefix(); - } - - ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, prefix, line); - if (dependentModuleBuilder == null) { - Object currentParent = findModuleFromContext(context, module, prefix, line); - - for (QName q : path) { - if (currentParent == null) { - throw new YangParseException(module.getName(), line, FAIL_DEVIATION_TARGET); - } - String name = q.getLocalName(); - if (currentParent instanceof DataNodeContainer) { - currentParent = ((DataNodeContainer) currentParent).getDataChildByName(name); - } - } - - if (currentParent == null) { - throw new YangParseException(module.getName(), line, FAIL_DEVIATION_TARGET); - } - if (currentParent instanceof SchemaNode) { - dev.setTargetPath(((SchemaNode) currentParent).getPath()); - } - - } else { - processDeviation(dev, dependentModuleBuilder, path, module); - } - } - } - /** * Correct deviation target path in deviation builder. *