import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
-import com.google.common.base.Preconditions;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
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;
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.ModuleBuilder;
import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.util.GroupingSort;
import org.opendaylight.yangtools.yang.parser.util.GroupingUtils;
import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
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);
}
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<InputStream, ModuleBuilder> parsedBuilders = parseModuleBuilders(
- new ArrayList<>(streamToFileMap.keySet()), new HashMap<ModuleBuilder, InputStream>());
+ Map<InputStream, ModuleBuilder> parsedBuilders = parseModuleBuilders(new ArrayList<>(streamToFileMap.keySet()),
+ new HashMap<ModuleBuilder, InputStream>());
ModuleBuilder main = parsedBuilders.get(yangFileStream);
List<ModuleBuilder> moduleBuilders = new ArrayList<>();
}
}
- return new LinkedHashSet<Module>(buildWithContext(modules, context).values());
+ return new LinkedHashSet<>(buildWithContext(modules, context).values());
}
return Collections.emptySet();
}
Map<ModuleBuilder, InputStream> builderToStreamMap = Maps.newHashMap();
final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersWithContext(
yangModelStreams, builderToStreamMap, context);
- return new LinkedHashSet<Module>(buildWithContext(modules, context).values());
+ return new LinkedHashSet<>(buildWithContext(modules, context).values());
}
return Collections.emptySet();
}
final Map<InputStream, ModuleBuilder> builders = new LinkedHashMap<>();
// validate yang
- new YangModelBasicValidator(walker).validate(new ArrayList<ParseTree>(trees.values()));
+ new YangModelBasicValidator(walker).validate(new ArrayList<>(trees.values()));
YangParserListenerImpl yangModelParser;
- for(Map.Entry<InputStream, ParseTree> entry : trees.entrySet()) {
+ for (Map.Entry<InputStream, ParseTree> entry : trees.entrySet()) {
yangModelParser = new YangParserListenerImpl();
walker.walk(yangModelParser, entry.getValue());
ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder();
final SchemaContext context) {
Map<InputStream, ModuleBuilder> 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<ModuleBuilder> sorted;
}
TreeMap<Date, ModuleBuilder> builderByRevision = result.get(builderName);
if (builderByRevision == null) {
- builderByRevision = new TreeMap<Date, ModuleBuilder>();
+ builderByRevision = new TreeMap<>();
}
builderByRevision.put(builderRevision, builder);
result.put(builderName, builderByRevision);
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);
}
private Map<ModuleBuilder, Module> build(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
// fix unresolved nodes
+ resolveDirtyNodes(modules);
resolveAugmentsTargetPath(modules, null);
resolveUsesTargetGrouping(modules, null);
- resolveDirtyNodes(modules);
+ resolveUsesForGroupings(modules, null);
+ resolveUsesForNodes(modules, null);
resolveAugments(modules);
- resolveUses(modules, false);
- resolvedUsesPostProcessing(modules, false);
resolveDeviations(modules);
// build
- final Map<ModuleBuilder, Module> result = new LinkedHashMap<ModuleBuilder, Module>();
+ final Map<ModuleBuilder, Module> result = new LinkedHashMap<>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
final ModuleBuilder moduleBuilder = childEntry.getValue();
private Map<ModuleBuilder, Module> buildWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
final SchemaContext context) {
// fix unresolved nodes
+ resolvedDirtyNodesWithContext(modules, context);
resolveAugmentsTargetPath(modules, context);
resolveUsesTargetGrouping(modules, context);
- resolvedDirtyNodesWithContext(modules, context);
+ resolveUsesForGroupings(modules, context);
+ resolveUsesForNodes(modules, context);
resolveAugmentsWithContext(modules, context);
- resolveUses(modules, true);
- resolvedUsesPostProcessing(modules, true);
resolveDeviationsWithContext(modules, context);
// build
- final Map<ModuleBuilder, Module> result = new LinkedHashMap<ModuleBuilder, Module>();
+ final Map<ModuleBuilder, Module> result = new LinkedHashMap<>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
final ModuleBuilder moduleBuilder = childEntry.getValue();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
final ModuleBuilder module = childEntry.getValue();
+ resolveUnknownNodes(modules, module);
resolveIdentities(modules, module);
resolveDirtyNodes(modules, module);
- resolveUnknownNodes(modules, module);
}
}
}
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> 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);
}
}
}
throw new YangParseException(module.getName(), idref.getLine(), "Failed to find base identity");
}
idref.setBaseIdentity(identity);
- nodeToResolve.setType(idref.build());
+ nodeToResolve.setType(idref.build(null));
} else {
resolveType(nodeToResolve, modules, module);
}
IdentitySchemaNodeBuilder identity = findBaseIdentity(modules, module, idref.getBaseString(),
idref.getLine());
idref.setBaseIdentity(identity);
- nodeToResolve.setType(idref.build());
+ nodeToResolve.setType(idref.build(null));
} else {
resolveTypeWithContext(nodeToResolve, modules, module, context);
}
SchemaPath oldSchemaPath = augment.getTargetPath();
List<QName> oldPath = oldSchemaPath.getPath();
List<QName> newPath = new ArrayList<>();
- for (QName qn : oldPath) {
- URI ns = module.getNamespace();
- Date rev = module.getRevision();
- String pref = module.getPrefix();
- String localPrefix = qn.getPrefix();
- if (localPrefix != null && !("".equals(localPrefix))) {
- ModuleBuilder currentModule = ParserUtils.findModuleFromBuilders(modules, module, localPrefix,
- augment.getLine());
- if (currentModule == null) {
- Module m = ParserUtils.findModuleFromContext(context, module, localPrefix, augment.getLine());
- if (m == null) {
- throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix "
- + localPrefix + " not found.");
+
+ Builder parent = augment.getParent();
+ if (parent instanceof UsesNodeBuilder) {
+ DataNodeContainerBuilder usesParent = ((UsesNodeBuilder) parent).getParent();
+ newPath.addAll(usesParent.getPath().getPath());
+
+ URI ns;
+ Date revision;
+ String prefix;
+ QName baseQName = usesParent.getQName();
+ if (baseQName == null) {
+ ModuleBuilder m = ParserUtils.getParentModule(usesParent);
+ ns = m.getNamespace();
+ revision = m.getRevision();
+ prefix = m.getPrefix();
+ } else {
+ ns = baseQName.getNamespace();
+ revision = baseQName.getRevision();
+ prefix = baseQName.getPrefix();
+ }
+
+ for (QName qn : oldSchemaPath.getPath()) {
+ newPath.add(new QName(ns, revision, prefix, qn.getLocalName()));
+ }
+ } else {
+
+ for (QName qn : oldPath) {
+ URI ns = module.getNamespace();
+ Date rev = module.getRevision();
+ String pref = module.getPrefix();
+ String localPrefix = qn.getPrefix();
+ if (localPrefix != null && !("".equals(localPrefix))) {
+ ModuleBuilder currentModule = ParserUtils.findModuleFromBuilders(modules, module, localPrefix,
+ augment.getLine());
+ if (currentModule == null) {
+ Module m = ParserUtils.findModuleFromContext(context, module, localPrefix, augment.getLine());
+ if (m == null) {
+ throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix "
+ + localPrefix + " not found.");
+ }
+ ns = m.getNamespace();
+ rev = m.getRevision();
+ pref = m.getPrefix();
+ } else {
+ ns = currentModule.getNamespace();
+ rev = currentModule.getRevision();
+ pref = currentModule.getPrefix();
}
- ns = m.getNamespace();
- rev = m.getRevision();
- pref = m.getPrefix();
- } else {
- ns = currentModule.getNamespace();
- rev = currentModule.getRevision();
- pref = currentModule.getPrefix();
}
+ newPath.add(new QName(ns, rev, pref, qn.getLocalName()));
}
- newPath.add(new QName(ns, rev, pref, qn.getLocalName()));
}
augment.setTargetNodeSchemaPath(new SchemaPath(newPath, augment.getTargetPath().isAbsolute()));
+
+ for (DataSchemaNodeBuilder childNode : augment.getChildNodeBuilders()) {
+ correctPathForAugmentNodes(childNode, augment.getTargetNodeSchemaPath());
+ }
+ }
+
+ private void correctPathForAugmentNodes(DataSchemaNodeBuilder node, SchemaPath parentPath) {
+ node.setPath(ParserUtils.createSchemaPath(parentPath, node.getQName()));
+ if (node instanceof DataNodeContainerBuilder) {
+ for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) node).getChildNodeBuilders()) {
+ correctPathForAugmentNodes(child, node.getPath());
+ }
+ }
}
/**
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());
}
}
}
throw new YangParseException(module.getName(), identity.getLine(), "Failed to find base identity");
} else {
identity.setBaseIdentity(baseIdentity);
- IdentitySchemaNode built = identity.build();
- baseIdentity.addDerivedIdentity(built);
}
}
}
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);
}
}
}
}
}
- /**
- * 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<String, TreeMap<Date, ModuleBuilder>> modules, final boolean resolveWithContext) {
+ private void resolveUsesForGroupings(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context) {
+ final Set<GroupingBuilder> allGroupings = new HashSet<>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
ModuleBuilder module = inner.getValue();
- boolean dataCollected = module.isAllUsesDataCollected();
-
- List<UsesNodeBuilder> 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<GroupingBuilder> sorted = GroupingSort.sort(allGroupings);
+ for (GroupingBuilder gb : sorted) {
+ List<UsesNodeBuilder> 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<String, TreeMap<Date, ModuleBuilder>> modules,
- final boolean resolveWithContext) {
- // new loop is must because in collecting data process new uses could
- // be created
- final List<UsesNodeBuilder> allModulesUses = new ArrayList<>();
+ private void resolveUsesForNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context) {
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
- allModulesUses.addAll(inner.getValue().getAllUsesNodes());
+ ModuleBuilder module = inner.getValue();
+ List<UsesNodeBuilder> usesNodes = module.getAllUsesNodes();
+ Collections.sort(usesNodes, new GroupingUtils.UsesComparator());
+ for (UsesNodeBuilder usesNode : usesNodes) {
+ resolveUses(usesNode, modules, context);
+ }
}
}
+ }
- for (UsesNodeBuilder usesNode : allModulesUses) {
- GroupingUtils.updateUsesParent(usesNode);
- GroupingUtils.performRefine(usesNode);
- }
+ private void resolveUses(UsesNodeBuilder usesNode,
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context) {
+ if (!usesNode.isResolved()) {
+ final int line = usesNode.getLine();
+ DataNodeContainerBuilder parent = usesNode.getParent();
+ ModuleBuilder module = ParserUtils.getParentModule(parent);
+ GroupingBuilder target = GroupingUtils.getTargetGroupingFromModules(usesNode, modules, module);
+ if (target == null) {
+ URI ns = null;
+ Date rev = null;
+ String prefix = null;
+ if (parent instanceof AugmentationSchemaBuilder || parent instanceof ModuleBuilder) {
+ ns = module.getNamespace();
+ rev = module.getRevision();
+ prefix = module.getPrefix();
+ } else {
+ ns = ((DataSchemaNodeBuilder) parent).getQName().getNamespace();
+ rev = ((DataSchemaNodeBuilder) parent).getQName().getRevision();
+ prefix = ((DataSchemaNodeBuilder) parent).getQName().getPrefix();
+ }
- if (!resolveWithContext) {
- for (UsesNodeBuilder usesNode : allModulesUses) {
- if (usesNode.isCopy()) {
- usesNode.getParent().getUsesNodes().remove(usesNode);
+ Set<DataSchemaNodeBuilder> childNodes = GroupingUtils.getTargetGroupingDefinitionNodesWithNewNamespace(
+ usesNode, ns, rev, prefix, module.getName(), line);
+ parent.getChildNodeBuilders().addAll(childNodes);
+ Set<TypeDefinitionBuilder> typedefs = GroupingUtils
+ .getTargetGroupingDefinitionTypedefsWithNewNamespace(usesNode, ns, rev, prefix,
+ module.getName(), line);
+ parent.getTypeDefinitionBuilders().addAll(typedefs);
+ Set<GroupingBuilder> groupings = GroupingUtils.getTargetGroupingDefinitionGroupingsWithNewNamespace(
+ usesNode, ns, rev, prefix, module.getName(), line);
+ parent.getGroupingBuilders().addAll(groupings);
+ List<UnknownSchemaNodeBuilder> unknownNodes = GroupingUtils
+ .getTargetGroupingDefinitionUnknownNodesWithNewNamespace(usesNode, ns, rev, prefix,
+ module.getName(), line);
+ parent.getUnknownNodeBuilders().addAll(unknownNodes);
+ usesNode.setResolved(true);
+
+ for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) {
+ processAugmentationOnContext(augment, augment.getTargetPath().getPath(), module, prefix, context);
}
+ GroupingUtils.performRefine(usesNode);
+ } else {
+ parent.getChildNodeBuilders().addAll(target.instantiateChildNodes(parent));
+ parent.getTypeDefinitionBuilders().addAll(target.instantiateTypedefs(parent));
+ parent.getGroupingBuilders().addAll(target.instantiateGroupings(parent));
+ parent.getUnknownNodeBuilders().addAll(target.instantiateUnknownNodes(parent));
+ usesNode.setResolved(true);
+
+ for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) {
+ processAugmentation(augment, parent, augment.getTargetPath().getPath());
+ }
+ GroupingUtils.performRefine(usesNode);
}
}
}
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(),
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);
}