X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=parser%2Fyang-parser-rfc7950%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Frfc7950%2Frepo%2FYangModelDependencyInfo.java;h=c1d35a7b2cbd498aed5699a5bd8799b4b1eb2196;hb=910a9f494dad9e03f60b3dd249f7c5b32a374591;hp=40b1116fd82e039b8eaa1f09a0dffd39b7325229;hpb=083ef931709258bed6e0fede5eea7fe3f63ddecc;p=yangtools.git diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangModelDependencyInfo.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangModelDependencyInfo.java index 40b1116fd8..c1d35a7b2c 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangModelDependencyInfo.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangModelDependencyInfo.java @@ -7,37 +7,37 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.repo; -import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; -import com.google.common.annotations.Beta; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; +import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableSet; import java.io.IOException; -import java.util.HashSet; +import java.util.Collection; +import java.util.Comparator; import java.util.Objects; import java.util.Optional; -import java.util.Set; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import org.opendaylight.yangtools.concepts.SemVer; -import org.opendaylight.yangtools.openconfig.model.api.OpenConfigStatements; -import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified; +import org.opendaylight.yangtools.yang.common.XMLNamespace; +import org.opendaylight.yangtools.yang.common.YangVersion; +import org.opendaylight.yangtools.yang.ir.IRKeyword; +import org.opendaylight.yangtools.yang.ir.IRStatement; +import org.opendaylight.yangtools.yang.ir.YangIRSchemaSource; import org.opendaylight.yangtools.yang.model.api.ModuleImport; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; +import org.opendaylight.yangtools.yang.model.api.meta.StatementSourceReference; +import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.ImportEffectiveStatement; -import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; -import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.model.spi.source.ModuleSourceInfo; +import org.opendaylight.yangtools.yang.model.spi.source.SourceInfo; +import org.opendaylight.yangtools.yang.model.spi.source.SourceInfo.Import; +import org.opendaylight.yangtools.yang.model.spi.source.SourceInfo.Include; +import org.opendaylight.yangtools.yang.model.spi.source.SubmoduleSourceInfo; +import org.opendaylight.yangtools.yang.model.spi.source.YangTextSource; import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException; -import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument; -import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRKeyword; -import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRKeyword.Unqualified; -import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource; -import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRStatement; import org.opendaylight.yangtools.yang.parser.spi.source.ExplicitStatement; -import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; /** * Helper transfer object which holds basic and dependency information for YANG @@ -53,54 +53,63 @@ import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReferenc * @see ModuleDependencyInfo * @see SubmoduleDependencyInfo */ -public abstract class YangModelDependencyInfo { +public abstract sealed class YangModelDependencyInfo { + /** + * Dependency information for a YANG module. + */ + public static final class ModuleDependencyInfo extends YangModelDependencyInfo { + private ModuleDependencyInfo(final String name, final Revision revision, + final ImmutableSet imports, final ImmutableSet includes) { + super(name, revision, imports, includes); + } + } + + /** + * Dependency information for a YANG submodule, also provides name for parent module. + */ + public static final class SubmoduleDependencyInfo extends YangModelDependencyInfo { + private final @NonNull Unqualified belongsTo; + + private SubmoduleDependencyInfo(final String name, final Revision revision, final Unqualified belongsTo, + final ImmutableSet imports, final ImmutableSet includes) { + super(name, revision, imports, includes); + this.belongsTo = requireNonNull(belongsTo); + } + + /** + * Returns name of parent module. + * + * @return The module this info belongs to + */ + public @NonNull Unqualified getParentModule() { + return belongsTo; + } + } + private static final String BELONGS_TO = YangStmtMapping.BELONGS_TO.getStatementName().getLocalName(); private static final String IMPORT = YangStmtMapping.IMPORT.getStatementName().getLocalName(); private static final String INCLUDE = YangStmtMapping.INCLUDE.getStatementName().getLocalName(); private static final String MODULE = YangStmtMapping.MODULE.getStatementName().getLocalName(); + private static final String NAMESPACE = YangStmtMapping.NAMESPACE.getStatementName().getLocalName(); + private static final String PREFIX = YangStmtMapping.PREFIX.getStatementName().getLocalName(); private static final String REVISION = YangStmtMapping.REVISION.getStatementName().getLocalName(); private static final String REVISION_DATE = YangStmtMapping.REVISION_DATE.getStatementName().getLocalName(); private static final String SUBMODULE = YangStmtMapping.SUBMODULE.getStatementName().getLocalName(); + private static final String YANG_VERSION = YangStmtMapping.YANG_VERSION.getStatementName().getLocalName(); - private static final String OPENCONFIG_VERSION = OpenConfigStatements.OPENCONFIG_VERSION.getStatementName() - .getLocalName(); - @Deprecated - private static final Splitter COLON_SPLITTER = Splitter.on(":").omitEmptyStrings().trimResults(); + private final @NonNull String name; + private final @Nullable Revision revision; + private final @NonNull ImmutableSet submoduleIncludes; + private final @NonNull ImmutableSet moduleImports; + private final @NonNull ImmutableSet dependencies; - private final String name; - private final Revision revision; - private final SemVer semVer; - private final ImmutableSet submoduleIncludes; - private final ImmutableSet moduleImports; - private final ImmutableSet dependencies; - - YangModelDependencyInfo(final String name, final String formattedRevision, - final ImmutableSet imports, + YangModelDependencyInfo(final String name, final Revision revision, final ImmutableSet imports, final ImmutableSet includes) { - this(name, formattedRevision, imports, includes, Optional.empty()); - } - - YangModelDependencyInfo(final String name, final String formattedRevision, - final ImmutableSet imports, - final ImmutableSet includes, - final Optional semVer) { - this.name = name; - this.revision = Revision.ofNullable(formattedRevision).orElse(null); - this.moduleImports = imports; - this.submoduleIncludes = includes; - this.dependencies = ImmutableSet.builder() - .addAll(moduleImports).addAll(submoduleIncludes).build(); - this.semVer = semVer.orElse(null); - } - - /** - * Returns immutable collection of all module imports. This collection contains both import statements - * and include statements for submodules. - * - * @return Immutable collection of imports. - */ - public ImmutableSet getDependencies() { - return dependencies; + this.name = requireNonNull(name); + this.revision = revision; + moduleImports = requireNonNull(imports); + submoduleIncludes = requireNonNull(includes); + dependencies = ImmutableSet.builder().addAll(moduleImports).addAll(submoduleIncludes).build(); } /** @@ -108,17 +117,18 @@ public abstract class YangModelDependencyInfo { * * @return model name */ - public String getName() { + public final String getName() { return name; } /** * Returns formatted revision string. * - * @return formatted revision string + * @return formatted revision string, or {@code null} */ - public String getFormattedRevision() { - return revision != null ? revision.toString() : null; + public final @Nullable String getFormattedRevision() { + final var local = revision; + return local != null ? local.toString() : null; } /** @@ -126,43 +136,38 @@ public abstract class YangModelDependencyInfo { * * @return revision, potentially null */ - public Optional getRevision() { + public final Optional getRevision() { return Optional.ofNullable(revision); } /** - * Returns semantic version of module. + * Returns immutable collection of all module imports. This collection contains both import statements + * and include statements for submodules. * - * @return semantic version + * @return Immutable collection of imports. */ - public Optional getSemanticVersion() { - return Optional.ofNullable(semVer); + public final ImmutableSet getDependencies() { + return dependencies; } @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Objects.hashCode(name); - result = prime * result + Objects.hashCode(revision); - result = prime * result + Objects.hashCode(semVer); - return result; + public final int hashCode() { + return Objects.hash(name, revision); } @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof YangModelDependencyInfo)) { - return false; - } - final YangModelDependencyInfo other = (YangModelDependencyInfo) obj; - return Objects.equals(name, other.name) && Objects.equals(revision, other.revision) - && Objects.equals(semVer, other.semVer); + public final boolean equals(final Object obj) { + return this == obj || obj instanceof YangModelDependencyInfo other + && Objects.equals(name, other.name) && Objects.equals(revision, other.revision); + } + + @Override + public final String toString() { + return MoreObjects.toStringHelper(this).omitNullValues() + .add("name", getName()) + .add("revision", getRevision()) + .add("dependencies", getDependencies()) + .toString(); } /** @@ -172,136 +177,159 @@ public abstract class YangModelDependencyInfo { * @return {@link YangModelDependencyInfo} * @throws IllegalArgumentException If the root statement is not a valid YANG module/submodule */ - public static @NonNull YangModelDependencyInfo forIR(final IRSchemaSource source) { - return forIR(source.getRootStatement(), source.getIdentifier()); + public static @NonNull YangModelDependencyInfo forIR(final YangIRSchemaSource source) { + return forIR(source.getRootStatement(), source.sourceId()); } /** * Extracts {@link YangModelDependencyInfo} from an intermediate representation root statement of a YANG model. * - * @param source Source identifier + * @param sourceId Source identifier * @param rootStatement root statement * @return {@link YangModelDependencyInfo} * @throws IllegalArgumentException If the root statement is not a valid YANG module/submodule */ static @NonNull YangModelDependencyInfo forIR(final IRStatement rootStatement, - final SourceIdentifier source) { - final IRKeyword keyword = rootStatement.keyword(); - checkArgument(keyword instanceof Unqualified, "Invalid root statement %s", keyword); + final SourceIdentifier sourceId) { + final var keyword = rootStatement.keyword(); + if (!(keyword instanceof IRKeyword.Unqualified)) { + throw new IllegalArgumentException("Invalid root statement " + keyword); + } final String arg = keyword.identifier(); if (MODULE.equals(arg)) { - return parseModuleContext(rootStatement, source); + return forSourceInfo(moduleForIR(rootStatement, sourceId)); } if (SUBMODULE.equals(arg)) { - return parseSubmoduleContext(rootStatement, source); + return forSourceInfo(submmoduleForIR(rootStatement, sourceId)); } throw new IllegalArgumentException("Root of parsed AST must be either module or submodule"); } - /** - * Extracts {@link YangModelDependencyInfo} from input stream containing a YANG model. This parsing does not - * validate full YANG module, only parses header up to the revisions and imports. - * - * @param refClass Base search class - * @param resourceName resource name, relative to refClass - * @return {@link YangModelDependencyInfo} - * @throws YangSyntaxErrorException If the resource does not pass syntactic analysis - * @throws IOException When the resource cannot be read - * @throws IllegalArgumentException - * If input stream is not valid YANG stream - * @deprecated This method was used by testing framework and was deemed to be potentially useful to the outside - * world. With Java Platform Module System, though, the resource loading rules have changed to the point - * where we no longer can guarantee it working correctly, as the results depend on the resource path. - * Users are advised to use {@link #forYangText(YangTextSchemaSource)}. - */ - @Deprecated(forRemoval = true) - public static YangModelDependencyInfo forResource(final Class refClass, final String resourceName) - throws IOException, YangSyntaxErrorException { - return forYangText(YangTextSchemaSource.forResource(refClass, resourceName)); + public static @NonNull YangModelDependencyInfo forSourceInfo(final SourceInfo info) { + if (info instanceof ModuleSourceInfo module) { + return forSourceInfo(module); + } else if (info instanceof SubmoduleSourceInfo submodule) { + return forSourceInfo(submodule); + } else { + throw new IllegalArgumentException("Unhandled source info " + requireNonNull(info)); + } + } + + public static @NonNull ModuleDependencyInfo forSourceInfo(final @NonNull ModuleSourceInfo info) { + return new ModuleDependencyInfo(info.name().getLocalName(), latestRevision(info.revisions()), + info.imports().stream().map(ModuleImportImpl::new).collect(ImmutableSet.toImmutableSet()), + info.includes().stream().map(ModuleImportImpl::new).collect(ImmutableSet.toImmutableSet())); + } + + public static @NonNull SubmoduleDependencyInfo forSourceInfo(final @NonNull SubmoduleSourceInfo info) { + return new SubmoduleDependencyInfo(info.name().getLocalName(), latestRevision(info.revisions()), + info.belongsTo(), info.imports().stream().map(ModuleImportImpl::new).collect(ImmutableSet.toImmutableSet()), + info.includes().stream().map(ModuleImportImpl::new).collect(ImmutableSet.toImmutableSet())); } /** - * Extracts {@link YangModelDependencyInfo} from a {@link YangTextSchemaSource}. This parsing does not - * validate full YANG module, only parses header up to the revisions and imports. + * Extracts {@link YangModelDependencyInfo} from a {@link YangTextSource}. This parsing does not validate full YANG + * module, only parses header up to the revisions and imports. * - * @param yangText {@link YangTextSchemaSource} + * @param yangText {@link YangTextSource} * @return {@link YangModelDependencyInfo} * @throws YangSyntaxErrorException If the resource does not pass syntactic analysis * @throws IOException When the resource cannot be read */ - public static YangModelDependencyInfo forYangText(final YangTextSchemaSource yangText) + public static YangModelDependencyInfo forYangText(final YangTextSource yangText) throws IOException, YangSyntaxErrorException { - final YangStatementStreamSource source = YangStatementStreamSource.create(yangText); + final var source = YangStatementStreamSource.create(yangText); return forIR(source.rootStatement(), source.getIdentifier()); } - private static @NonNull YangModelDependencyInfo parseModuleContext(final IRStatement module, - final SourceIdentifier source) { - final String name = safeStringArgument(source, module, "module name"); - final String latestRevision = getLatestRevision(module, source); - final Optional semVer = Optional.ofNullable(findSemanticVersion(module, source)); - final ImmutableSet imports = parseImports(module, source); - final ImmutableSet includes = parseIncludes(module, source); + private static @NonNull ModuleSourceInfo moduleForIR(final IRStatement root, final SourceIdentifier sourceId) { + return new ModuleSourceInfo(Unqualified.of(safeStringArgument(sourceId, root, "module name")), + extractYangVersion(root, sourceId), extractNamespace(root, sourceId), extractPrefix(root, sourceId), + extractRevisions(root, sourceId), extractImports(root, sourceId), extractIncludes(root, sourceId)); + } - return new ModuleDependencyInfo(name, latestRevision, imports, includes, semVer); + private static @NonNull SubmoduleSourceInfo submmoduleForIR(final IRStatement root, + final SourceIdentifier sourceId) { + return new SubmoduleSourceInfo(Unqualified.of(safeStringArgument(sourceId, root, "submodule name")), + extractYangVersion(root, sourceId), extractBelongsTo(root, sourceId), + extractRevisions(root, sourceId), extractImports(root, sourceId), extractIncludes(root, sourceId)); } - private static ImmutableSet parseImports(final IRStatement module, - final SourceIdentifier source) { - final Set result = new HashSet<>(); - for (final IRStatement substatement : module.statements()) { - if (isBuiltin(substatement, IMPORT)) { - final String importedModuleName = safeStringArgument(source, substatement, "imported module name"); - final String revisionDateStr = getRevisionDateString(substatement, source); - final Revision revisionDate = Revision.ofNullable(revisionDateStr).orElse(null); - final SemVer importSemVer = findSemanticVersion(substatement, source); - result.add(new ModuleImportImpl(importedModuleName, revisionDate, importSemVer)); - } - } - return ImmutableSet.copyOf(result); + private static @Nullable Revision latestRevision(final Collection revision) { + return revision.stream().sorted(Comparator.reverseOrder()).findFirst().orElse(null); } - @Beta - public static SemVer findSemanticVersion(final IRStatement statement, final SourceIdentifier source) { - String semVerString = null; - for (final IRStatement substatement : statement.statements()) { - // FIXME: this should also check we are using a prefix - if (OPENCONFIG_VERSION.equals(substatement.keyword().identifier())) { - semVerString = safeStringArgument(source, substatement, "version string"); - break; - } - } + private static YangVersion extractYangVersion(final IRStatement root, final SourceIdentifier sourceId) { + return root.statements().stream() + .filter(stmt -> isBuiltin(stmt, YANG_VERSION)) + .findFirst() + .map(stmt -> safeStringArgument(sourceId, stmt, "yang-version argument")) + .map(YangVersion::forString) + .orElse(YangVersion.VERSION_1); + } - return Strings.isNullOrEmpty(semVerString) ? null : SemVer.valueOf(semVerString); + private static @NonNull XMLNamespace extractNamespace(final IRStatement root, final SourceIdentifier sourceId) { + return root.statements().stream() + .filter(stmt -> isBuiltin(stmt, NAMESPACE)) + .findFirst() + .map(stmt -> safeStringArgument(sourceId, stmt, "namespace argument")) + .map(XMLNamespace::of) + .orElseThrow(() -> new IllegalArgumentException("No namespace statement in " + refOf(sourceId, root))); } - private static boolean isBuiltin(final IRStatement stmt, final String localName) { - final IRKeyword keyword = stmt.keyword(); - return keyword instanceof Unqualified && localName.equals(keyword.identifier()); + private static @NonNull String extractPrefix(final IRStatement root, final SourceIdentifier sourceId) { + return root.statements().stream() + .filter(stmt -> isBuiltin(stmt, PREFIX)) + .findFirst() + .map(stmt -> safeStringArgument(sourceId, stmt, "prefix argument")) + .orElseThrow(() -> new IllegalArgumentException("No prefix statement in " + refOf(sourceId, root))); } - private static ImmutableSet parseIncludes(final IRStatement module, final SourceIdentifier source) { - final Set result = new HashSet<>(); - for (final IRStatement substatement : module.statements()) { - if (isBuiltin(substatement, INCLUDE)) { - final String revisionDateStr = getRevisionDateString(substatement, source); - final String IncludeModuleName = safeStringArgument(source, substatement, "included submodule name"); - final Revision revisionDate = Revision.ofNullable(revisionDateStr).orElse(null); - result.add(new ModuleImportImpl(IncludeModuleName, revisionDate)); - } - } - return ImmutableSet.copyOf(result); + private static @NonNull Unqualified extractBelongsTo(final IRStatement root, final SourceIdentifier sourceId) { + return root.statements().stream() + .filter(stmt -> isBuiltin(stmt, BELONGS_TO)) + .findFirst() + .map(stmt -> Unqualified.of(safeStringArgument(sourceId, stmt, "belongs-to module name"))) + .orElseThrow(() -> new IllegalArgumentException("No belongs-to statement in " + refOf(sourceId, root))); } - private static String getRevisionDateString(final IRStatement importStatement, final SourceIdentifier source) { - String revisionDateStr = null; - for (final IRStatement substatement : importStatement.statements()) { - if (isBuiltin(substatement, REVISION_DATE)) { - revisionDateStr = safeStringArgument(source, substatement, "imported module revision-date"); - } - } - return revisionDateStr; + private static @NonNull ImmutableSet extractRevisions(final IRStatement root, + final SourceIdentifier sourceId) { + return root.statements().stream() + .filter(stmt -> isBuiltin(stmt, REVISION)) + .map(stmt -> Revision.of(safeStringArgument(sourceId, stmt, "revision argument"))) + .collect(ImmutableSet.toImmutableSet()); + } + + private static @Nullable Revision extractRevisionDate(final IRStatement root, final SourceIdentifier sourceId) { + return root.statements().stream() + .filter(stmt -> isBuiltin(stmt, REVISION_DATE)) + .findFirst() + .map(stmt -> Revision.of(safeStringArgument(sourceId, stmt, "revision date argument"))) + .orElse(null); + } + + private static @NonNull ImmutableSet extractImports(final IRStatement root, + final SourceIdentifier sourceId) { + return root.statements().stream() + .filter(stmt -> isBuiltin(stmt, IMPORT)) + .map(stmt -> new Import(Unqualified.of(safeStringArgument(sourceId, stmt, "imported module name")), + extractPrefix(stmt, sourceId), extractRevisionDate(stmt, sourceId))) + .collect(ImmutableSet.toImmutableSet()); + } + + private static @NonNull ImmutableSet extractIncludes(final IRStatement root, + final SourceIdentifier sourceId) { + return root.statements().stream() + .filter(stmt -> isBuiltin(stmt, INCLUDE)) + .map(stmt -> new Include(Unqualified.of(safeStringArgument(sourceId, stmt, "included submodule name")), + extractRevisionDate(stmt, sourceId))) + .collect(ImmutableSet.toImmutableSet()); + } + + private static boolean isBuiltin(final IRStatement stmt, final String localName) { + return stmt.keyword() instanceof IRKeyword.Unqualified keyword && localName.equals(keyword.identifier()); } public static String getLatestRevision(final IRStatement module, final SourceIdentifier source) { @@ -317,82 +345,20 @@ public abstract class YangModelDependencyInfo { return latestRevision; } - private static @NonNull YangModelDependencyInfo parseSubmoduleContext(final IRStatement submodule, - final SourceIdentifier source) { - final String name = safeStringArgument(source, submodule, "submodule name"); - final String belongsTo = parseBelongsTo(submodule, source); - - final String latestRevision = getLatestRevision(submodule, source); - final ImmutableSet imports = parseImports(submodule, source); - final ImmutableSet includes = parseIncludes(submodule, source); - - return new SubmoduleDependencyInfo(name, latestRevision, belongsTo, imports, includes); - } - - private static String parseBelongsTo(final IRStatement submodule, final SourceIdentifier source) { - for (final IRStatement substatement : submodule.statements()) { - if (isBuiltin(substatement, BELONGS_TO)) { - return safeStringArgument(source, substatement, "belongs-to module name"); - } + static @NonNull String safeStringArgument(final SourceIdentifier source, final IRStatement stmt, + final String desc) { + final var ref = refOf(source, stmt); + final var arg = stmt.argument(); + if (arg == null) { + throw new IllegalArgumentException("Missing " + desc + " at " + ref); } - return null; - } - static String safeStringArgument(final SourceIdentifier source, final IRStatement stmt, final String desc) { - final StatementSourceReference ref = getReference(source, stmt); - final IRArgument arg = stmt.argument(); - checkArgument(arg != null, "Missing %s at %s", desc, ref); // TODO: we probably need to understand yang version first.... return ArgumentContextUtils.rfc6020().stringFromStringContext(arg, ref); } - private static StatementSourceReference getReference(final SourceIdentifier source, final IRStatement stmt) { - return ExplicitStatement.atPosition(source.getName(), stmt.startLine(), stmt.startColumn() + 1); - } - - /** - * Dependency information for YANG module. - */ - public static final class ModuleDependencyInfo extends YangModelDependencyInfo { - ModuleDependencyInfo(final String name, final String latestRevision, final ImmutableSet imports, - final ImmutableSet includes, final Optional semVer) { - super(name, latestRevision, imports, includes, semVer); - } - - @Override - public String toString() { - return "Module [name=" + getName() + ", revision=" + getRevision() - + ", semanticVersion=" + getSemanticVersion().orElse(null) - + ", dependencies=" + getDependencies() - + "]"; - } - } - - /** - * Dependency information for submodule, also provides name for parent module. - */ - public static final class SubmoduleDependencyInfo extends YangModelDependencyInfo { - private final String belongsTo; - - private SubmoduleDependencyInfo(final String name, final String latestRevision, final String belongsTo, - final ImmutableSet imports, final ImmutableSet includes) { - super(name, latestRevision, imports, includes); - this.belongsTo = belongsTo; - } - - /** - * Returns name of parent module. - */ - public String getParentModule() { - return belongsTo; - } - - @Override - public String toString() { - return "Submodule [name=" + getName() + ", revision=" - + getRevision() + ", dependencies=" + getDependencies() - + "]"; - } + private static StatementSourceReference refOf(final SourceIdentifier source, final IRStatement stmt) { + return ExplicitStatement.atPosition(source.name().getLocalName(), stmt.startLine(), stmt.startColumn() + 1); } /** @@ -400,25 +366,22 @@ public abstract class YangModelDependencyInfo { */ // FIXME: this is a rather nasty misuse of APIs :( private static final class ModuleImportImpl implements ModuleImport { - + private final @NonNull Unqualified moduleName; private final Revision revision; - private final SemVer semVer; - private final String name; - ModuleImportImpl(final @NonNull String moduleName, final @Nullable Revision revision) { - this(moduleName, revision, null); + ModuleImportImpl(final Import importSpec) { + moduleName = importSpec.name(); + revision = importSpec.revision(); } - ModuleImportImpl(final @NonNull String moduleName, final @Nullable Revision revision, - final @Nullable SemVer semVer) { - this.name = requireNonNull(moduleName, "Module name must not be null."); - this.revision = revision; - this.semVer = semVer; + ModuleImportImpl(final Include includeSpec) { + moduleName = includeSpec.name(); + revision = includeSpec.revision(); } @Override - public String getModuleName() { - return name; + public Unqualified getModuleName() { + return moduleName; } @Override @@ -426,14 +389,9 @@ public abstract class YangModelDependencyInfo { return Optional.ofNullable(revision); } - @Override - public Optional getSemanticVersion() { - return Optional.ofNullable(semVer); - } - @Override public String getPrefix() { - return null; + throw new UnsupportedOperationException(); } @Override @@ -455,29 +413,20 @@ public abstract class YangModelDependencyInfo { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + Objects.hashCode(name); + result = prime * result + Objects.hashCode(moduleName); result = prime * result + Objects.hashCode(revision); - result = prime * result + Objects.hashCode(semVer); return result; } @Override public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof ModuleImportImpl)) { - return false; - } - final ModuleImportImpl other = (ModuleImportImpl) obj; - return name.equals(other.name) && Objects.equals(revision, other.revision) - && Objects.equals(getSemanticVersion(), other.getSemanticVersion()); + return this == obj || obj instanceof ModuleImportImpl other + && moduleName.equals(other.moduleName) && Objects.equals(revision, other.revision); } @Override public String toString() { - return "ModuleImportImpl [name=" + name + ", revision=" - + QName.formattedRevision(Optional.ofNullable(revision)) + ", semanticVersion=" + semVer + "]"; + return "ModuleImportImpl [name=" + moduleName + ", revision=" + revision + "]"; } } }