Refactor import statement implementations 01/87401/1
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 3 Feb 2020 09:41:56 +0000 (10:41 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 3 Feb 2020 18:55:45 +0000 (19:55 +0100)
Migrate Import(Effective)Statement to improve their memory footprint.

JIRA: YANGTOOLS-652
Change-Id: If469e5233783a5d3b011e7d86b8c88db885c54e9
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportEffectiveStatement.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ImportStatement.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/AbstractImportStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportEffectiveStatementImpl.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportStatementImpl.java

index ab7155a0e6f60083f82d76987cd8baa8cf1ca09b..9e2bc8cacd7149b33cff7f5b6aab3f965408f0e4 100644 (file)
@@ -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<String, ImportStatement> {
-
+    @Override
+    default StatementDefinition statementDefinition() {
+        return YangStmtMapping.IMPORT;
+    }
 }
index af00ae9285c537c83eaece4aee28c8e114d66d5c..68f6fc6c62100cf2c8b0a49bec20926aab6f1e89 100644 (file)
@@ -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<String> {
+    @Override
+    default StatementDefinition statementDefinition() {
+        return YangStmtMapping.IMPORT;
+    }
+
     default @NonNull String getModule() {
         // FIXME: YANGTOOLS-908: verifyNotNull() should not be needed here
         return verifyNotNull(rawArgument());
index d717328d4f129ff585e02af289b8f41504598d2d..788d455d28b929353c0b25fd3867612111950ca5 100644 (file)
@@ -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<String, ImportStatement, ImportEffectiveStatement> {
+        extends BaseStringStatementSupport<ImportStatement, ImportEffectiveStatement> {
     AbstractImportStatementSupport() {
         super(YangStmtMapping.IMPORT);
     }
@@ -41,17 +52,6 @@ abstract class AbstractImportStatementSupport
         return value;
     }
 
-    @Override
-    public final ImportStatement createDeclared(final StmtContext<String, ImportStatement, ?> ctx) {
-        return new ImportStatementImpl(ctx);
-    }
-
-    @Override
-    public final ImportEffectiveStatement createEffective(
-            final StmtContext<String, ImportStatement, ImportEffectiveStatement> ctx) {
-        return new ImportEffectiveStatementImpl(ctx);
-    }
-
     @Override
     public final void onPreLinkageDeclared(final Mutable<String, ImportStatement, ImportEffectiveStatement> stmt) {
         /*
@@ -99,4 +99,56 @@ abstract class AbstractImportStatementSupport
             RevisionImport.onLinkageDeclared(stmt);
         }
     }
+
+    @Override
+    protected final ImportStatement createDeclared(final StmtContext<String, ImportStatement, ?> ctx,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        return new ImportStatementImpl(ctx, substatements);
+    }
+
+    @Override
+    protected final ImportStatement createEmptyDeclared(final StmtContext<String, ImportStatement, ?> ctx) {
+        throw new IllegalStateException("Unexpected empty declared import statement");
+    }
+
+    @Override
+    protected final ImportEffectiveStatement createEffective(
+            final StmtContext<String, ImportStatement, ImportEffectiveStatement> ctx, final ImportStatement declared,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+
+        final String prefix = declared.getPrefix().getValue();
+        final SemVer semVer;
+        final Revision revision;
+        if (!ctx.isEnabledSemanticVersioning()) {
+            final Optional<Revision> 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<String, ImportStatement, ImportEffectiveStatement> ctx, final ImportStatement declared) {
+        throw new IllegalStateException("Unexpected empty effective import statement");
+    }
+
+    private static Revision getImportedRevision(final StmtContext<String, ImportStatement, ?> 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);
+    }
 }
index a780173b1a1b5fbbc7501d8256a034905042174d..d5f32734b50ccf12a51529fdd9c0dc5b604dd5d5 100644 (file)
@@ -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<String, ImportStatement>
-        implements ImportEffectiveStatement, ModuleImport {
+final class ImportEffectiveStatementImpl extends WithSubstatements<String, ImportStatement>
+        implements ImportEffectiveStatement, ModuleImport, DocumentedNodeMixin<String, ImportStatement> {
+    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<String, ImportStatement, ?> ctx) {
-        super(ctx);
-
-        moduleName = ctx.coerceStatementArgument();
-        final Optional<String> 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<Revision> 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<String, ImportStatement, ?> 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<? extends EffectiveStatement<?, ?>> 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();
     }
 }
index bb5ddc9f4dd2e43e061224e37b0edd85ef7c3b76..57ba2903133fd2b81473108ec17d9e24afb66505 100644 (file)
@@ -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<String> implements ImportStatement {
-    ImportStatementImpl(final StmtContext<String, ImportStatement,?> context) {
-        super(context);
+final class ImportStatementImpl extends WithSubstatements implements ImportStatement {
+    ImportStatementImpl(final StmtContext<String, ?, ?> context,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        super(context, substatements);
     }
 }