From: Robert Varga Date: Mon, 3 Feb 2020 09:41:56 +0000 (+0100) Subject: Refactor import statement implementations X-Git-Tag: v4.0.7~26 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=c100eff4dc330c32cc1bbf47635d9598ea1a1e43;p=yangtools.git Refactor import statement implementations Migrate Import(Effective)Statement to improve their memory footprint. JIRA: YANGTOOLS-652 Change-Id: If469e5233783a5d3b011e7d86b8c88db885c54e9 Signed-off-by: Robert Varga --- diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportEffectiveStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportEffectiveStatement.java index ab7155a0e6..9e2bc8cacd 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportEffectiveStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportEffectiveStatement.java @@ -8,9 +8,14 @@ package org.opendaylight.yangtools.yang.model.api.stmt; import com.google.common.annotations.Beta; +import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; @Beta public interface ImportEffectiveStatement extends EffectiveStatement { - + @Override + default StatementDefinition statementDefinition() { + return YangStmtMapping.IMPORT; + } } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportStatement.java index af00ae9285..68f6fc6c62 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportStatement.java @@ -12,8 +12,15 @@ import static com.google.common.base.Verify.verifyNotNull; import java.util.Optional; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; +import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; public interface ImportStatement extends DocumentedDeclaredStatement { + @Override + default StatementDefinition statementDefinition() { + return YangStmtMapping.IMPORT; + } + default @NonNull String getModule() { // FIXME: YANGTOOLS-908: verifyNotNull() should not be needed here return verifyNotNull(rawArgument()); diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/AbstractImportStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/AbstractImportStatementSupport.java index d717328d4f..788d455d28 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/AbstractImportStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/AbstractImportStatementSupport.java @@ -11,14 +11,23 @@ import static org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPha import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf; import com.google.common.base.Verify; +import com.google.common.collect.ImmutableList; import java.net.URI; import java.util.Collection; +import java.util.Optional; +import org.opendaylight.yangtools.concepts.SemVer; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; +import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ImportEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement; import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateEffectiveStatement; +import org.opendaylight.yangtools.yang.model.repo.api.SemVerSourceIdentifier; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseStringStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.PreLinkageModuleNamespace; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction; @@ -26,12 +35,14 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Infere import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToNamespace; +import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToSemVerSourceIdentifier; import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToNamespace; import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; abstract class AbstractImportStatementSupport - extends AbstractStatementSupport { + extends BaseStringStatementSupport { AbstractImportStatementSupport() { super(YangStmtMapping.IMPORT); } @@ -41,17 +52,6 @@ abstract class AbstractImportStatementSupport return value; } - @Override - public final ImportStatement createDeclared(final StmtContext ctx) { - return new ImportStatementImpl(ctx); - } - - @Override - public final ImportEffectiveStatement createEffective( - final StmtContext ctx) { - return new ImportEffectiveStatementImpl(ctx); - } - @Override public final void onPreLinkageDeclared(final Mutable stmt) { /* @@ -99,4 +99,56 @@ abstract class AbstractImportStatementSupport RevisionImport.onLinkageDeclared(stmt); } } + + @Override + protected final ImportStatement createDeclared(final StmtContext ctx, + final ImmutableList> substatements) { + return new ImportStatementImpl(ctx, substatements); + } + + @Override + protected final ImportStatement createEmptyDeclared(final StmtContext ctx) { + throw new IllegalStateException("Unexpected empty declared import statement"); + } + + @Override + protected final ImportEffectiveStatement createEffective( + final StmtContext ctx, final ImportStatement declared, + final ImmutableList> substatements) { + + final String prefix = declared.getPrefix().getValue(); + final SemVer semVer; + final Revision revision; + if (!ctx.isEnabledSemanticVersioning()) { + final Optional optRev = substatements.stream() + .filter(RevisionDateEffectiveStatement.class::isInstance) + .findFirst() + .map(stmt -> ((RevisionDateEffectiveStatement) stmt).argument()); + revision = optRev.isPresent() ? optRev.get() : getImportedRevision(ctx, declared.getModule(), prefix); + semVer = null; + } else { + final SemVerSourceIdentifier importedModuleIdentifier = ctx.getFromNamespace( + ImportPrefixToSemVerSourceIdentifier.class, prefix); + revision = importedModuleIdentifier.getRevision().orElse(null); + semVer = importedModuleIdentifier.getSemanticVersion().orElse(null); + } + + return new ImportEffectiveStatementImpl(declared, substatements, revision, semVer); + } + + @Override + protected final ImportEffectiveStatement createEmptyEffective( + final StmtContext ctx, final ImportStatement declared) { + throw new IllegalStateException("Unexpected empty effective import statement"); + } + + private static Revision getImportedRevision(final StmtContext ctx, + final String moduleName, final String prefix) { + // When 'revision-date' of an import is not specified in yang source, we need to find revision of imported + // module. + final QNameModule importedModule = StmtContextUtils.getModuleQNameByPrefix(ctx, prefix); + SourceException.throwIfNull(importedModule, ctx.getStatementSourceReference(), + "Unable to find import of module %s with prefix %s.", moduleName, prefix); + return importedModule.getRevision().orElse(null); + } } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportEffectiveStatementImpl.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportEffectiveStatementImpl.java index a780173b1a..d5f32734b5 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportEffectiveStatementImpl.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportEffectiveStatementImpl.java @@ -8,68 +8,35 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.import_; import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; import java.util.Objects; import java.util.Optional; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.concepts.SemVer; -import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.model.api.ModuleImport; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ImportEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.PrefixEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateEffectiveStatement; -import org.opendaylight.yangtools.yang.model.repo.api.SemVerSourceIdentifier; -import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveDocumentedNodeWithoutStatus; -import org.opendaylight.yangtools.yang.parser.spi.meta.MissingSubstatementException; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; -import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToSemVerSourceIdentifier; -import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveStatement.DefaultArgument.WithSubstatements; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.DocumentedNodeMixin; -final class ImportEffectiveStatementImpl extends AbstractEffectiveDocumentedNodeWithoutStatus - implements ImportEffectiveStatement, ModuleImport { +final class ImportEffectiveStatementImpl extends WithSubstatements + implements ImportEffectiveStatement, ModuleImport, DocumentedNodeMixin { + private final @Nullable Revision revision; + private final @Nullable SemVer semVer; - private final String moduleName; - private final Revision revision; - private final SemVer semVer; - private final String prefix; - - ImportEffectiveStatementImpl(final StmtContext ctx) { - super(ctx); - - moduleName = ctx.coerceStatementArgument(); - final Optional prefixStmt = findFirstEffectiveSubstatementArgument(PrefixEffectiveStatement.class); - MissingSubstatementException.throwIf(!prefixStmt.isPresent(), ctx.getStatementSourceReference(), - "Prefix is mandatory substatement of import statement"); - this.prefix = prefixStmt.get(); - - if (!ctx.isEnabledSemanticVersioning()) { - final Optional optRev = findFirstEffectiveSubstatementArgument( - RevisionDateEffectiveStatement.class); - this.revision = optRev.isPresent() ? optRev.get() : getImportedRevision(ctx); - this.semVer = null; - } else { - final SemVerSourceIdentifier importedModuleIdentifier = ctx.getFromNamespace( - ImportPrefixToSemVerSourceIdentifier.class, prefix); - revision = importedModuleIdentifier.getRevision().orElse(null); - semVer = importedModuleIdentifier.getSemanticVersion().orElse(null); - } - } - - private Revision getImportedRevision(final StmtContext ctx) { - /* - * When 'revision-date' of an import is not specified in yang source, we - * need to find revision of imported module. - */ - final QNameModule importedModule = StmtContextUtils.getModuleQNameByPrefix(ctx, this.prefix); - SourceException.throwIfNull(importedModule, ctx.getStatementSourceReference(), - "Unable to find import of module %s with prefix %s.", this.moduleName, this.prefix); - return importedModule.getRevision().orElse(null); + ImportEffectiveStatementImpl(final ImportStatement declared, + final ImmutableList> substatements, + final @Nullable Revision revision, final @Nullable SemVer semVer) { + super(declared, substatements); + this.revision = revision; + this.semVer = semVer; } @Override public String getModuleName() { - return moduleName; + return argument(); } @Override @@ -84,12 +51,13 @@ final class ImportEffectiveStatementImpl extends AbstractEffectiveDocumentedNode @Override public String getPrefix() { - return prefix; + return getDeclared().getPrefix().getValue(); } @Override public int hashCode() { - return Objects.hash(moduleName, revision, prefix, semVer, nullableDescription(), nullableReference()); + return Objects.hash(getModuleName(), revision, getPrefix(), semVer, getDescription().orElse(null), + getReference().orElse(null)); } @Override @@ -104,16 +72,21 @@ final class ImportEffectiveStatementImpl extends AbstractEffectiveDocumentedNode return false; } final ImportEffectiveStatementImpl other = (ImportEffectiveStatementImpl) obj; - return Objects.equals(moduleName, other.moduleName) && Objects.equals(revision, other.revision) - && Objects.equals(semVer, other.semVer) && Objects.equals(prefix, other.prefix) - && Objects.equals(nullableDescription(), other.nullableDescription()) - && Objects.equals(nullableReference(), other.nullableReference()); + return Objects.equals(getModuleName(), other.getModuleName()) && Objects.equals(revision, other.revision) + && Objects.equals(semVer, other.semVer) && Objects.equals(getPrefix(), other.getPrefix()) + && Objects.equals(getDescription(), other.getDescription()) + && Objects.equals(getReference(), other.getReference()); } @Override public String toString() { - return MoreObjects.toStringHelper(this).omitNullValues().add("moduleName", getModuleName()) - .add("revision", revision).add("version", semVer).add("prefix", getPrefix()) - .add("description", nullableDescription()).add("reference", nullableReference()).toString(); + return MoreObjects.toStringHelper(this).omitNullValues() + .add("moduleName", getModuleName()) + .add("revision", revision) + .add("version", semVer) + .add("prefix", getPrefix()) + .add("description", getDescription().orElse(null)) + .add("reference", getReference().orElse(null)) + .toString(); } } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportStatementImpl.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportStatementImpl.java index bb5ddc9f4d..57ba290313 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportStatementImpl.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportStatementImpl.java @@ -7,12 +7,15 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.import_; +import com.google.common.collect.ImmutableList; +import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithRawStringArgument.WithSubstatements; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -final class ImportStatementImpl extends AbstractDeclaredStatement implements ImportStatement { - ImportStatementImpl(final StmtContext context) { - super(context); +final class ImportStatementImpl extends WithSubstatements implements ImportStatement { + ImportStatementImpl(final StmtContext context, + final ImmutableList> substatements) { + super(context, substatements); } }