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=e0510aeabd2450d593c50b80b621a6fd658ca714;hb=6e1f541302d06c8e20fa92eea87c6a7236d178e4;hp=954f6c9261018b20eeab9ecbeb27744de8b94030;hpb=14f284ccd84b286e0765678dd03222e53f9f3e5a;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 954f6c9261..e0510aeabd 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 @@ -8,7 +8,10 @@ package org.opendaylight.yangtools.yang.parser.impl; import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.*; -import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.*; +import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveType; +import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeUnion; +import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeUnionWithContext; +import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.resolveTypeWithContext; import java.io.File; import java.io.FileInputStream; @@ -16,38 +19,18 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; +import java.util.*; -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; import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.opendaylight.yangtools.antlrv4.code.gen.YangLexer; 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.model.api.DataNodeContainer; -import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; -import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; -import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; -import org.opendaylight.yangtools.yang.model.api.Module; -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.api.*; import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser; -import org.opendaylight.yangtools.yang.model.util.IdentityrefType; import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder; import org.opendaylight.yangtools.yang.parser.builder.api.Builder; import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder; @@ -55,25 +38,22 @@ 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; -import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.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.builder.impl.*; +import org.opendaylight.yangtools.yang.parser.util.Comparators; +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.NamedFileInputStream; import org.opendaylight.yangtools.yang.parser.util.ParserUtils; import org.opendaylight.yangtools.yang.parser.util.YangParseException; import org.opendaylight.yangtools.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; +import com.google.common.base.Preconditions; + public final class YangParserImpl implements YangModelParser { private static final Logger LOG = LoggerFactory.getLogger(YangParserImpl.class); @@ -92,11 +72,10 @@ public final class YangParserImpl implements YangModelParser { FileInputStream yangFileStream = null; LinkedHashMap streamToFileMap = new LinkedHashMap<>(); - 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); } @@ -109,131 +88,156 @@ 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 = parseBuilders(new ArrayList<>(streamToFileMap.keySet()), + new HashMap()); ModuleBuilder main = parsedBuilders.get(yangFileStream); List moduleBuilders = new ArrayList<>(); moduleBuilders.add(main); filterImports(main, new ArrayList<>(parsedBuilders.values()), moduleBuilders); - - ModuleBuilder[] builders = new ModuleBuilder[moduleBuilders.size()]; - moduleBuilders.toArray(builders); - - // module dependency graph sorted - List sorted = ModuleDependencySort.sort(builders); - - final LinkedHashMap> modules = orderModules(sorted); - return new LinkedHashSet<>(build(modules).values()); + Collection result = resolveSubmodules(moduleBuilders); + + // module builders sorted by dependencies + ModuleBuilder[] builders = new ModuleBuilder[result.size()]; + result.toArray(builders); + List sortedBuilders = ModuleDependencySort.sort(builders); + LinkedHashMap> modules = orderModules(sortedBuilders); + Collection unsorted = build(modules).values(); + return new LinkedHashSet<>(ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()]))); } @Override public Set parseYangModels(final List yangFiles) { - return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values()); + Collection unsorted = parseYangModelsMapped(yangFiles).values(); + return new LinkedHashSet<>(ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()]))); } @Override public Set parseYangModels(final List yangFiles, final SchemaContext context) { - if (yangFiles != null) { - final Map inputStreams = Maps.newHashMap(); - - for (final File yangFile : yangFiles) { - try { - inputStreams.put(new FileInputStream(yangFile), yangFile); - } catch (FileNotFoundException e) { - LOG.warn("Exception while reading yang file: " + yangFile.getName(), e); - } + if (yangFiles == null) { + return Collections.emptySet(); + } + + final Map inputStreams = new HashMap<>(); + for (final File yangFile : yangFiles) { + try { + inputStreams.put(new FileInputStream(yangFile), yangFile); + } catch (FileNotFoundException e) { + LOG.warn("Exception while reading yang file: " + yangFile.getName(), e); } + } - Map builderToStreamMap = Maps.newHashMap(); - final Map> modules = resolveModuleBuilders( - Lists.newArrayList(inputStreams.keySet()), builderToStreamMap); + List yangModelStreams = new ArrayList<>(inputStreams.keySet()); + Map builderToStreamMap = new HashMap<>(); + Map> modules = resolveModuleBuilders(yangModelStreams, + builderToStreamMap, null); - for (InputStream is : inputStreams.keySet()) { - try { - is.close(); - } catch (IOException e) { - LOG.debug("Failed to close stream."); - } + for (InputStream is : inputStreams.keySet()) { + try { + is.close(); + } catch (IOException e) { + LOG.debug("Failed to close stream."); } + } - return new LinkedHashSet(buildWithContext(modules, context).values()); + final Collection unsorted = buildWithContext(modules, context).values(); + if (context != null) { + for (Module m : context.getModules()) { + if (!unsorted.contains(m)) { + unsorted.add(m); + } + } } - return Collections.emptySet(); + return new LinkedHashSet<>(ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()]))); } @Override public Set parseYangModelsFromStreams(final List yangModelStreams) { - return Sets.newHashSet(parseYangModelsFromStreamsMapped(yangModelStreams).values()); + Collection unsorted = parseYangModelsFromStreamsMapped(yangModelStreams).values(); + return new LinkedHashSet<>(ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()]))); } @Override public Set parseYangModelsFromStreams(final List yangModelStreams, SchemaContext context) { - if (yangModelStreams != null) { - Map builderToStreamMap = Maps.newHashMap(); - final Map> modules = resolveModuleBuildersWithContext( - yangModelStreams, builderToStreamMap, context); - return new LinkedHashSet(buildWithContext(modules, context).values()); + if (yangModelStreams == null) { + return Collections.emptySet(); } - return Collections.emptySet(); - } - @Override - public Map parseYangModelsMapped(List yangFiles) { - if (yangFiles != null) { - final Map inputStreams = Maps.newHashMap(); - - for (final File yangFile : yangFiles) { - try { - inputStreams.put(new FileInputStream(yangFile), yangFile); - } catch (FileNotFoundException e) { - LOG.warn("Exception while reading yang file: " + yangFile.getName(), e); + final Map builderToStreamMap = new HashMap<>(); + final Map> modules = resolveModuleBuilders(yangModelStreams, + builderToStreamMap, context); + final Set unsorted = new LinkedHashSet<>(buildWithContext(modules, context).values()); + if (context != null) { + for (Module m : context.getModules()) { + if (!unsorted.contains(m)) { + unsorted.add(m); } } + } + return new LinkedHashSet<>(ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()]))); + } - Map builderToStreamMap = Maps.newHashMap(); - final Map> modules = resolveModuleBuilders( - Lists.newArrayList(inputStreams.keySet()), builderToStreamMap); + @Override + public Map parseYangModelsMapped(List yangFiles) { + if (yangFiles == null) { + return Collections.emptyMap(); + } - for (InputStream is : inputStreams.keySet()) { - try { - is.close(); - } catch (IOException e) { - LOG.debug("Failed to close stream."); - } + final Map inputStreams = new HashMap<>(); + for (final File yangFile : yangFiles) { + try { + + inputStreams.put(new FileInputStream(yangFile), yangFile); + } catch (FileNotFoundException e) { + LOG.warn("Exception while reading yang file: " + yangFile.getName(), e); } + } - Map retVal = Maps.newLinkedHashMap(); - Map builderToModuleMap = build(modules); + List yangModelStreams = new ArrayList<>(inputStreams.keySet()); + Map builderToStreamMap = new HashMap<>(); + Map> modules = resolveModuleBuilders(yangModelStreams, builderToStreamMap, + null); - for (Entry builderToModule : builderToModuleMap.entrySet()) { - retVal.put(inputStreams.get(builderToStreamMap.get(builderToModule.getKey())), - builderToModule.getValue()); + for (InputStream is : inputStreams.keySet()) { + try { + is.close(); + } catch (IOException e) { + LOG.debug("Failed to close stream."); } + } - return retVal; + Map result = new LinkedHashMap<>(); + Map builderToModuleMap = build(modules); + Set keyset = builderToModuleMap.keySet(); + List sorted = ModuleDependencySort.sort(keyset.toArray(new ModuleBuilder[keyset.size()])); + for (ModuleBuilder key : sorted) { + result.put(inputStreams.get(builderToStreamMap.get(key)), builderToModuleMap.get(key)); } - return Collections.emptyMap(); + return result; } @Override public Map parseYangModelsFromStreamsMapped(final List yangModelStreams) { - Map builderToStreamMap = Maps.newHashMap(); + if (yangModelStreams == null) { + return Collections.emptyMap(); + } - final Map> modules = resolveModuleBuilders(yangModelStreams, - builderToStreamMap); - Map retVal = Maps.newLinkedHashMap(); + Map builderToStreamMap = new HashMap<>(); + Map> modules = resolveModuleBuilders(yangModelStreams, builderToStreamMap, + null); + Map result = new LinkedHashMap<>(); Map builderToModuleMap = build(modules); - - for (Entry builderToModule : builderToModuleMap.entrySet()) { - retVal.put(builderToStreamMap.get(builderToModule.getKey()), builderToModule.getValue()); + Set keyset = builderToModuleMap.keySet(); + List sorted = ModuleDependencySort.sort(keyset.toArray(new ModuleBuilder[keyset.size()])); + for (ModuleBuilder key : sorted) { + result.put(builderToStreamMap.get(key), builderToModuleMap.get(key)); } - return retVal; + return result; } @Override @@ -243,39 +247,123 @@ public final class YangParserImpl implements YangModelParser { private Map parseModuleBuilders(List inputStreams, Map streamToBuilderMap) { + Map modules = parseBuilders(inputStreams, streamToBuilderMap); + Map result = resolveSubmodules(modules); + return result; + } + private Map parseBuilders(List inputStreams, + Map streamToBuilderMap) { final ParseTreeWalker walker = new ParseTreeWalker(); final Map trees = parseStreams(inputStreams); final Map builders = new LinkedHashMap<>(); // validate yang - new YangModelBasicValidator(walker).validate(new ArrayList(trees.values())); + new YangModelBasicValidator(walker).validate(new ArrayList<>(trees.values())); YangParserListenerImpl yangModelParser; - for(Map.Entry entry : trees.entrySet()) { - yangModelParser = new YangParserListenerImpl(); + for (Map.Entry entry : trees.entrySet()) { + InputStream is = entry.getKey(); + String path = null; + if (is instanceof NamedFileInputStream) { + NamedFileInputStream nis = (NamedFileInputStream)is; + path = nis.getFileDestination(); + } + yangModelParser = new YangParserListenerImpl(path); walker.walk(yangModelParser, entry.getValue()); ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder(); // We expect the order of trees and streams has to be the same streamToBuilderMap.put(moduleBuilder, entry.getKey()); + builders.put(entry.getKey(), moduleBuilder); } return builders; } - private Map> resolveModuleBuilders(final List yangFileStreams, - Map streamToBuilderMap) { - return resolveModuleBuildersWithContext(yangFileStreams, streamToBuilderMap, null); + private Map resolveSubmodules(Map builders) { + Map modules = new HashMap<>(); + Set submodules = new HashSet<>(); + for (Map.Entry entry : builders.entrySet()) { + ModuleBuilder moduleBuilder = entry.getValue(); + if (moduleBuilder.isSubmodule()) { + submodules.add(moduleBuilder); + } else { + modules.put(entry.getKey(), moduleBuilder); + } + } + + Collection values = modules.values(); + for (ModuleBuilder submodule : submodules) { + for (ModuleBuilder module : values) { + if (module.getName().equals(submodule.getBelongsTo())) { + addSubmoduleToModule(submodule, module); + } + } + } + return modules; } - private Map> resolveModuleBuildersWithContext( - final List yangFileStreams, final Map streamToBuilderMap, - final SchemaContext context) { + private Collection resolveSubmodules(Collection builders) { + Collection modules = new HashSet<>(); + Set submodules = new HashSet<>(); + for (ModuleBuilder moduleBuilder : builders) { + if (moduleBuilder.isSubmodule()) { + submodules.add(moduleBuilder); + } else { + modules.add(moduleBuilder); + } + } + + for (ModuleBuilder submodule : submodules) { + for (ModuleBuilder module : modules) { + if (module.getName().equals(submodule.getBelongsTo())) { + addSubmoduleToModule(submodule, module); + } + } + } + return modules; + } + + private void addSubmoduleToModule(ModuleBuilder submodule, ModuleBuilder module) { + submodule.setParent(module); + module.getDirtyNodes().addAll(submodule.getDirtyNodes()); + module.getModuleImports().addAll(submodule.getModuleImports()); + module.getAugments().addAll(submodule.getAugments()); + module.getAugmentBuilders().addAll(submodule.getAugmentBuilders()); + module.getAllAugments().addAll(submodule.getAllAugments()); + module.getChildNodeBuilders().addAll(submodule.getChildNodeBuilders()); + module.getChildNodes().addAll(submodule.getChildNodes()); + module.getGroupings().addAll(submodule.getGroupings()); + module.getGroupingBuilders().addAll(submodule.getGroupingBuilders()); + module.getTypeDefinitions().addAll(submodule.getTypeDefinitions()); + module.getTypeDefinitionBuilders().addAll(submodule.getTypeDefinitionBuilders()); + module.getUsesNodes().addAll(submodule.getUsesNodes()); + module.getUsesNodeBuilders().addAll(submodule.getUsesNodeBuilders()); + module.getAllGroupings().addAll(submodule.getAllGroupings()); + module.getAllUsesNodes().addAll(submodule.getAllUsesNodes()); + module.getRpcs().addAll(submodule.getRpcs()); + module.getAddedRpcs().addAll(submodule.getAddedRpcs()); + module.getNotifications().addAll(submodule.getNotifications()); + module.getAddedNotifications().addAll(submodule.getAddedNotifications()); + module.getIdentities().addAll(submodule.getIdentities()); + module.getAddedIdentities().addAll(submodule.getAddedIdentities()); + module.getFeatures().addAll(submodule.getFeatures()); + module.getAddedFeatures().addAll(submodule.getAddedFeatures()); + module.getDeviations().addAll(submodule.getDeviations()); + module.getDeviationBuilders().addAll(submodule.getDeviationBuilders()); + module.getExtensions().addAll(submodule.getExtensions()); + module.getAddedExtensions().addAll(submodule.getAddedExtensions()); + module.getUnknownNodes().addAll(submodule.getUnknownNodes()); + module.getAllUnknownNodes().addAll(submodule.getAllUnknownNodes()); + } + + private Map> resolveModuleBuilders(final List yangFileStreams, + final Map streamToBuilderMap, final SchemaContext context) { Map parsedBuilders = parseModuleBuilders(yangFileStreams, streamToBuilderMap); ModuleBuilder[] builders = new ModuleBuilder[parsedBuilders.size()]; - final ModuleBuilder[] moduleBuilders = new ArrayList<>(parsedBuilders.values()).toArray(builders); + parsedBuilders.values().toArray(builders); // module dependency graph sorted List sorted; @@ -284,7 +372,6 @@ public final class YangParserImpl implements YangModelParser { } else { sorted = ModuleDependencySort.sortWithContext(context, builders); } - return orderModules(sorted); } @@ -296,8 +383,7 @@ public final class YangParserImpl implements YangModelParser { * @return modules ordered by name and revision */ private LinkedHashMap> orderModules(List modules) { - // LinkedHashMap must be used to preserve order - LinkedHashMap> result = new LinkedHashMap<>(); + final LinkedHashMap> result = new LinkedHashMap<>(); for (final ModuleBuilder builder : modules) { if (builder == null) { continue; @@ -309,7 +395,7 @@ public final class YangParserImpl implements YangModelParser { } TreeMap builderByRevision = result.get(builderName); if (builderByRevision == null) { - builderByRevision = new TreeMap(); + builderByRevision = new TreeMap<>(); } builderByRevision.put(builderRevision, builder); result.put(builderName, builderByRevision); @@ -318,7 +404,22 @@ public final class YangParserImpl implements YangModelParser { } private void filterImports(ModuleBuilder main, List other, List filtered) { - for (ModuleImport mi : main.getModuleImports()) { + Set imports = main.getModuleImports(); + + // if this is submodule, add parent to filtered and pick its imports + if (main.isSubmodule()) { + TreeMap dependencies = new TreeMap<>(); + for (ModuleBuilder mb : other) { + if (mb.getName().equals(main.getBelongsTo())) { + dependencies.put(mb.getRevision(), mb); + } + } + ModuleBuilder parent = dependencies.get(dependencies.firstKey()); + filtered.add(parent); + imports.addAll(parent.getModuleImports()); + } + + for (ModuleImport mi : imports) { for (ModuleBuilder builder : other) { if (mi.getModuleName().equals(builder.getModuleName())) { if (mi.getRevision() == null) { @@ -355,8 +456,24 @@ 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); + } + return result; + } + public static YangContext parseStreamWithoutErrorListeners(final InputStream yangStream) { + YangContext result = null; + try { + final ANTLRInputStream input = new ANTLRInputStream(yangStream); + final YangLexer lexer = new YangLexer(input); + final CommonTokenStream tokens = new CommonTokenStream(lexer); + final YangParser parser = new YangParser(tokens); + parser.removeErrorListeners(); result = parser.yang(); } catch (IOException e) { LOG.warn("Exception while reading yang file: " + yangStream, e); @@ -366,16 +483,16 @@ 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); - resolveAugments(modules); - resolveUses(modules, false); - resolvedUsesPostProcessing(modules, false); + resolveUsesForGroupings(modules, null); + resolveUsesForNodes(modules, null); + resolveAugments(modules, null); resolveDeviations(modules); // build - final Map result = new LinkedHashMap(); + final Map result = new LinkedHashMap<>(); for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry childEntry : entry.getValue().entrySet()) { final ModuleBuilder moduleBuilder = childEntry.getValue(); @@ -389,16 +506,16 @@ 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); - resolveAugmentsWithContext(modules, context); - resolveUses(modules, true); - resolvedUsesPostProcessing(modules, true); + resolveUsesForGroupings(modules, context); + resolveUsesForNodes(modules, context); + resolveAugments(modules, context); resolveDeviationsWithContext(modules, context); // build - final Map result = new LinkedHashMap(); + final Map result = new LinkedHashMap<>(); for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry childEntry : entry.getValue().entrySet()) { final ModuleBuilder moduleBuilder = childEntry.getValue(); @@ -413,9 +530,9 @@ public final class YangParserImpl implements YangModelParser { for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry childEntry : entry.getValue().entrySet()) { final ModuleBuilder module = childEntry.getValue(); + resolveUnknownNodes(modules, module); resolveIdentities(modules, module); resolveDirtyNodes(modules, module); - resolveUnknownNodes(modules, module); } } } @@ -425,9 +542,9 @@ public final class YangParserImpl implements YangModelParser { for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry childEntry : entry.getValue().entrySet()) { final ModuleBuilder module = childEntry.getValue(); + resolveUnknownNodesWithContext(modules, module, context); resolveIdentitiesWithContext(modules, module, context); resolveDirtyNodesWithContext(modules, module, context); - resolveUnknownNodesWithContext(modules, module, context); } } } @@ -514,75 +631,76 @@ 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())); - } - /** - * Go through all augment definitions and perform augmentation. It is - * expected that modules are already sorted by their dependencies. - * - * @param modules - * all loaded modules - */ - private void resolveAugments(final Map> modules) { - // collect augments from all loaded modules - final List allAugments = new ArrayList<>(); - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - allAugments.addAll(inner.getValue().getAllAugments()); - } + for (DataSchemaNodeBuilder childNode : augment.getChildNodeBuilders()) { + correctPathForAugmentNodes(childNode, augment.getTargetNodeSchemaPath()); } + } - checkAugmentMandatoryNodes(allAugments); - - for (int i = 0; i < allAugments.size(); i++) { - // pick one augment - final AugmentationSchemaBuilder augment = allAugments.get(i); - // create collection of others - List others = new ArrayList<>(allAugments); - others.remove(augment); - - // try to resolve it - boolean resolved = resolveAugment(modules, augment); - // while not resolved - int j = 0; - while (!(resolved) && j < others.size()) { - // try to resolve next augment - resolveAugment(modules, others.get(j)); - // then try to resolve first again - resolved = resolveAugment(modules, augment); - j++; - + private void correctPathForAugmentNodes(DataSchemaNodeBuilder node, SchemaPath parentPath) { + SchemaPath newPath = ParserUtils.createSchemaPath(parentPath, node.getQName()); + node.setPath(newPath); + if (node instanceof DataNodeContainerBuilder) { + for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) node).getChildNodeBuilders()) { + correctPathForAugmentNodes(child, node.getPath()); } - - if (!resolved) { - throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Error in augment parsing: failed to find augment target"); + } + if (node instanceof ChoiceBuilder) { + for (ChoiceCaseBuilder child : ((ChoiceBuilder)node).getCases()) { + correctPathForAugmentNodes(child, node.getPath()); } } } @@ -608,53 +726,13 @@ 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()); } } } } - /** - * Search for augment target and perform augmentation. - * - * @param modules - * all loaded modules - * @param augment - * augment to resolve - * @return true if target node found, false otherwise - */ - private boolean resolveAugment(final Map> modules, - final AugmentationSchemaBuilder augment) { - if (augment.isResolved()) { - return true; - } - - int line = augment.getLine(); - ModuleBuilder module = getParentModule(augment); - List path = augment.getTargetPath().getPath(); - Builder augmentParent = augment.getParent(); - - Builder firstNodeParent; - if (augmentParent instanceof ModuleBuilder) { - // if augment is defined under module, parent of first node is - // target module - final QName firstNameInPath = path.get(0); - String prefix = firstNameInPath.getPrefix(); - if (prefix == null) { - prefix = module.getPrefix(); - } - firstNodeParent = findModuleFromBuilders(modules, module, prefix, line); - } else if (augmentParent instanceof UsesNodeBuilder) { - firstNodeParent = augmentParent.getParent(); - } else { - // augment can be defined only under module or uses - throw new YangParseException(augment.getModuleName(), line, - "Failed to parse augment: Unresolved parent of augment: " + augmentParent); - } - - return processAugmentation(augment, firstNodeParent, path); - } - /** * Go through all augment definitions and resolve them. This method works in * same way as {@link #resolveAugments(Map)} except that if target node is @@ -665,80 +743,116 @@ public final class YangParserImpl implements YangModelParser { * @param context * SchemaContext containing already resolved modules */ - private void resolveAugmentsWithContext(final Map> modules, - final SchemaContext context) { - // collect augments from all loaded modules - final List allAugments = new ArrayList<>(); + private void resolveAugments(final Map> modules, final SchemaContext context) { + List all = new ArrayList<>(); for (Map.Entry> entry : modules.entrySet()) { for (Map.Entry inner : entry.getValue().entrySet()) { - allAugments.addAll(inner.getValue().getAllAugments()); + all.add(inner.getValue()); } } - for (int i = 0; i < allAugments.size(); i++) { - // pick augment from list - final AugmentationSchemaBuilder augment = allAugments.get(i); - // try to resolve it - boolean resolved = resolveAugmentWithContext(modules, augment, context); - // while not resolved - int j = i + 1; - while (!(resolved) && j < allAugments.size()) { - // try to resolve next augment - resolveAugmentWithContext(modules, allAugments.get(j), context); - // then try to resolve first again - resolved = resolveAugmentWithContext(modules, augment, context); - j++; - } + 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()])); + } - if (!resolved) { - throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Error in augment parsing: failed to find augment target"); + for (ModuleBuilder mb : sorted) { + if (mb != null) { + List augments = mb.getAllAugments(); + checkAugmentMandatoryNodes(augments); + Collections.sort(augments, Comparators.AUGMENT_COMP); + for (AugmentationSchemaBuilder augment : augments) { + if (!(augment.isResolved())) { + boolean resolved = resolveAugment(augment, mb, modules, context); + if (!resolved) { + throw new YangParseException(augment.getModuleName(), augment.getLine(), + "Error in augment parsing: failed to find augment target: " + augment); + } + } + } } } } + private boolean resolveUsesAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module, + final Map> modules, final SchemaContext context) { + if (augment.isResolved()) { + return true; + } + + UsesNodeBuilder usesNode = (UsesNodeBuilder) augment.getParent(); + DataNodeContainerBuilder parentNode = usesNode.getParent(); + SchemaNodeBuilder targetNode; + if (parentNode instanceof ModuleBuilder) { + targetNode = findSchemaNodeInModule(augment.getTargetPath().getPath(), (ModuleBuilder)parentNode); + } else { + targetNode = findSchemaNode(augment.getTargetPath().getPath(), (SchemaNodeBuilder)parentNode); + } + + fillAugmentTarget(augment, targetNode); + augment.setResolved(true); + return true; + } + + private boolean resolveAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module, + final Map> modules, final SchemaContext context) { + if (augment.isResolved()) { + return true; + } + + List targetPath = augment.getTargetPath().getPath(); + ModuleBuilder targetModule = findTargetModule(targetPath.get(0), module, modules, context, augment.getLine()); + if (targetModule == null) { + throw new YangParseException(module.getModuleName(), augment.getLine(), "Failed to resolve augment " + + augment); + } + + return processAugmentation(augment, targetModule); + } + /** - * Search for augment target and perform augmentation. + * 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 augment - * augment to resolve * @param context - * SchemaContext containing already resolved modules - * @return true if target node found, false otherwise + * schema context + * @param line + * current line + * @return */ - private boolean resolveAugmentWithContext(final Map> modules, - final AugmentationSchemaBuilder augment, final SchemaContext context) { - if (augment.isResolved()) { - return true; - } - int line = augment.getLine(); - ModuleBuilder module = getParentModule(augment); - List path = augment.getTargetNodeSchemaPath().getPath(); - final QName firstNameInPath = path.get(0); - String prefix = firstNameInPath.getPrefix(); - if (prefix == null) { - prefix = module.getPrefix(); - } - Builder augmentParent = augment.getParent(); - Builder currentParent; - if (augmentParent instanceof ModuleBuilder) { - // if augment is defined under module, first parent is target module - currentParent = findModuleFromBuilders(modules, module, prefix, line); - } else if (augmentParent instanceof UsesNodeBuilder) { - currentParent = augmentParent.getParent(); + 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 { - // augment can be defined only under module or uses - throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Error in augment parsing: Unresolved parent of augment: " + augmentParent); + targetModule = findModuleFromBuilders(modules, module, qname.getPrefix(), line); } - if (currentParent == null) { - return processAugmentationOnContext(augment, path, module, prefix, context); - } else { - return processAugmentation(augment, currentParent, path); + 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; } /** @@ -751,7 +865,7 @@ public final class YangParserImpl implements YangModelParser { * module being resolved */ private void resolveIdentities(final Map> modules, final ModuleBuilder module) { - final Set identities = module.getIdentities(); + final Set identities = module.getAddedIdentities(); for (IdentitySchemaNodeBuilder identity : identities) { final String baseIdentityName = identity.getBaseIdentityName(); final int line = identity.getLine(); @@ -761,8 +875,6 @@ public final class YangParserImpl implements YangModelParser { throw new YangParseException(module.getName(), identity.getLine(), "Failed to find base identity"); } else { identity.setBaseIdentity(baseIdentity); - IdentitySchemaNode built = identity.build(); - baseIdentity.addDerivedIdentity(built); } } } @@ -782,7 +894,7 @@ public final class YangParserImpl implements YangModelParser { */ private void resolveIdentitiesWithContext(final Map> modules, final ModuleBuilder module, final SchemaContext context) { - final Set identities = module.getIdentities(); + final Set identities = module.getAddedIdentities(); for (IdentitySchemaNodeBuilder identity : identities) { final String baseIdentityName = identity.getBaseIdentityName(); final int line = identity.getLine(); @@ -792,15 +904,8 @@ public final class YangParserImpl implements YangModelParser { IdentitySchemaNode baseId = findBaseIdentityFromContext(modules, module, baseIdentityName, line, context); identity.setBaseIdentity(baseId); - IdentitySchemaNode built = identity.build(); - if (baseId instanceof IdentitySchemaNodeBuilder.IdentitySchemaNodeImpl) { - ((IdentitySchemaNodeBuilder.IdentitySchemaNodeImpl) baseId).toBuilder().addDerivedIdentity( - built); - } } else { identity.setBaseIdentity(baseIdentity); - IdentitySchemaNode built = identity.build(); - baseIdentity.addDerivedIdentity(built); } } } @@ -842,74 +947,115 @@ 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); + private void resolveUses(UsesNodeBuilder usesNode, + final Map> modules, final SchemaContext context) { + if (!usesNode.isResolved()) { + DataNodeContainerBuilder parent = usesNode.getParent(); + ModuleBuilder module = ParserUtils.getParentModule(parent); + GroupingBuilder target = GroupingUtils.getTargetGroupingFromModules(usesNode, modules, module); + if (target == null) { + resolveUsesWithContext(usesNode); + usesNode.setResolved(true); + for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) { + resolveUsesAugment(augment, module, modules, context); + } + } else { + parent.getChildNodeBuilders().addAll(target.instantiateChildNodes(parent)); + parent.getTypeDefinitionBuilders().addAll(target.instantiateTypedefs(parent)); + parent.getGroupingBuilders().addAll(target.instantiateGroupings(parent)); + parent.getUnknownNodes().addAll(target.instantiateUnknownNodes(parent)); + usesNode.setResolved(true); + for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) { + resolveUsesAugment(augment, module, modules, context); + } + } GroupingUtils.performRefine(usesNode); } + } - if (!resolveWithContext) { - for (UsesNodeBuilder usesNode : allModulesUses) { - if (usesNode.isCopy()) { - usesNode.getParent().getUsesNodes().remove(usesNode); - } + private void resolveUsesWithContext(UsesNodeBuilder usesNode) { + final int line = usesNode.getLine(); + DataNodeContainerBuilder parent = usesNode.getParent(); + ModuleBuilder module = ParserUtils.getParentModule(parent); + SchemaPath parentPath; + URI ns = null; + Date rev = null; + String pref = null; + if (parent instanceof AugmentationSchemaBuilder || parent instanceof ModuleBuilder) { + ns = module.getNamespace(); + rev = module.getRevision(); + pref = module.getPrefix(); + if (parent instanceof AugmentationSchemaBuilder) { + parentPath = ((AugmentationSchemaBuilder)parent).getTargetNodeSchemaPath(); + } else { + parentPath = ((ModuleBuilder)parent).getPath(); } + } else { + ns = ((DataSchemaNodeBuilder) parent).getQName().getNamespace(); + rev = ((DataSchemaNodeBuilder) parent).getQName().getRevision(); + pref = ((DataSchemaNodeBuilder) parent).getQName().getPrefix(); + parentPath = ((DataSchemaNodeBuilder)parent).getPath(); + } + + GroupingDefinition gd = usesNode.getGroupingDefinition(); + + Set childNodes = wrapChildNodes(module.getModuleName(), line, + gd.getChildNodes(), parentPath, ns, rev, pref); + parent.getChildNodeBuilders().addAll(childNodes); + for (DataSchemaNodeBuilder childNode : childNodes) { + setNodeAddedByUses(childNode); + } + + Set typedefs = wrapTypedefs(module.getModuleName(), line, gd, parentPath, ns, + rev, pref); + parent.getTypeDefinitionBuilders().addAll(typedefs); + for (TypeDefinitionBuilder typedef : typedefs) { + setNodeAddedByUses(typedef); + } + + Set groupings = wrapGroupings(module.getModuleName(), line, usesNode + .getGroupingDefinition().getGroupings(), parentPath, ns, rev, pref); + parent.getGroupingBuilders().addAll(groupings); + for (GroupingBuilder gb : groupings) { + setNodeAddedByUses(gb); + } + + List unknownNodes = wrapUnknownNodes(module.getModuleName(), line, + gd.getUnknownSchemaNodes(), parentPath, ns, rev, pref); + parent.getUnknownNodes().addAll(unknownNodes); + for (UnknownSchemaNodeBuilder un : unknownNodes) { + un.setAddedByUses(true); } } @@ -919,7 +1065,7 @@ public final class YangParserImpl implements YangModelParser { try { ModuleBuilder dependentModule = findModuleFromBuilders(modules, module, nodeType.getPrefix(), usnb.getLine()); - for (ExtensionBuilder extension : dependentModule.getExtensions()) { + for (ExtensionBuilder extension : dependentModule.getAddedExtensions()) { if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) { usnb.setNodeType(extension.getQName()); usnb.setExtensionBuilder(extension); @@ -938,8 +1084,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(), @@ -953,7 +1099,7 @@ public final class YangParserImpl implements YangModelParser { } } } else { - for (ExtensionBuilder extension : dependentModuleBuilder.getExtensions()) { + for (ExtensionBuilder extension : dependentModuleBuilder.getAddedExtensions()) { if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) { usnb.setExtensionBuilder(extension); break; @@ -993,7 +1139,7 @@ public final class YangParserImpl implements YangModelParser { * module in which resolve deviations */ private void resolveDeviation(final Map> modules, final ModuleBuilder module) { - for (DeviationBuilder dev : module.getDeviations()) { + for (DeviationBuilder dev : module.getDeviationBuilders()) { int line = dev.getLine(); SchemaPath targetPath = dev.getTargetPath(); List path = targetPath.getPath(); @@ -1040,7 +1186,7 @@ public final class YangParserImpl implements YangModelParser { */ private void resolveDeviationWithContext(final Map> modules, final ModuleBuilder module, final SchemaContext context) { - for (DeviationBuilder dev : module.getDeviations()) { + for (DeviationBuilder dev : module.getDeviationBuilders()) { int line = dev.getLine(); SchemaPath targetPath = dev.getTargetPath(); List path = targetPath.getPath(); @@ -1049,18 +1195,16 @@ public final class YangParserImpl implements YangModelParser { if (prefix == null) { prefix = module.getPrefix(); } - String name = null; ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, prefix, line); if (dependentModuleBuilder == null) { - Module dependentModule = findModuleFromContext(context, module, prefix, line); - Object currentParent = dependentModule; + Object currentParent = findModuleFromContext(context, module, prefix, line); for (QName q : path) { if (currentParent == null) { throw new YangParseException(module.getName(), line, FAIL_DEVIATION_TARGET); } - name = q.getLocalName(); + String name = q.getLocalName(); if (currentParent instanceof DataNodeContainer) { currentParent = ((DataNodeContainer) currentParent).getDataChildByName(name); }