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=c63a52bd218fc7d8b2fcef35138682c577d02c59;hb=6d5bc79e51c24f02fed64e976eb5b83398c9afad;hp=1a017758eb10eb7cb7473be38c93da4a735c673e;hpb=d625e657cf10d602c26374d1d6154f2d0920f8e6;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 1a017758eb..c63a52bd21 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,37 +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.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; @@ -54,14 +38,10 @@ 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.GroupingSort; import org.opendaylight.yangtools.yang.parser.util.GroupingUtils; import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort; import org.opendaylight.yangtools.yang.parser.util.ParserUtils; @@ -70,9 +50,8 @@ 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); @@ -89,121 +68,173 @@ public final class YangParserImpl implements YangModelParser { final String[] fileList = directory.list(); Preconditions.checkNotNull(fileList, directory + " not found"); - final List modules = new ArrayList<>(); + FileInputStream yangFileStream = null; + LinkedHashMap streamToFileMap = new LinkedHashMap<>(); + try { + yangFileStream = new FileInputStream(yangFile); + streamToFileMap.put(yangFileStream, yangFile); + } catch (FileNotFoundException e) { + LOG.warn("Exception while reading yang file: " + yangFile.getName(), e); + } + for (String fileName : fileList) { if (fileName.equals(yangFileName)) { continue; } - modules.add(new File(directory, fileName)); + File dependency = new File(directory, fileName); + try { + if (dependency.isFile()) { + streamToFileMap.put(new FileInputStream(dependency), dependency); + } + } catch (FileNotFoundException e) { + LOG.warn("Exception while reading yang file: " + fileName, e); + } } - modules.add(yangFile); - return parseYangModels(modules); + 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); + 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(); + List yangModelStreams = new ArrayList<>(inputStreams.keySet()); + Map builderToStreamMap = new HashMap<>(); + Map> modules = resolveModuleBuilders(yangModelStreams, + builderToStreamMap, null); - final Map> modules = resolveModuleBuilders( - Lists.newArrayList(inputStreams.keySet()), builderToStreamMap); + 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."); + final Collection unsorted = buildWithContext(modules, context).values(); + if (context != null) { + for (Module m : context.getModules()) { + if (!unsorted.contains(m)) { + unsorted.add(m); } } - - return new LinkedHashSet(buildWithContext(modules, context).values()); } - 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 @@ -211,41 +242,119 @@ public final class YangParserImpl implements YangModelParser { return new SchemaContextImpl(modules); } - private ModuleBuilder[] parseModuleBuilders(List inputStreams, + 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 List trees = parseStreams(inputStreams); - final ModuleBuilder[] builders = new ModuleBuilder[trees.size()]; + final Map trees = parseStreams(inputStreams); + final Map builders = new LinkedHashMap<>(); // validate yang - new YangModelBasicValidator(walker).validate(trees); + new YangModelBasicValidator(walker).validate(new ArrayList<>(trees.values())); YangParserListenerImpl yangModelParser; - for (int i = 0; i < trees.size(); i++) { + for (Map.Entry entry : trees.entrySet()) { yangModelParser = new YangParserListenerImpl(); - walker.walk(yangModelParser, trees.get(i)); + 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, inputStreams.get(i)); - builders[i] = moduleBuilder; + 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) { - final ModuleBuilder[] builders = parseModuleBuilders(yangFileStreams, streamToBuilderMap); + 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; + } - // LinkedHashMap must be used to preserve order - final LinkedHashMap> modules = new LinkedHashMap>(); + 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().putAll(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()]; + parsedBuilders.values().toArray(builders); // module dependency graph sorted List sorted; @@ -254,8 +363,19 @@ public final class YangParserImpl implements YangModelParser { } else { sorted = ModuleDependencySort.sortWithContext(context, builders); } + return orderModules(sorted); + } - for (final ModuleBuilder builder : sorted) { + /** + * Order modules by name and revision. + * + * @param modules + * modules to order + * @return modules ordered by name and revision + */ + private LinkedHashMap> orderModules(List modules) { + final LinkedHashMap> result = new LinkedHashMap<>(); + for (final ModuleBuilder builder : modules) { if (builder == null) { continue; } @@ -264,20 +384,57 @@ public final class YangParserImpl implements YangModelParser { if (builderRevision == null) { builderRevision = new Date(0L); } - TreeMap builderByRevision = modules.get(builderName); + TreeMap builderByRevision = result.get(builderName); if (builderByRevision == null) { - builderByRevision = new TreeMap(); + builderByRevision = new TreeMap<>(); } builderByRevision.put(builderRevision, builder); - modules.put(builderName, builderByRevision); + result.put(builderName, builderByRevision); + } + return result; + } + + private void filterImports(ModuleBuilder main, List other, List filtered) { + 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) { + if (!filtered.contains(builder)) { + filtered.add(builder); + filterImports(builder, other, filtered); + } + } else { + if (mi.getRevision().equals(builder.getRevision())) { + if (!filtered.contains(builder)) { + filtered.add(builder); + filterImports(builder, other, filtered); + } + } + } + } + } } - return modules; } - private List parseStreams(final List yangStreams) { - final List trees = new ArrayList(); + private Map parseStreams(final List yangStreams) { + final Map trees = new HashMap<>(); for (InputStream yangStream : yangStreams) { - trees.add(parseStream(yangStream)); + trees.put(yangStream, parseStream(yangStream)); } return trees; } @@ -290,8 +447,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); @@ -301,16 +474,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(); @@ -324,16 +497,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(); @@ -348,9 +521,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(); - resolveDirtyNodes(modules, module); - resolveIdentities(modules, module); resolveUnknownNodes(modules, module); + resolveIdentities(modules, module); + resolveDirtyNodes(modules, module); } } } @@ -360,9 +533,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(); - resolveDirtyNodesWithContext(modules, module, context); - resolveIdentitiesWithContext(modules, module, context); resolveUnknownNodesWithContext(modules, module, context); + resolveIdentitiesWithContext(modules, module, context); + resolveDirtyNodesWithContext(modules, module, context); } } } @@ -386,7 +559,13 @@ public final class YangParserImpl implements YangModelParser { } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) { // special handling for identityref types IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef(); - nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath())); + IdentitySchemaNodeBuilder identity = findBaseIdentity(modules, module, idref.getBaseString(), + idref.getLine()); + if (identity == null) { + throw new YangParseException(module.getName(), idref.getLine(), "Failed to find base identity"); + } + idref.setBaseIdentity(identity); + nodeToResolve.setType(idref.build()); } else { resolveType(nodeToResolve, modules, module); } @@ -405,7 +584,10 @@ public final class YangParserImpl implements YangModelParser { } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) { // special handling for identityref types IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef(); - nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath())); + IdentitySchemaNodeBuilder identity = findBaseIdentity(modules, module, idref.getBaseString(), + idref.getLine()); + idref.setBaseIdentity(identity); + nodeToResolve.setType(idref.build()); } else { resolveTypeWithContext(nodeToResolve, modules, module, context); } @@ -440,75 +622,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()); } } } @@ -534,53 +717,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 @@ -591,80 +734,117 @@ 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()])); + } + + // resolve other augments + for (ModuleBuilder mb : sorted) { + if (mb != null) { + List augments = mb.getAllAugments(); + checkAugmentMandatoryNodes(augments); + 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); - if (!resolved) { - throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Error in augment parsing: failed to find augment target"); + } + } + } } } } + 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; } /** @@ -677,38 +857,17 @@ 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(); if (baseIdentityName != null) { - String baseIdentityPrefix; - String baseIdentityLocalName; - if (baseIdentityName.contains(":")) { - final String[] splitted = baseIdentityName.split(":"); - baseIdentityPrefix = splitted[0]; - baseIdentityLocalName = splitted[1]; - } else { - baseIdentityPrefix = module.getPrefix(); - baseIdentityLocalName = baseIdentityName; - } - final ModuleBuilder dependentModule = findModuleFromBuilders(modules, module, baseIdentityPrefix, - identity.getLine()); - - IdentitySchemaNodeBuilder baseIdentity = null; - final Set dependentModuleIdentities = dependentModule.getIdentities(); - for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) { - if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) { - baseIdentity = idBuilder; - break; - } - } + IdentitySchemaNodeBuilder baseIdentity = findBaseIdentity(modules, module, baseIdentityName, line); if (baseIdentity == null) { - throw new YangParseException(module.getName(), identity.getLine(), - "Base identity " + baseIdentityName + " not found"); + throw new YangParseException(module.getName(), identity.getLine(), "Failed to find base identity"); } else { identity.setBaseIdentity(baseIdentity); } - } } } @@ -727,40 +886,18 @@ 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(); if (baseIdentityName != null) { - String baseIdentityPrefix; - String baseIdentityLocalName; - if (baseIdentityName.contains(":")) { - final String[] splitted = baseIdentityName.split(":"); - baseIdentityPrefix = splitted[0]; - baseIdentityLocalName = splitted[1]; - } else { - baseIdentityPrefix = module.getPrefix(); - baseIdentityLocalName = baseIdentityName; - } - final ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, - baseIdentityPrefix, identity.getLine()); - - if (dependentModuleBuilder == null) { - final Module dependentModule = findModuleFromContext(context, module, baseIdentityPrefix, - identity.getLine()); - final Set dependentModuleIdentities = dependentModule.getIdentities(); - for (IdentitySchemaNode idNode : dependentModuleIdentities) { - if (idNode.getQName().getLocalName().equals(baseIdentityLocalName)) { - identity.setBaseIdentity(idNode); - } - } + IdentitySchemaNodeBuilder baseIdentity = findBaseIdentity(modules, module, baseIdentityName, line); + if (baseIdentity == null) { + IdentitySchemaNode baseId = findBaseIdentityFromContext(modules, module, baseIdentityName, line, + context); + identity.setBaseIdentity(baseId); } else { - final Set dependentModuleIdentities = dependentModuleBuilder - .getIdentities(); - for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) { - if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) { - identity.setBaseIdentity(idBuilder); - } - } + identity.setBaseIdentity(baseIdentity); } } } @@ -802,74 +939,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); } } @@ -879,7 +1057,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); @@ -898,8 +1076,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(), @@ -913,7 +1091,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; @@ -953,7 +1131,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(); @@ -1000,7 +1178,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(); @@ -1009,18 +1187,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); }