All nodes defined in submodule are added to module to which submodule belongs.
Dependency utility parser is small YANG parser which extracts module identifier
(module name,revision) and all imports / includes, so it is easier for
implementations using YANG parser to check if all dependencies are available.
Change-Id: If1c4c5544aaf54e9ba7d8000a6f31cce83a7f9f1
Signed-off-by: Martin Vitez <mvitez@cisco.com>
Signed-off-by: Tony Tkaciik <ttkacik@cisco.com>
loadTestResources();
assertEquals("Incorrect number of test files.", 1, testModels.size());
- Set<UsesNodeBuilder> usesNodeBuilders = getModuleBuilder().getUsesNodes();
+ Set<UsesNodeBuilder> usesNodeBuilders = getModuleBuilder().getUsesNodeBuilders();
List<RefineHolder> refineHolders = null;
Set<DataSchemaNodeBuilder> dataSchemaNodeBuilders = null;
for (UsesNodeBuilder usesNodeBuilder : usesNodeBuilders) {
refineHolders = usesNodeBuilder.getRefines();
// FIXME
//GroupingUtils.updateUsesParent(usesNodeBuilder);
- dataSchemaNodeBuilders = usesNodeBuilder.getParent().getChildNodes();
+ dataSchemaNodeBuilders = usesNodeBuilder.getParent().getChildNodeBuilders();
break;
}
}
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.Objects;
import org.opendaylight.yangtools.concepts.Immutable;
import org.slf4j.Logger;
public static QName create(String namespace, String revision, String localName) throws IllegalArgumentException{
try {
URI namespaceUri = new URI(namespace);
- Date revisionDate = REVISION_FORMAT.get().parse(revision);
+ Date revisionDate = parseRevision(revision);
return create(namespaceUri, revisionDate, localName);
- } catch (ParseException pe) {
- throw new IllegalArgumentException("Revision is not in supported format", pe);
- } catch (URISyntaxException ue) {
+ } catch (URISyntaxException ue) {
throw new IllegalArgumentException("Namespace is is not valid URI", ue);
}
}
public QName withoutRevision() {
return QName.create(namespace, null, localName);
}
+
+ public static Date parseRevision(String formatedDate) {
+ try {
+ return REVISION_FORMAT.get().parse(formatedDate);
+ } catch (ParseException e) {
+ throw new IllegalArgumentException("Revision is not in supported format",e);
+ }
+ }
+
+ public static String formattedRevision(Date revision) {
+ if(revision == null) {
+ return null;
+ }
+ return REVISION_FORMAT.get().format(revision);
+ }
+
+ public boolean isEqualWithoutRevision(QName other) {
+ return localName.equals(other.getLocalName()) && Objects.equals(namespace, other.getNamespace());
+ }
}
@Override
public Optional<O> getSchemaSource(String moduleName, Optional<String> revision) {
- return getSchemaSourceImpl(moduleName, revision, defaultDelegate);
+ checkNotNull(moduleName, "Module name should not be null.");
+ checkNotNull(revision, "Revision should not be null");
+ return getSchemaSource(SourceIdentifier.create(moduleName, revision));
+ }
+
+ @Override
+ public Optional<O> getSchemaSource(SourceIdentifier sourceIdentifier) {
+ return getSchemaSourceImpl(sourceIdentifier, defaultDelegate);
}
- private Optional<O> getSchemaSourceImpl(String moduleName, Optional<String> revision,
+ protected final Optional<O> getSchemaSourceImpl(SourceIdentifier identifier,
SchemaSourceProvider<I> delegate) {
- checkNotNull(moduleName, "Module name should not be null.");
- checkNotNull(revision, "Revision should not be null");
+ checkNotNull(identifier, "Source identifier name should not be null.");
- Optional<O> cached = getCachedSchemaSource(moduleName, revision);
+ Optional<O> cached = getCachedSchemaSource(identifier);
if (cached.isPresent()) {
return cached;
}
- Optional<I> live = delegate.getSchemaSource(moduleName, revision);
- return cacheSchemaSource(moduleName, revision, live);
+ Optional<I> live = delegate.getSchemaSource(identifier);
+ return cacheSchemaSource(identifier, live);
}
- abstract protected Optional<O> cacheSchemaSource(String moduleName, Optional<String> revision, Optional<I> stream);
+ abstract protected Optional<O> cacheSchemaSource(SourceIdentifier identifier, Optional<I> stream);
- abstract protected Optional<O> getCachedSchemaSource(String moduleName, Optional<String> revision);
+ abstract protected Optional<O> getCachedSchemaSource(SourceIdentifier identifier);
public SchemaSourceProvider<I> getDelegate() {
return defaultDelegate;
return new SchemaSourceProviderInstance(delegate);
}
- private class SchemaSourceProviderInstance implements SchemaSourceProvider<O>, Delegator<SchemaSourceProvider<I>> {
+ private class SchemaSourceProviderInstance implements //
+ SchemaSourceProvider<O>,
+ Delegator<SchemaSourceProvider<I>> {
private final SchemaSourceProvider<I> delegate;
@Override
public Optional<O> getSchemaSource(String moduleName, Optional<String> revision) {
- return getSchemaSourceImpl(moduleName, revision, getDelegate());
+ return getSchemaSource(SourceIdentifier.create(moduleName, revision));
}
@Override
public SchemaSourceProvider<I> getDelegate() {
return delegate;
}
+
+ @Override
+ public Optional<O> getSchemaSource(SourceIdentifier sourceIdentifier) {
+ return getSchemaSourceImpl(sourceIdentifier, getDelegate());
+ }
}
}
}
@Override
- protected synchronized Optional<InputStream> cacheSchemaSource(String moduleName, Optional<String> revision, Optional<I> source) {
- File schemaFile = toFile(moduleName, revision);
+ protected synchronized Optional<InputStream> cacheSchemaSource(SourceIdentifier identifier, Optional<I> source) {
+ File schemaFile = toFile(identifier);
try {
if(source.isPresent() && schemaFile.createNewFile()) {
try (
}
@Override
- protected Optional<InputStream> getCachedSchemaSource(String moduleName, Optional<String> revision) {
- File inputFile = toFile(moduleName, revision);
+ protected Optional<InputStream> getCachedSchemaSource(SourceIdentifier identifier) {
+ File inputFile = toFile(identifier);
try {
if (inputFile.exists() && inputFile.canRead()) {
InputStream stream = new FileInputStream(inputFile);
return Optional.absent();
}
- private File toFile(String moduleName, Optional<String> revision) {
- return new File(storageDirectory, toYangFileName(moduleName, revision));
+ private File toFile(SourceIdentifier identifier) {
+ return new File(storageDirectory, identifier.toYangFilename());
}
- public static final String toYangFileName(String moduleName, Optional<String> revision) {
- StringBuilder filename = new StringBuilder(moduleName);
- if (revision.isPresent()) {
- filename.append("@");
- filename.append(revision.get());
- }
- filename.append(".yang");
- return filename.toString();
- }
+
private static final Function<String, String> NOOP_TRANSFORMATION = new Function<String, String>() {
@Override
package org.opendaylight.yangtools.yang.model.util.repo;
-import java.io.InputStream;
-
import com.google.common.base.Optional;
public interface SchemaSourceProvider<F> {
Optional<F> getSchemaSource(String moduleName, Optional<String> revision);
+
+ Optional<F> getSchemaSource(SourceIdentifier sourceIdentifier);
}
package org.opendaylight.yangtools.yang.model.util.repo;
+import java.io.InputStream;
+import java.io.StringBufferInputStream;
+
+import org.opendaylight.yangtools.concepts.Delegator;
+
import com.google.common.base.Optional;
public class SchemaSourceProviders {
return Optional.absent();
}
+ @Override
+ public Optional getSchemaSource(SourceIdentifier sourceIdentifier) {
+ return Optional.absent();
+ }
+
};
@SuppressWarnings("unchecked")
return (SchemaSourceProvider<T>) NOOP_PROVIDER;
}
+ public static SchemaSourceProvider<InputStream> inputStreamProviderfromStringProvider(
+ SchemaSourceProvider<String> delegate) {
+ return new StringToInputStreamSchemaSourceProvider(delegate);
+ }
+
+ private final static class StringToInputStreamSchemaSourceProvider implements //
+ SchemaSourceProvider<InputStream>, Delegator<SchemaSourceProvider<String>> {
+
+ private SchemaSourceProvider<String> delegate;
+
+ public StringToInputStreamSchemaSourceProvider(SchemaSourceProvider<String> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public SchemaSourceProvider<String> getDelegate() {
+ return delegate;
+ }
+
+ @Override
+ public Optional<InputStream> getSchemaSource(SourceIdentifier sourceIdentifier) {
+ Optional<String> potential = getDelegate().getSchemaSource(sourceIdentifier);
+ if (potential.isPresent()) {
+ String stringStream = potential.get();
+ return Optional.<InputStream> of(new StringBufferInputStream(stringStream));
+ }
+ return Optional.absent();
+ }
+
+ @Override
+ public Optional<InputStream> getSchemaSource(String moduleName, Optional<String> revision) {
+ return getSchemaSource(SourceIdentifier.create(moduleName, revision));
+ }
+ }
+
}
--- /dev/null
+package org.opendaylight.yangtools.yang.model.util.repo;
+
+import com.google.common.base.Optional;
+
+public final class SourceIdentifier {
+
+ private final String name;
+ private final String revision;
+
+ public SourceIdentifier(String name, Optional<String> formattedRevision) {
+ super();
+ this.name = name;
+ this.revision = formattedRevision.orNull();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((revision == null) ? 0 : revision.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ SourceIdentifier other = (SourceIdentifier) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (revision == null) {
+ if (other.revision != null)
+ return false;
+ } else if (!revision.equals(other.revision))
+ return false;
+ return true;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getRevision() {
+ return revision;
+ }
+
+ public static SourceIdentifier create(String moduleName, Optional<String> revision) {
+ return new SourceIdentifier(moduleName, revision);
+ }
+
+ public String toYangFilename() {
+ return toYangFileName(name, Optional.fromNullable(revision));
+ }
+
+ @Override
+ public String toString() {
+ return "SourceIdentifier [name=" + name + "@" + revision + "]";
+ }
+
+ public static final String toYangFileName(String moduleName, Optional<String> revision) {
+ StringBuilder filename = new StringBuilder(moduleName);
+ if (revision.isPresent()) {
+ filename.append("@");
+ filename.append(revision.get());
+ }
+ filename.append(".yang");
+ return filename.toString();
+ }
+
+}
\ No newline at end of file
return qname;
}
+ public Map<QName, DataSchemaNode> getChildNodes() {
+ return childNodes;
+ }
+
@Override
- public Set<DataSchemaNodeBuilder> getChildNodes() {
+ public Set<DataSchemaNodeBuilder> getChildNodeBuilders() {
return addedChildNodes;
}
}
@Override
- public Set<UsesNodeBuilder> getUsesNodes() {
+ public Set<TypeDefinition<?>> getTypeDefinitions() {
+ return typedefs;
+ }
+
+ public Set<UsesNode> getUsesNodes() {
+ return usesNodes;
+ }
+
+ @Override
+ public Set<UsesNodeBuilder> getUsesNodeBuilders() {
return addedUsesNodes;
}
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
/**
* Interface for all yang data-node containers [augment, case, container,
*
* @return collection child nodes builders
*/
- Set<DataSchemaNodeBuilder> getChildNodes();
+ Set<DataSchemaNodeBuilder> getChildNodeBuilders();
/**
* Get child node by name.
*
* @return collection of uses builders
*/
- Set<UsesNodeBuilder> getUsesNodes();
+ Set<UsesNodeBuilder> getUsesNodeBuilders();
/**
* Add builder of uses statement to this node.
*/
void addUsesNode(UsesNodeBuilder usesBuilder);
+ Set<TypeDefinition<?>> getTypeDefinitions();
+
/**
* Get builders of typedef statement defined in this node.
*
for (GroupingBuilder node : addedGroupings) {
GroupingBuilder copy = CopyUtils.copy(node, newParent, true);
copy.setAddedByUses(true);
- for (DataSchemaNodeBuilder childNode : copy.getChildNodes()) {
+ for (DataSchemaNodeBuilder childNode : copy.getChildNodeBuilders()) {
ParserUtils.setNodeAddedByUses(childNode);
}
nodes.add(copy);
private String prefix;
private Date revision;
+ private final boolean submodule;
+ private String belongsTo;
+ private ModuleBuilder parent;
+
+ public ModuleBuilder getParent() {
+ return parent;
+ }
+
+ public void setParent(ModuleBuilder parent) {
+ this.parent = parent;
+ }
+
private final Deque<Builder> actualPath = new LinkedList<>();
private final Set<TypeAwareBuilder> dirtyNodes = new HashSet<>();
private final List<UnknownSchemaNodeBuilder> allUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
public ModuleBuilder(final String name) {
+ this(name, false);
+ }
+
+ public ModuleBuilder(final String name, final boolean submodule) {
super(name, 0, null);
this.name = name;
schemaPath = new SchemaPath(Collections.<QName> emptyList(), true);
instance = new ModuleImpl(name);
+ this.submodule = submodule;
actualPath.push(this);
}
this.name = base.getName();
schemaPath = new SchemaPath(Collections.<QName> emptyList(), true);
instance = new ModuleImpl(base.getName());
+ submodule = false;
actualPath.push(this);
namespace = base.getNamespace();
return dirtyNodes;
}
+ public Set<AugmentationSchema> getAugments() {
+ return augments;
+ }
+
+ public List<AugmentationSchemaBuilder> getAugmentBuilders() {
+ return augmentBuilders;
+ }
+
public List<AugmentationSchemaBuilder> getAllAugments() {
return allAugments;
}
- public Set<IdentitySchemaNodeBuilder> getIdentities() {
+ public Set<IdentitySchemaNode> getIdentities() {
+ return identities;
+ }
+
+ public Set<IdentitySchemaNodeBuilder> getAddedIdentities() {
return addedIdentities;
}
+ public Set<FeatureDefinition> getFeatures() {
+ return features;
+ }
+
+ public Set<FeatureBuilder> getAddedFeatures() {
+ return addedFeatures;
+ }
+
public List<GroupingBuilder> getAllGroupings() {
return allGroupings;
}
return allUsesNodes;
}
- public Set<DeviationBuilder> getDeviations() {
+ public Set<Deviation> getDeviations() {
+ return deviations;
+ }
+
+ public Set<DeviationBuilder> getDeviationBuilders() {
return deviationBuilders;
}
- public List<ExtensionBuilder> getExtensions() {
+ public List<ExtensionDefinition> getExtensions() {
+ return extensions;
+ }
+
+ public List<ExtensionBuilder> getAddedExtensions() {
return addedExtensions;
}
return revision;
}
+ public boolean isSubmodule() {
+ return submodule;
+ }
+
+ public String getBelongsTo() {
+ return belongsTo;
+ }
+
+ public void setBelongsTo(String belongsTo) {
+ this.belongsTo = belongsTo;
+ }
+
public void markActualNodeDirty() {
final TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) getActualNode();
dirtyNodes.add(nodeBuilder);
return builder;
}
- public Set<RpcDefinitionBuilder> getRpcs() {
+ public Set<RpcDefinition> getRpcs() {
+ return rpcs;
+ }
+
+ public Set<RpcDefinitionBuilder> getAddedRpcs() {
return addedRpcs;
}
- public Set<NotificationBuilder> getNotifications() {
+ public Set<NotificationDefinition> getNotifications() {
+ return notifications;
+ }
+
+ public Set<NotificationBuilder> getAddedNotifications() {
return addedNotifications;
}
// defined only under module or submodule
if (parent instanceof DataNodeContainerBuilder) {
DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;
- for (DataSchemaNodeBuilder childNode : parentNode.getChildNodes()) {
+ for (DataSchemaNodeBuilder childNode : parentNode.getChildNodeBuilders()) {
if (childNode.getQName().getLocalName().equals(childName)) {
raiseYangParserException("'" + child + "'", "node", childName, lineNum, childNode.getLine());
}
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.*;
import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
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.ChoiceBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
-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;
}
}
- Map<InputStream, ModuleBuilder> parsedBuilders = parseModuleBuilders(new ArrayList<>(streamToFileMap.keySet()),
+ Map<InputStream, ModuleBuilder> parsedBuilders = parseBuilders(new ArrayList<>(streamToFileMap.keySet()),
new HashMap<ModuleBuilder, InputStream>());
ModuleBuilder main = parsedBuilders.get(yangFileStream);
List<ModuleBuilder> moduleBuilders = new ArrayList<>();
moduleBuilders.add(main);
filterImports(main, new ArrayList<>(parsedBuilders.values()), moduleBuilders);
+ Collection<ModuleBuilder> result = resolveSubmodules(moduleBuilders);
// module builders sorted by dependencies
- ModuleBuilder[] builders = new ModuleBuilder[moduleBuilders.size()];
- moduleBuilders.toArray(builders);
+ ModuleBuilder[] builders = new ModuleBuilder[result.size()];
+ result.toArray(builders);
List<ModuleBuilder> sortedBuilders = ModuleDependencySort.sort(builders);
LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> modules = orderModules(sortedBuilders);
Collection<Module> unsorted = build(modules).values();
private Map<InputStream, ModuleBuilder> parseModuleBuilders(List<InputStream> inputStreams,
Map<ModuleBuilder, InputStream> streamToBuilderMap) {
+ Map<InputStream, ModuleBuilder> modules = parseBuilders(inputStreams, streamToBuilderMap);
+ Map<InputStream, ModuleBuilder> result = resolveSubmodules(modules);
+ return result;
+ }
+ private Map<InputStream, ModuleBuilder> parseBuilders(List<InputStream> inputStreams,
+ Map<ModuleBuilder, InputStream> streamToBuilderMap) {
final ParseTreeWalker walker = new ParseTreeWalker();
final Map<InputStream, ParseTree> trees = parseStreams(inputStreams);
final Map<InputStream, ModuleBuilder> builders = new LinkedHashMap<>();
// 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<InputStream, ModuleBuilder> resolveSubmodules(Map<InputStream, ModuleBuilder> builders) {
+ Map<InputStream, ModuleBuilder> modules = new HashMap<>();
+ Set<ModuleBuilder> submodules = new HashSet<>();
+ for (Map.Entry<InputStream, ModuleBuilder> entry : builders.entrySet()) {
+ ModuleBuilder moduleBuilder = entry.getValue();
+ if (moduleBuilder.isSubmodule()) {
+ submodules.add(moduleBuilder);
+ } else {
+ modules.put(entry.getKey(), moduleBuilder);
+ }
+ }
+
+ Collection<ModuleBuilder> values = modules.values();
+ for (ModuleBuilder submodule : submodules) {
+ for (ModuleBuilder module : values) {
+ if (module.getName().equals(submodule.getBelongsTo())) {
+ addSubmoduleToModule(submodule, module);
+ }
+ }
+ }
+ return modules;
+ }
+
+ private Collection<ModuleBuilder> resolveSubmodules(Collection<ModuleBuilder> builders) {
+ Collection<ModuleBuilder> modules = new HashSet<>();
+ Set<ModuleBuilder> 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().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<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(final List<InputStream> yangFileStreams,
final Map<ModuleBuilder, InputStream> streamToBuilderMap, final SchemaContext context) {
Map<InputStream, ModuleBuilder> parsedBuilders = parseModuleBuilders(yangFileStreams, streamToBuilderMap);
}
private void filterImports(ModuleBuilder main, List<ModuleBuilder> other, List<ModuleBuilder> filtered) {
- for (ModuleImport mi : main.getModuleImports()) {
+ Set<ModuleImport> imports = main.getModuleImports();
+
+ // if this is submodule, add parent to filtered and pick its imports
+ if (main.isSubmodule()) {
+ TreeMap<Date, ModuleBuilder> 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) {
}
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);
+ }
+ return result;
+ }
private Map<ModuleBuilder, Module> build(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
// fix unresolved nodes
}
augment.setTargetNodeSchemaPath(new SchemaPath(newPath, augment.getTargetPath().isAbsolute()));
- for (DataSchemaNodeBuilder childNode : augment.getChildNodes()) {
+ for (DataSchemaNodeBuilder childNode : augment.getChildNodeBuilders()) {
correctPathForAugmentNodes(childNode, augment.getTargetNodeSchemaPath());
}
}
SchemaPath newPath = ParserUtils.createSchemaPath(parentPath, node.getQName());
node.setPath(newPath);
if (node instanceof DataNodeContainerBuilder) {
- for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) node).getChildNodes()) {
+ for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) node).getChildNodeBuilders()) {
correctPathForAugmentNodes(child, node.getPath());
}
}
continue;
}
- for (DataSchemaNodeBuilder childNode : augment.getChildNodes()) {
+ for (DataSchemaNodeBuilder childNode : augment.getChildNodeBuilders()) {
if (childNode.getConstraints().isMandatory()) {
throw new YangParseException(augment.getModuleName(), augment.getLine(),
"Error in augment parsing: cannot augment mandatory node "
* module being resolved
*/
private void resolveIdentities(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
- final Set<IdentitySchemaNodeBuilder> identities = module.getIdentities();
+ final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
for (IdentitySchemaNodeBuilder identity : identities) {
final String baseIdentityName = identity.getBaseIdentityName();
final int line = identity.getLine();
*/
private void resolveIdentitiesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
final ModuleBuilder module, final SchemaContext context) {
- final Set<IdentitySchemaNodeBuilder> identities = module.getIdentities();
+ final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
for (IdentitySchemaNodeBuilder identity : identities) {
final String baseIdentityName = identity.getBaseIdentityName();
final int line = identity.getLine();
resolveUsesAugment(augment, module, modules, context);
}
} else {
- parent.getChildNodes().addAll(target.instantiateChildNodes(parent));
+ parent.getChildNodeBuilders().addAll(target.instantiateChildNodes(parent));
parent.getTypeDefinitionBuilders().addAll(target.instantiateTypedefs(parent));
parent.getGroupingBuilders().addAll(target.instantiateGroupings(parent));
parent.getUnknownNodes().addAll(target.instantiateUnknownNodes(parent));
Set<DataSchemaNodeBuilder> childNodes = wrapChildNodes(module.getModuleName(), line,
gd.getChildNodes(), parentPath, ns, rev, pref);
- parent.getChildNodes().addAll(childNodes);
+ parent.getChildNodeBuilders().addAll(childNodes);
for (DataSchemaNodeBuilder childNode : childNodes) {
setNodeAddedByUses(childNode);
}
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);
}
}
} else {
- for (ExtensionBuilder extension : dependentModuleBuilder.getExtensions()) {
+ for (ExtensionBuilder extension : dependentModuleBuilder.getAddedExtensions()) {
if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) {
usnb.setExtensionBuilder(extension);
break;
* module in which resolve deviations
*/
private void resolveDeviation(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
- for (DeviationBuilder dev : module.getDeviations()) {
+ for (DeviationBuilder dev : module.getDeviationBuilders()) {
int line = dev.getLine();
SchemaPath targetPath = dev.getTargetPath();
List<QName> path = targetPath.getPath();
*/
private void resolveDeviationWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> 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<QName> path = targetPath.getPath();
actualPath.pop();
}
+ @Override public void enterSubmodule_stmt(YangParser.Submodule_stmtContext ctx) {
+ moduleName = stringFromNode(ctx);
+ LOGGER.debug("entering submodule " + moduleName);
+ enterLog("submodule", moduleName, 0);
+ actualPath.push(new Stack<QName>());
+
+ moduleBuilder = new ModuleBuilder(moduleName, true);
+
+ String description = null;
+ String reference = null;
+ for (int i = 0; i < ctx.getChildCount(); i++) {
+ ParseTree child = ctx.getChild(i);
+ if (child instanceof Description_stmtContext) {
+ description = stringFromNode(child);
+ } else if (child instanceof Reference_stmtContext) {
+ reference = stringFromNode(child);
+ } else {
+ if (description != null && reference != null) {
+ break;
+ }
+ }
+ }
+ moduleBuilder.setDescription(description);
+ moduleBuilder.setReference(reference);
+ }
+
+ @Override public void exitSubmodule_stmt(YangParser.Submodule_stmtContext ctx) {
+ exitLog("submodule", "");
+ actualPath.pop();
+ }
+
+ @Override public void enterBelongs_to_stmt(YangParser.Belongs_to_stmtContext ctx) {
+ moduleBuilder.setBelongsTo(stringFromNode(ctx));
+ }
+
@Override
public void enterModule_header_stmts(Module_header_stmtsContext ctx) {
enterLog("module_header", "", ctx.getStart().getLine());
--- /dev/null
+package org.opendaylight.yangtools.yang.parser.impl.util;
+
+import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getArgumentString;
+import static org.opendaylight.yangtools.yang.parser.util.ParserListenerUtils.getFirstContext;
+
+import java.io.InputStream;
+import java.util.Date;
+import java.util.List;
+
+import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Belongs_to_stmtContext;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Include_stmtContext;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_stmtContext;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_date_stmtContext;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtContext;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtsContext;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Submodule_stmtContext;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+
+public abstract class YangModelDependencyInfo {
+
+ private final String name;
+ private final String formattedRevision;
+ private final Date revision;
+ private final ImmutableSet<ModuleImport> submoduleIncludes;
+ private final ImmutableSet<ModuleImport> moduleImports;
+ private final ImmutableSet<ModuleImport> dependencies;
+
+ public YangModelDependencyInfo(String name, String formattedRevision, ImmutableSet<ModuleImport> imports,
+ ImmutableSet<ModuleImport> includes) {
+ this.name = name;
+ this.formattedRevision = formattedRevision;
+ this.revision = QName.parseRevision(formattedRevision);
+ this.moduleImports = imports;
+ this.submoduleIncludes = includes;
+ this.dependencies = ImmutableSet.<ModuleImport> builder() //
+ .addAll(moduleImports) //
+ .addAll(submoduleIncludes) //
+ .build();
+ }
+
+ public ImmutableSet<ModuleImport> getDependencies() {
+ return dependencies;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getFormattedRevision() {
+ return formattedRevision;
+ }
+
+ public Date getRevision() {
+ return revision;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((formattedRevision == null) ? 0 : formattedRevision.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof YangModelDependencyInfo))
+ return false;
+ YangModelDependencyInfo other = (YangModelDependencyInfo) obj;
+ if (formattedRevision == null) {
+ if (other.formattedRevision != null)
+ return false;
+ } else if (!formattedRevision.equals(other.formattedRevision))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+
+ public static YangModelDependencyInfo fromInputStream(InputStream yangStream) {
+ YangContext yangContext = YangParserImpl.parseStreamWithoutErrorListeners(yangStream);
+
+ Optional<Module_stmtContext> moduleCtx = getFirstContext(yangContext, Module_stmtContext.class);
+ if (moduleCtx.isPresent()) {
+ return fromModuleContext(moduleCtx.get());
+ }
+ Optional<Submodule_stmtContext> submoduleCtx = getFirstContext(yangContext, Submodule_stmtContext.class);
+ if (submoduleCtx.isPresent()) {
+ return fromSubmoduleContext(submoduleCtx.get());
+ }
+ throw new IllegalArgumentException("Supplied stream is not valid yang file.");
+ }
+
+ private static YangModelDependencyInfo fromModuleContext(Module_stmtContext module) {
+ String name = getArgumentString(module);
+ // String prefix =
+ // getArgumentString(module.module_header_stmts().prefix_stmt(0));
+ String namespace = getArgumentString(module.module_header_stmts().namespace_stmt(0));
+ String latestRevision = getLatestRevision(module.revision_stmts());
+ ImmutableSet<ModuleImport> imports = getImports(module.linkage_stmts().import_stmt());
+ ImmutableSet<ModuleImport> includes = getIncludes(module.linkage_stmts().include_stmt());
+
+ return new ModuleDependencyInfo(name, latestRevision, namespace, imports, includes);
+ }
+
+ private static ImmutableSet<ModuleImport> getImports(List<Import_stmtContext> importStatements) {
+ ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
+ for (Import_stmtContext importStmt : importStatements) {
+ String moduleName = getArgumentString(importStmt);
+ Date revision = getRevision(importStmt.revision_date_stmt());
+ String prefix = getArgumentString(importStmt.prefix_stmt());
+ builder.add(new ModuleImportImpl(moduleName, revision));
+ }
+ return builder.build();
+ }
+
+ private static String getLatestRevision(Revision_stmtsContext revision_stmts) {
+ List<Revision_stmtContext> revisions = revision_stmts.getRuleContexts(Revision_stmtContext.class);
+ String latestRevision = null;
+ for (Revision_stmtContext revisionStmt : revisions) {
+ String currentRevision = getArgumentString(revisionStmt);
+ if (latestRevision == null || latestRevision.compareTo(currentRevision) == 1) {
+ latestRevision = currentRevision;
+ }
+ }
+ return latestRevision;
+ }
+
+ private static YangModelDependencyInfo fromSubmoduleContext(Submodule_stmtContext submodule) {
+ String name = getArgumentString(submodule);
+ Belongs_to_stmtContext belongsToStmt = submodule.submodule_header_stmts().belongs_to_stmt(0);
+ String belongsTo = getArgumentString(belongsToStmt);
+
+ String latestRevision = getLatestRevision(submodule.revision_stmts());
+ ImmutableSet<ModuleImport> imports = getImports(submodule.linkage_stmts().import_stmt());
+ ImmutableSet<ModuleImport> includes = getIncludes(submodule.linkage_stmts().include_stmt());
+
+ return new SubmoduleDependencyInfo(name, latestRevision, belongsTo, imports, includes);
+ }
+
+ private static ImmutableSet<ModuleImport> getIncludes(List<Include_stmtContext> importStatements) {
+ ImmutableSet.Builder<ModuleImport> builder = ImmutableSet.builder();
+ for (Include_stmtContext importStmt : importStatements) {
+ String moduleName = getArgumentString(importStmt);
+ Date revision = getRevision(importStmt.revision_date_stmt());
+ builder.add(new ModuleImportImpl(moduleName, revision));
+ }
+ return builder.build();
+ }
+
+ private static Date getRevision(Revision_date_stmtContext revision_date_stmt) {
+ if (revision_date_stmt == null) {
+ return null;
+ }
+ String formatedDate = getArgumentString(revision_date_stmt);
+ return QName.parseRevision(formatedDate);
+ }
+
+ public static final class ModuleDependencyInfo extends YangModelDependencyInfo {
+
+ private ModuleDependencyInfo(String name, String latestRevision, String namespace,
+ ImmutableSet<ModuleImport> imports, ImmutableSet<ModuleImport> includes) {
+ super(name, latestRevision, imports, includes);
+ }
+
+ @Override
+ public String toString() {
+ return "Module [name=" + getName() + ", revision=" + getRevision()
+ + ", dependencies=" + getDependencies() + "]";
+ }
+
+ }
+
+ public static final class SubmoduleDependencyInfo extends YangModelDependencyInfo {
+
+ private final String belongsTo;
+
+ public String getParentModule() {
+ return belongsTo;
+ }
+
+ private SubmoduleDependencyInfo(String name, String latestRevision, String belongsTo,
+ ImmutableSet<ModuleImport> imports, ImmutableSet<ModuleImport> includes) {
+ super(name, latestRevision, imports, includes);
+ this.belongsTo = belongsTo;
+ }
+
+ @Override
+ public String toString() {
+ return "Submodule [name=" + getName() + ", revision=" + getRevision()
+ + ", dependencies=" + getDependencies() + "]";
+ }
+
+ }
+
+ private static final class ModuleImportImpl implements ModuleImport {
+
+ private Date revision;
+ private String name;
+
+ public ModuleImportImpl(String moduleName, Date revision) {
+ this.name = moduleName;
+ this.revision = revision;
+ }
+
+ @Override
+ public String getModuleName() {
+ return this.name;
+ }
+
+ @Override
+ public Date getRevision() {
+ return this.revision;
+ }
+
+ @Override
+ public String getPrefix() {
+ return null;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((revision == null) ? 0 : revision.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ModuleImportImpl other = (ModuleImportImpl) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (revision == null) {
+ if (other.revision != null)
+ return false;
+ } else if (!revision.equals(other.revision))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "ModuleImportImpl [name=" + name + ", revision=" + QName.formattedRevision(revision) + "]";
+ }
+
+
+ }
+}
--- /dev/null
+package org.opendaylight.yangtools.yang.parser.impl.util;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.yangtools.yang.common.QName;
+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.util.repo.SchemaSourceProvider;
+import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
+
+public class YangSourceContext implements SchemaSourceProvider<InputStream>,AutoCloseable {
+
+ private final ImmutableSet<SourceIdentifier> validSources;
+
+
+ private final ImmutableSet<SourceIdentifier> missingSources;
+ private final ImmutableMultimap<SourceIdentifier, ModuleImport> missingDependencies;
+ private SchemaSourceProvider<InputStream> sourceProvider;
+
+ private YangSourceContext(ImmutableSet<SourceIdentifier> validSourcesSet,
+ ImmutableSet<SourceIdentifier> missingSourcesSet,
+ ImmutableMultimap<SourceIdentifier, ModuleImport> missingDependenciesMap, SchemaSourceProvider<InputStream> sourceProvicer) {
+ validSources = validSourcesSet;
+ missingSources = missingSourcesSet;
+ missingDependencies = missingDependenciesMap;
+ sourceProvider = sourceProvicer;
+ }
+
+ public ImmutableSet<SourceIdentifier> getValidSources() {
+ return validSources;
+ }
+
+ public ImmutableSet<SourceIdentifier> getMissingSources() {
+ return missingSources;
+ }
+
+ public ImmutableMultimap<SourceIdentifier, ModuleImport> getMissingDependencies() {
+ return missingDependencies;
+ }
+
+ @Override
+ public Optional<InputStream> getSchemaSource(String moduleName, Optional<String> revision) {
+ return getSchemaSource(SourceIdentifier.create(moduleName,revision));
+ }
+
+ @Override
+ public Optional<InputStream> getSchemaSource(SourceIdentifier sourceIdentifier) {
+ if(validSources.contains(sourceIdentifier)) {
+ return getDelegateChecked().getSchemaSource(sourceIdentifier);
+ }
+ return Optional.absent();
+ }
+
+ private SchemaSourceProvider<InputStream> getDelegateChecked() {
+ Preconditions.checkState(sourceProvider != null,"Instance is already closed.");
+ return sourceProvider;
+ }
+
+ @Override
+ public void close() {
+ if(sourceProvider != null) {
+ sourceProvider = null;
+ }
+ }
+
+ public static final YangSourceContext createFrom(Iterable<QName> capabilities,
+ SchemaSourceProvider<InputStream> schemaSourceProvider) {
+ YangSourceContextResolver resolver = new YangSourceFromCapabilitiesResolver(capabilities, schemaSourceProvider);
+ return resolver.resolveContext();
+ }
+
+ public static final SchemaContext toSchemaContext(YangSourceContext context) {
+ List<InputStream> inputStreams = getValidInputStreams(context);
+ YangParserImpl parser = new YangParserImpl();
+ Set<Module> models = parser.parseYangModelsFromStreams(inputStreams);
+ return parser.resolveSchemaContext(models);
+ }
+
+ public static List<InputStream> getValidInputStreams(YangSourceContext context) {
+ return getValidInputStreams(context, context.sourceProvider);
+ }
+
+ public static List<InputStream> getValidInputStreams(YangSourceContext context, SchemaSourceProvider<InputStream> provider) {
+ // TODO Auto-generated method stub
+ final HashSet<SourceIdentifier> sourcesToLoad = new HashSet<>();
+ sourcesToLoad.addAll(context.getValidSources());
+ for(SourceIdentifier source : context.getValidSources()) {
+ if(source.getRevision() != null) {
+ SourceIdentifier sourceWithoutRevision = SourceIdentifier.create(source.getName(), Optional.<String>absent());
+ sourcesToLoad.removeAll(Collections.singleton(sourceWithoutRevision));
+ }
+ }
+
+ ImmutableList.Builder<InputStream> ret = ImmutableList.<InputStream>builder();
+ for(SourceIdentifier sourceIdentifier : sourcesToLoad) {
+ Optional<InputStream> source = provider.getSchemaSource(sourceIdentifier);
+ ret.add(source.get());
+ }
+ return ret.build();
+ }
+
+
+ public static abstract class YangSourceContextResolver {
+
+ private static final Logger LOG = LoggerFactory.getLogger(YangSourceContextResolver.class);
+
+ private SchemaSourceProvider<InputStream> sourceProvicer;
+
+ private HashMap<SourceIdentifier, ResolutionState> alreadyProcessed = new HashMap<>();
+
+ private ImmutableSet.Builder<SourceIdentifier> missingSources = ImmutableSet.builder();
+
+ private ImmutableMultimap.Builder<SourceIdentifier, ModuleImport> missingDependencies = ImmutableMultimap
+ .builder();
+
+ private ImmutableSet.Builder<SourceIdentifier> validSources = ImmutableSet.builder();
+
+ public YangSourceContextResolver(SchemaSourceProvider<InputStream> schemaSourceProvider) {
+ sourceProvicer = schemaSourceProvider;
+ }
+
+ public abstract YangSourceContext resolveContext();
+
+ public ResolutionState resolveSource(String name, Optional<String> formattedRevision) {
+ return resolveSource(new SourceIdentifier(name, formattedRevision));
+ }
+
+ private ResolutionState resolveSource(SourceIdentifier identifier) {
+
+ if (alreadyProcessed.containsKey(identifier)) {
+ return alreadyProcessed.get(identifier);
+ }
+ LOG.info("Resolving source:Â {}",identifier);
+ ResolutionState potentialState = ResolutionState.EVERYTHING_OK;
+ try {
+ Optional<InputStream> source = getSchemaSource(identifier);
+ if (source.isPresent()) {
+
+ YangModelDependencyInfo info = YangModelDependencyInfo.fromInputStream(source.get());
+
+ checkValidSource(identifier,info);
+
+ for (ModuleImport dependency : info.getDependencies()) {
+ LOG.debug("Source: {} Resolving dependency: {}",identifier,dependency);
+ ResolutionState dependencyState = resolveDependency(dependency);
+ if (dependencyState == ResolutionState.MISSING_SOURCE) {
+ potentialState = ResolutionState.MISSING_DEPENDENCY;
+ missingDependencies.put(identifier, dependency);
+ }
+ }
+ } else {
+ missingSources.add(identifier);
+ return ResolutionState.MISSING_SOURCE;
+ }
+ } catch (Exception e) {
+ potentialState = ResolutionState.OTHER_ERROR;
+ }
+ updateResolutionState(identifier, potentialState);
+ return potentialState;
+ }
+
+ private boolean checkValidSource(SourceIdentifier identifier, YangModelDependencyInfo info) {
+ if(!identifier.getName().equals(info.getName())) {
+ LOG.warn("Incorrect model returned. Identifier name was: {}, source contained: {}", identifier.getName(),info.getName());
+ throw new IllegalStateException("Incorrect source was returned");
+ }
+ return true;
+ }
+
+ private void updateResolutionState(SourceIdentifier identifier, ResolutionState potentialState) {
+ alreadyProcessed.put(identifier, potentialState);
+ switch (potentialState) {
+ case MISSING_SOURCE:
+ missingSources.add(identifier);
+ break;
+ case EVERYTHING_OK:
+ validSources.add(identifier);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private ResolutionState resolveDependency(ModuleImport dependency) {
+ String name = dependency.getModuleName();
+ Optional<String> formattedRevision = Optional
+ .fromNullable(QName.formattedRevision(dependency.getRevision()));
+ return resolveSource(new SourceIdentifier(name, formattedRevision));
+ }
+
+ private Optional<InputStream> getSchemaSource(SourceIdentifier identifier) {
+ return sourceProvicer
+ .getSchemaSource(identifier.getName(), Optional.fromNullable(identifier.getRevision()));
+ }
+
+ protected YangSourceContext createSourceContext() {
+
+ ImmutableSet<SourceIdentifier> missingSourcesSet = missingSources.build();
+ ImmutableMultimap<SourceIdentifier, ModuleImport> missingDependenciesMap = missingDependencies.build();
+ ImmutableSet<SourceIdentifier> validSourcesSet = validSources.build();
+
+
+ return new YangSourceContext(validSourcesSet,missingSourcesSet,missingDependenciesMap,sourceProvicer);
+
+ }
+ }
+
+ private enum ResolutionState {
+ MISSING_SOURCE, MISSING_DEPENDENCY, OTHER_ERROR, EVERYTHING_OK
+ }
+
+ public static final class YangSourceFromCapabilitiesResolver extends YangSourceContextResolver {
+
+ private Iterable<QName> capabilities;
+
+ public YangSourceFromCapabilitiesResolver(Iterable<QName> capabilities,
+ SchemaSourceProvider<InputStream> schemaSourceProvider) {
+ super(schemaSourceProvider);
+ this.capabilities = capabilities;
+ }
+
+ @Override
+ public YangSourceContext resolveContext() {
+ for (QName capability : capabilities) {
+ resolveCapability(capability);
+ }
+ return createSourceContext();
+ }
+
+ private void resolveCapability(QName capability) {
+ super.resolveSource(capability.getLocalName(), Optional.fromNullable(capability.getFormattedRevision()));
+ }
+ }
+
+
+}
copy.setReference(old.getReference());
copy.setStatus(old.getStatus());
copy.setAugmenting(old.isAugmenting());
- for (DataSchemaNodeBuilder childNode : old.getChildNodes()) {
+ for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
copy.addChildNode(copy(childNode, copy, updateQName));
}
copy.getGroupings().addAll(old.getGroupings());
for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
copy.addTypedef(copy(tdb, copy, updateQName));
}
- for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
+ for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
copy.addUsesNode(copyUses(oldUses, copy));
}
for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
copy.setAugmenting(old.isAugmenting());
copy.setAddedByUses(old.isAddedByUses());
copy.setConfiguration(old.isConfiguration());
- for (DataSchemaNodeBuilder childNode : old.getChildNodes()) {
+ for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
copy.addChildNode(copy(childNode, copy, updateQName));
}
copy.getGroupings().addAll(old.getGroupings());
for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
copy.addTypedef(copy(tdb, copy, updateQName));
}
- for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
+ for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
copy.addUsesNode(copyUses(oldUses, copy));
}
for (AugmentationSchemaBuilder augment : old.getAugmentationBuilders()) {
copy.setAugmenting(old.isAugmenting());
copy.setAddedByUses(old.isAddedByUses());
copy.setConfiguration(old.isConfiguration());
- for (DataSchemaNodeBuilder childNode : old.getChildNodes()) {
+ for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
copy.addChildNode(copy(childNode, copy, updateQName));
}
copy.getGroupings().addAll(old.getGroupings());
for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
copy.addTypedef(copy(tdb, copy, updateQName));
}
- for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
+ for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
copy.addUsesNode(copyUses(oldUses, copy));
}
for (AugmentationSchemaBuilder augment : old.getAugmentationBuilders()) {
copy.setReference(old.getReference());
copy.setStatus(old.getStatus());
copy.setAddedByUses(old.isAddedByUses());
- for (DataSchemaNodeBuilder childNode : old.getChildNodes()) {
+ for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
copy.addChildNode(copy(childNode, copy, updateQName));
}
copy.getGroupings().addAll(old.getGroupings());
for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
copy.addTypedef(copy(tdb, copy, updateQName));
}
- for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
+ for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
copy.addUsesNode(copyUses(oldUses, copy));
}
for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
copy.setStatus(old.getStatus());
copy.addWhenCondition(old.getWhenCondition());
copy.setTargetNodeSchemaPath(old.getTargetNodeSchemaPath());
- for (DataSchemaNodeBuilder childNode : old.getChildNodes()) {
+ for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
copy.addChildNode(copy(childNode, copy, false));
}
- for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
+ for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
copy.addUsesNode(copyUses(oldUses, copy));
}
for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
*/
public static Set<UsesNodeBuilder> getAllUsesNodes(DataNodeContainerBuilder container) {
Set<UsesNodeBuilder> ret = new HashSet<>();
- Set<UsesNodeBuilder> usesNodes = container.getUsesNodes();
+ Set<UsesNodeBuilder> usesNodes = container.getUsesNodeBuilders();
ret.addAll(usesNodes);
for (UsesNodeBuilder usesNode : usesNodes) {
for (GroupingBuilder groupingDefinition : groupings) {
ret.addAll(getAllUsesNodes(groupingDefinition));
}
- Set<DataSchemaNodeBuilder> childNodes = container.getChildNodes();
+ Set<DataSchemaNodeBuilder> childNodes = container.getChildNodeBuilders();
for (DataSchemaNodeBuilder childNode : childNodes) {
if (childNode instanceof DataNodeContainerBuilder) {
ret.addAll(getAllUsesNodes((DataNodeContainerBuilder) childNode));
}
ModuleBuilder dependentModule;
+ if(groupingPrefix == null) {
+ dependentModule = module;
+ }
if (groupingPrefix.equals(module.getPrefix())) {
dependentModule = module;
} else {
*/
package org.opendaylight.yangtools.yang.parser.util;
+import static com.google.common.base.Preconditions.checkState;
+
import java.math.BigDecimal;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
+import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
+import org.omg.CORBA.CTX_RESTRICT_SCOPE;
import org.opendaylight.yangtools.antlrv4.code.gen.*;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Argument_stmtContext;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Base_stmtContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
+
public final class ParserListenerUtils {
private static final Logger LOG = LoggerFactory.getLogger(ParserListenerUtils.class);
if (treeNode.getChild(i) instanceof StringContext) {
final StringContext context = (StringContext) treeNode.getChild(i);
if (context != null) {
- return stringFromStringContext(context,treeNode);
+ return stringFromStringContext(context);
}
}
return result;
}
- private static String stringFromStringContext(StringContext context, ParseTree treeNode) {
+ public static String stringFromStringContext(StringContext context) {
StringBuilder str = new StringBuilder();
for (TerminalNode stringNode : context.STRING()) {
String result = stringNode.getText();
if(!result.contains("\"")){
str.append(result);
} else if (!(result.startsWith("\"")) && result.endsWith("\"")) {
- LOG.error("Syntax error in module {} at line {}: missing '\"'.", getParentModule(treeNode),
+ LOG.error("Syntax error in module {} at line {}: missing '\"'.", getParentModule(context),
context.getStart().getLine());
} else {
str.append(result.replace("\"", ""));
return refine;
}
+ public static String getArgumentString(org.antlr.v4.runtime.ParserRuleContext ctx) {
+ List<StringContext> potentialValues = ctx.getRuleContexts(StringContext.class);
+ checkState(!potentialValues.isEmpty());
+ return ParserListenerUtils.stringFromStringContext(potentialValues.get(0));
+ }
+
+ public static <T extends ParserRuleContext> Optional<T> getFirstContext(ParserRuleContext context,Class<T> contextType) {
+ List<T> potential = context.getRuleContexts(contextType);
+ if(potential.isEmpty()) {
+ return Optional.absent();
+ }
+ return Optional.of(potential.get(0));
+ }
+
}
import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+import com.google.common.base.Preconditions
public final class ParserUtils {
var ModuleBuilder dependentModule = null;
var Date dependentModuleRevision = null;
- if (prefix.equals(module.getPrefix())) {
+ if(prefix == null) {
+ dependentModule = module;
+ } else if (prefix.equals(module.getPrefix())) {
dependentModule = module;
} else {
val ModuleImport dependentModuleImport = getModuleImport(module, prefix);
* augmentation target node
*/
public static def dispatch fillAugmentTarget(AugmentationSchemaBuilder augment, DataNodeContainerBuilder target) {
- for (DataSchemaNodeBuilder child : augment.getChildNodes()) {
+ for (DataSchemaNodeBuilder child : augment.getChildNodeBuilders()) {
val childCopy = CopyUtils.copy(child, target, false);
if (augment.parent instanceof UsesNodeBuilder) {
setNodeAddedByUses(childCopy);
* augmentation target choice node
*/
public static def dispatch fillAugmentTarget(AugmentationSchemaBuilder augment, ChoiceBuilder target) {
- for (DataSchemaNodeBuilder builder : augment.getChildNodes()) {
+ for (DataSchemaNodeBuilder builder : augment.getChildNodeBuilders()) {
val childCopy = CopyUtils.copy(builder, target, false);
if (augment.parent instanceof UsesNodeBuilder) {
setNodeAddedByUses(childCopy);
setNodeAugmenting(childCopy)
target.addCase(childCopy);
}
- for (UsesNodeBuilder usesNode : augment.getUsesNodes()) {
+ for (UsesNodeBuilder usesNode : augment.getUsesNodeBuilders()) {
if (usesNode !== null) {
throw new YangParseException(augment.getModuleName(), augment.getLine(),
"Error in augment parsing: cannot augment choice with nodes from grouping");
child.setAugmenting(true);
if (child instanceof DataNodeContainerBuilder) {
val DataNodeContainerBuilder dataNodeChild = child as DataNodeContainerBuilder;
- for (inner : dataNodeChild.getChildNodes()) {
+ for (inner : dataNodeChild.getChildNodeBuilders()) {
setNodeAugmenting(inner);
}
} else if (child instanceof ChoiceBuilder) {
child.setAddedByUses(true);
if (child instanceof DataNodeContainerBuilder) {
val DataNodeContainerBuilder dataNodeChild = child as DataNodeContainerBuilder;
- for (inner : dataNodeChild.getChildNodes()) {
+ for (inner : dataNodeChild.getChildNodeBuilders()) {
setNodeAddedByUses(inner);
}
} else if (child instanceof ChoiceBuilder) {
var SchemaNodeBuilder node = module.getDataChildByName(first.localName)
if (node == null) {
- val notifications = module.notifications
+ val notifications = module.getAddedNotifications
for (notification : notifications) {
if (notification.QName.localName.equals(first.localName)) {
node = notification
}
}
if (node == null) {
- val rpcs = module.rpcs
+ val rpcs = module.getAddedRpcs
for (rpc : rpcs) {
if (rpc.QName.localName.equals(first.localName)) {
node = rpc
val name = splittedBase.get(1);
val dependentModule = findModuleFromBuilders(modules, module, prefix, line);
if (dependentModule !== null) {
- result = findIdentity(dependentModule.identities, name);
+ result = findIdentity(dependentModule.getAddedIdentities, name);
}
} else {
- result = findIdentity(module.identities, baseString);
+ result = findIdentity(module.getAddedIdentities, baseString);
}
return result;
}
while (!(parent instanceof ModuleBuilder)) {
parent = parent.getParent();
}
- return parent as ModuleBuilder;
+ Preconditions.checkState(parent instanceof ModuleBuilder)
+ var parentModule = parent as ModuleBuilder
+ if(parentModule.submodule) {
+ parentModule = parentModule.parent;
+ }
+ return parentModule;
}
public static def Set<DataSchemaNodeBuilder> wrapChildNodes(String moduleName, int line, Set<DataSchemaNode> nodes,
import org.opendaylight.yangtools.yang.model.util.UnionType;
public class YangParserTest {
+ public static final String FS = File.separator;
+
private final URI fooNS = URI.create("urn:opendaylight.foo");
private final URI barNS = URI.create("urn:opendaylight.bar");
private final URI bazNS = URI.create("urn:opendaylight.baz");
}
}
+ @Test
+ public void testSubmodules() {
+ String yangFilePath = getClass().getResource(FS + "submodule-test" + FS + "subfoo.yang").getPath();
+ String directoryPath = getClass().getResource(FS + "model").getPath();
+
+ File directory = new File(directoryPath);
+ File yangFile = new File(yangFilePath);
+
+ Set<Module> modules = new YangParserImpl().parseYangModels(yangFile, directory);
+ assertEquals(3, modules.size());
+
+ Module foo = TestUtils.findModule(modules, "foo");
+
+ DataSchemaNode id = foo.getDataChildByName("id");
+ assertNotNull(id);
+ DataSchemaNode subExt = foo.getDataChildByName("sub-ext");
+ assertNotNull(subExt);
+ DataSchemaNode subTransfer = foo.getDataChildByName("sub-transfer");
+ assertNotNull(subTransfer);
+
+ assertEquals(2, foo.getExtensionSchemaNodes().size());
+ assertEquals(2, foo.getAugmentations().size());
+ }
+
}
--- /dev/null
+submodule subfoo {
+ yang-version 1;
+
+ belongs-to foo {
+ prefix f;
+ }
+
+ import bar {
+ prefix "br";
+ revision-date 2013-07-03;
+ }
+
+ import baz {
+ prefix "bz";
+ revision-date 2013-02-27;
+ }
+
+ revision "2013-02-27" {
+ }
+
+ leaf id {
+ type br:int32-ext2 {
+ range "12..max";
+ }
+ }
+
+ container sub-ext {
+ bz:c-define "MY_INTERFACES";
+ }
+
+
+ container sub-transfer {
+ choice how {
+ default interval;
+ container input {
+ }
+ list output {
+ leaf id {
+ type string;
+ }
+ }
+ case manual {
+ leaf manual {
+ type empty;
+ }
+ }
+ }
+ }
+
+ anyxml sub-datas {
+ status obsolete;
+ }
+
+ augment "/br:interfaces/br:ifEntry/bz:augment-holder" {
+ when "if:ifType='ds0'";
+ leaf subleaf {
+ type string;
+ }
+ }
+
+ extension sub-mountpoint {
+ argument "name" {
+ yin-element "true";
+ }
+ }
+
+}