Refactor {Module,Submodule}EffectiveStatementImpl 02/87502/7
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 3 Jul 2020 09:56:35 +0000 (11:56 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sat, 4 Jul 2020 11:13:51 +0000 (13:13 +0200)
Modules and submodules are tied together via AbstractEffectiveModule,
which holds on to old layout. While it is not directly harmful to
these implementations, having statement creation outside of actual
constructors is a long-term goal.

Refactor AbstractEffectiveModule and thus both implementations to
create substatements separately in BaseStatementSupport.

The inlining of submodule statements is hooked into
BaseStatementSupport lifecycle via buildEffectiveSubstatements(),
so that modules can stop mucking with statement build rules and just
pick up whatever was created for the corresponding submodule.

For declared statements we introduce AbstractDeclaredEffectiveRootStatement
as a replacement for AbstractRootStatement, which is now deprecated
for removal.

JIRA: YANGTOOLS-1065
Change-Id: I032bb1ea4f2ee5db87d9b0dbbdeb89f152bc4593
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
16 files changed:
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleEffectiveStatement.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleStatement.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SubmoduleEffectiveStatement.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SubmoduleStatement.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractDeclaredEffectiveRootStatement.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractDeclaredStatement.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveModule.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractRootStatement.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/BaseStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/AbstractModuleStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleEffectiveStatementImpl.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleStatementImpl.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleStmtContext.java [deleted file]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/submodule/AbstractSubmoduleStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/submodule/SubmoduleEffectiveStatementImpl.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/submodule/SubmoduleStatementImpl.java

index bb6053b92109c3b8d7951d87c4f77912408480c7..e13d3776b3c520e6935d394d801833c86ebe6712 100644 (file)
@@ -10,7 +10,9 @@ package org.opendaylight.yangtools.yang.model.api.stmt;
 import com.google.common.annotations.Beta;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 /**
  * Effective view of a {@link ModuleStatement}.
@@ -52,6 +54,11 @@ public interface ModuleEffectiveStatement extends DataTreeAwareEffectiveStatemen
         }
     }
 
+    @Override
+    default StatementDefinition statementDefinition() {
+        return YangStmtMapping.MODULE;
+    }
+
     /**
      * Get the local QNameModule of this module. All implementations need to override this default method.
      *
index 693926fc6b5ccf4b908346b3b509055d5f10ca82..6a4aae3938ac11ab9d308597988e7ab4dfa87e87 100644 (file)
@@ -11,9 +11,16 @@ import static com.google.common.base.Verify.verifyNotNull;
 
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 public interface ModuleStatement extends MetaDeclaredStatement<String>, ModuleHeaderGroup, LinkageDeclaredStatement,
         RevisionAwareDeclaredStatement, BodyDeclaredStatement {
+    @Override
+    default StatementDefinition statementDefinition() {
+        return YangStmtMapping.MODULE;
+    }
+
     default @NonNull String getName() {
         // FIXME: YANGTOOLS-908: verifyNotNull() should not be needed here
         return verifyNotNull(rawArgument());
index 65993c39c4b80f2e425d23ae2b8b27bc89227401..24c7716aab55fd83425ca916741f5424babeaa65 100644 (file)
@@ -8,6 +8,8 @@
 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.StatementDefinition;
 
 /**
  * Representation of {@code submodule} statement. Note that implementations of this interface are required to provide
@@ -16,5 +18,8 @@ import com.google.common.annotations.Beta;
  */
 @Beta
 public interface SubmoduleEffectiveStatement extends DataTreeAwareEffectiveStatement<String, SubmoduleStatement> {
-
+    @Override
+    default StatementDefinition statementDefinition() {
+        return YangStmtMapping.SUBMODULE;
+    }
 }
index 2e003dbdea300d4eccd2d908f05a4383231933c2..468ad243882fb670570a26f06a33b758db171ee4 100644 (file)
@@ -12,9 +12,16 @@ 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 SubmoduleStatement extends MetaDeclaredStatement<String>, LinkageDeclaredStatement,
         RevisionAwareDeclaredStatement, BodyDeclaredStatement {
+    @Override
+    default StatementDefinition statementDefinition() {
+        return YangStmtMapping.SUBMODULE;
+    }
+
     default @NonNull String getName() {
         // 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/AbstractDeclaredEffectiveRootStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractDeclaredEffectiveRootStatement.java
new file mode 100644 (file)
index 0000000..60fb169
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BodyDeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LinkageDeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MetaDeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RevisionAwareDeclaredStatement;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithRawStringArgument.WithSubstatements;
+
+@Beta
+public abstract class AbstractDeclaredEffectiveRootStatement<D extends DeclaredStatement<String>>
+        extends WithSubstatements implements LinkageDeclaredStatement, MetaDeclaredStatement<String>,
+                RevisionAwareDeclaredStatement, BodyDeclaredStatement {
+    protected AbstractDeclaredEffectiveRootStatement(final String rawArgument,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        super(rawArgument, substatements);
+    }
+}
index 8a713abe4089cc5e91652c974e70e1b3bd0568c7..4e0a7bffbb4ee16c80807faecf030d0b06d19aca 100644 (file)
@@ -113,6 +113,12 @@ public abstract class AbstractDeclaredStatement<A> extends AbstractModelStatemen
                 this.substatements = maskList(substatements);
             }
 
+            protected WithSubstatements(final String rawArgument,
+                    final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+                super(rawArgument);
+                this.substatements = maskList(substatements);
+            }
+
             @Override
             public final Collection<? extends DeclaredStatement<?>> declaredSubstatements() {
                 return unmaskList(substatements);
index b5c519eb8ddf96bb4cba7a4a82680e09e87db476..376bf624eecbc312b567a6611ff68100512d5119 100644 (file)
@@ -13,6 +13,7 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.collect.ImmutableSet;
@@ -54,6 +55,8 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStateme
 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.compat.NotificationNodeContainerCompat;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithSubstatements;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.DocumentedNodeMixin;
 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.ImportPrefixToModuleCtx;
@@ -61,19 +64,18 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 @Beta
 public abstract class AbstractEffectiveModule<D extends DeclaredStatement<String>,
-        E extends DataTreeAwareEffectiveStatement<String, D>>
-        extends AbstractEffectiveDocumentedNodeWithStatus<String, D>
-        implements Module, NotificationNodeContainerCompat<String, D, E> {
+        E extends DataTreeAwareEffectiveStatement<String, D>> extends WithSubstatements<String, D, E>
+        implements Module, DocumentedNodeMixin<String, D>, NotificationNodeContainerCompat<String, D, E> {
     private final String prefix;
     private final ImmutableSet<GroupingDefinition> groupings;
     private final ImmutableSet<UsesNode> uses;
     private final ImmutableSet<TypeDefinition<?>> typeDefinitions;
     private final ImmutableMap<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace;
 
-    protected AbstractEffectiveModule(
-            final @NonNull StmtContext<String, D, ? extends EffectiveStatement<String, ?>> ctx,
-            final @NonNull String prefix) {
-        super(ctx);
+    protected AbstractEffectiveModule(final D declared,
+            final StmtContext<String, D, ? extends EffectiveStatement<String, ?>> ctx,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements, final String prefix) {
+        super(declared, ctx, substatements);
 
         // This check is rather weird, but comes from our desire to lower memory footprint while providing both
         // EffectiveStatements and SchemaNode interfaces -- which do not overlap completely where child lookups are
@@ -112,6 +114,11 @@ public abstract class AbstractEffectiveModule<D extends DeclaredStatement<String
         this.uses = ImmutableSet.copyOf(mutableUses);
     }
 
+    @Override
+    public String argument() {
+        return getDeclared().argument();
+    }
+
     @Override
     public String getName() {
         return argument();
index f6c28f072531b8638bcaee4d075979fc8bc647b1..45be5ef1cd1bbe946fabc80df9019814381ceb31 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.RevisionAwareDeclaredState
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
+@Deprecated(forRemoval = true)
 public abstract class AbstractRootStatement<T extends DeclaredStatement<String>>
         extends AbstractDeclaredStatement<String> implements LinkageDeclaredStatement, MetaDeclaredStatement<String>,
         RevisionAwareDeclaredStatement, BodyDeclaredStatement {
index 941eb12d9ece976d5e501fdb6a1dc1b23564a92e..3cab48caee0b6cf1560ad2828fbbdab45d867947 100644 (file)
@@ -57,7 +57,7 @@ public abstract class BaseStatementSupport<A, D extends DeclaredStatement<A>,
     public final E createEffective(final StmtContext<A, D, E> ctx) {
         final D declared = ctx.buildDeclared();
         final ImmutableList<? extends EffectiveStatement<?, ?>> substatements =
-                buildEffectiveSubstatements(statementsToBuild(ctx, declaredSubstatements(ctx)));
+                buildEffectiveSubstatements(ctx, statementsToBuild(ctx, declaredSubstatements(ctx)));
         return substatements.isEmpty() ? createEmptyEffective(ctx, declared)
                 : createEffective(ctx, declared, substatements);
     }
@@ -97,13 +97,24 @@ public abstract class BaseStatementSupport<A, D extends DeclaredStatement<A>,
     }
 
     /**
-     * Create a set of substatements. This method is split out so it can be overridden in
-     * ExtensionEffectiveStatementImpl to leak a not-fully-initialized instance.
+     * Create a set of substatements. This method is split out so it can be overridden in subclasses adjust the
+     * resulting statements.
      *
+     * @param ctx Parent statement context
      * @param substatements proposed substatements
-     * @return Filtered substatements
+     * @return Built effective substatements
      */
-    private static ImmutableList<? extends EffectiveStatement<?, ?>> buildEffectiveSubstatements(
+    protected ImmutableList<? extends EffectiveStatement<?, ?>> buildEffectiveSubstatements(
+            final StmtContext<A, D, E> ctx, final List<? extends StmtContext<?, ?, ?>> substatements) {
+        return defaultBuildEffectiveSubstatements(substatements);
+    }
+
+    static final ImmutableList<? extends EffectiveStatement<?, ?>> buildEffectiveSubstatements(
+            final StmtContext<?, ?, ?> ctx) {
+        return defaultBuildEffectiveSubstatements(declaredSubstatements(ctx));
+    }
+
+    private static ImmutableList<? extends EffectiveStatement<?, ?>> defaultBuildEffectiveSubstatements(
             final List<? extends StmtContext<?, ?, ?>> substatements) {
         return substatements.stream()
                 .filter(StmtContext::isSupportedToBuildEffective)
@@ -111,11 +122,6 @@ public abstract class BaseStatementSupport<A, D extends DeclaredStatement<A>,
                 .collect(ImmutableList.toImmutableList());
     }
 
-    static final ImmutableList<? extends EffectiveStatement<?, ?>> buildEffectiveSubstatements(
-            final StmtContext<?, ?, ?> ctx) {
-        return buildEffectiveSubstatements(declaredSubstatements(ctx));
-    }
-
     static final @NonNull List<StmtContext<?, ?, ?>> declaredSubstatements(final StmtContext<?, ?, ?> ctx) {
         /*
          * This dance is required to ensure that effects of 'uses' nodes are applied in the same order as
index 09d0ce8e674b43d367b6760a79d8d8690b69df16..bfeacc7b82f955cfc9500f300fffb124edbad083 100644 (file)
@@ -7,14 +7,25 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module;
 
+import static com.google.common.base.Verify.verify;
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
 
+import com.google.common.collect.ImmutableList;
 import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 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.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 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.ModuleEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
@@ -22,10 +33,10 @@ import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
 import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SemVerSourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
 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.SemanticVersionModuleNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.SemanticVersionNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
@@ -33,6 +44,7 @@ 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.ImportPrefixToModuleCtx;
+import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToModuleCtx;
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToSourceIdentifier;
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
@@ -43,7 +55,7 @@ import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 abstract class AbstractModuleStatementSupport
-        extends AbstractStatementSupport<String, ModuleStatement, ModuleEffectiveStatement> {
+        extends BaseStatementSupport<String, ModuleStatement, ModuleEffectiveStatement> {
     AbstractModuleStatementSupport() {
         super(YangStmtMapping.MODULE);
     }
@@ -53,17 +65,6 @@ abstract class AbstractModuleStatementSupport
         return value;
     }
 
-    @Override
-    public final ModuleStatement createDeclared(final StmtContext<String, ModuleStatement, ?> ctx) {
-        return new ModuleStatementImpl(ctx);
-    }
-
-    @Override
-    public final ModuleEffectiveStatement createEffective(
-            final StmtContext<String, ModuleStatement, ModuleEffectiveStatement> ctx) {
-        return new ModuleEffectiveStatementImpl(ctx);
-    }
-
     @Override
     public final void onPreLinkageDeclared(final Mutable<String, ModuleStatement, ModuleEffectiveStatement> stmt) {
         final String moduleName = stmt.getStatementArgument();
@@ -127,6 +128,74 @@ abstract class AbstractModuleStatementSupport
         }
     }
 
+    @Override
+    protected final ImmutableList<? extends EffectiveStatement<?, ?>> buildEffectiveSubstatements(
+            final StmtContext<String, ModuleStatement, ModuleEffectiveStatement> ctx,
+            final List<? extends StmtContext<?, ?, ?>> substatements) {
+        final ImmutableList<? extends EffectiveStatement<?, ?>> local =
+                super.buildEffectiveSubstatements(ctx, substatements);
+        final Collection<StmtContext<?, ?, ?>> submodules = submoduleContexts(ctx);
+        if (submodules.isEmpty()) {
+            return local;
+        }
+
+        // Concatenate statements so they appear as if they were part of target module
+        final List<EffectiveStatement<?, ?>> others = new ArrayList<>();
+        for (StmtContext<?, ?, ?> submoduleCtx : submodules) {
+            for (EffectiveStatement<?, ?> effective : submoduleCtx.buildEffective().effectiveSubstatements()) {
+                if (effective instanceof SchemaNode || effective instanceof DataNodeContainer) {
+                    others.add(effective);
+                }
+            }
+        }
+
+        return ImmutableList.<EffectiveStatement<?, ?>>builderWithExpectedSize(local.size() + others.size())
+                .addAll(local)
+                .addAll(others)
+                .build();
+    }
+
+    @Override
+    protected final ModuleStatement createDeclared(final StmtContext<String, ModuleStatement, ?> ctx,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        return new ModuleStatementImpl(ctx.coerceRawStatementArgument(), substatements);
+    }
+
+    @Override
+    protected final ModuleStatement createEmptyDeclared(final StmtContext<String, ModuleStatement, ?> ctx) {
+        throw noNamespace(ctx);
+    }
+
+    @Override
+    protected final ModuleEffectiveStatement createEffective(
+            final StmtContext<String, ModuleStatement, ModuleEffectiveStatement> ctx,
+            final ModuleStatement declared, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        final List<Module> submodules = new ArrayList<>();
+        for (StmtContext<?, ?, ?> submoduleCtx : submoduleContexts(ctx)) {
+            final EffectiveStatement<?, ?> submodule = submoduleCtx.buildEffective();
+            verify(submodule instanceof Module, "Submodule statement %s is not a Module", submodule);
+            submodules.add((Module) submodule);
+        }
+
+        return new ModuleEffectiveStatementImpl(ctx, declared, substatements, submodules);
+    }
+
+    @Override
+    protected final ModuleEffectiveStatement createEmptyEffective(
+            final StmtContext<String, ModuleStatement, ModuleEffectiveStatement> ctx, final ModuleStatement declared) {
+        throw noNamespace(ctx);
+    }
+
+    private static Collection<StmtContext<?, ?, ?>> submoduleContexts(final StmtContext<?, ?, ?> ctx) {
+        final Map<String, StmtContext<?, ?, ?>> submodules = ctx.getAllFromCurrentStmtCtxNamespace(
+            IncludedSubmoduleNameToModuleCtx.class);
+        return submodules == null ? List.of() : submodules.values();
+    }
+
+    private static SourceException noNamespace(final StmtContext<?, ?, ?> ctx) {
+        return new SourceException("No namespace declared in module", ctx.getStatementSourceReference());
+    }
+
     private static void addToSemVerModuleNamespace(
             final Mutable<String, ModuleStatement, ModuleEffectiveStatement> stmt,
             final SourceIdentifier moduleIdentifier) {
index d6a9a160812bd30835ee6b49c6d85d20eb8a42cb..26a73b4e641d7c88a9a0d366c359bd34b958ccf4 100644 (file)
@@ -9,10 +9,11 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module;
 
 import static com.google.common.base.Verify.verifyNotNull;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
+import java.util.Collection;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
@@ -20,6 +21,7 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionEffectiveStatementNamespace;
@@ -51,13 +53,15 @@ final class ModuleEffectiveStatementImpl extends AbstractEffectiveModule<ModuleS
     private final ImmutableMap<String, ModuleEffectiveStatement> prefixToModule;
     private final ImmutableMap<QNameModule, String> namespaceToPrefix;
     private final @NonNull QNameModule qnameModule;
-    private final ImmutableSet<Module> submodules;
+    private final ImmutableList<Module> submodules;
 
-    private ModuleEffectiveStatementImpl(final @NonNull ModuleStmtContext ctx) {
-        super(ctx, findPrefix(ctx.delegate(), "module", ctx.getStatementArgument()));
-        submodules = ctx.getSubmodules();
+    ModuleEffectiveStatementImpl(final StmtContext<String, ModuleStatement, ModuleEffectiveStatement> ctx,
+            final ModuleStatement declared, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements,
+            final Collection<? extends Module> submodules) {
+        super(declared, ctx, substatements, findPrefix(ctx, "module", ctx.getStatementArgument()));
 
-        qnameModule = verifyNotNull(ctx.getFromNamespace(ModuleCtxToModuleQName.class, ctx.delegate()));
+        qnameModule = verifyNotNull(ctx.getFromNamespace(ModuleCtxToModuleQName.class, ctx));
+        this.submodules = ImmutableList.copyOf(submodules);
 
         final String localPrefix = findFirstEffectiveSubstatementArgument(PrefixEffectiveStatement.class).get();
         final Builder<String, ModuleEffectiveStatement> prefixToModuleBuilder = ImmutableMap.builder();
@@ -92,10 +96,6 @@ final class ModuleEffectiveStatementImpl extends AbstractEffectiveModule<ModuleS
                 : ImmutableMap.copyOf(Maps.transformValues(identities, StmtContext::buildEffective));
     }
 
-    ModuleEffectiveStatementImpl(final StmtContext<String, ModuleStatement, ModuleEffectiveStatement> ctx) {
-        this(ModuleStmtContext.create(ctx));
-    }
-
     @Override
     public @NonNull QNameModule localQNameModule() {
         return qnameModule;
@@ -107,7 +107,7 @@ final class ModuleEffectiveStatementImpl extends AbstractEffectiveModule<ModuleS
     }
 
     @Override
-    public ImmutableSet<Module> getSubmodules() {
+    public Collection<? extends Module> getSubmodules() {
         return submodules;
     }
 
index e358e6b01962fa81898d4f19af2efc2fe55f4ce7..fab4de6aeff99c02ea3dbd970d1af8d6388b642a 100644 (file)
@@ -7,12 +7,15 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module;
 
+import com.google.common.collect.ImmutableList;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
-import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractRootStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveRootStatement;
 
-final class ModuleStatementImpl extends AbstractRootStatement<ModuleStatement> implements ModuleStatement {
-    ModuleStatementImpl(final StmtContext<String, ModuleStatement,?> context) {
-        super(context);
+final class ModuleStatementImpl extends AbstractDeclaredEffectiveRootStatement<ModuleStatement>
+        implements ModuleStatement {
+    ModuleStatementImpl(final String rawArgument,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        super(rawArgument, substatements);
     }
 }
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleStmtContext.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleStmtContext.java
deleted file mode 100644 (file)
index d5e7e14..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module;
-
-import static com.google.common.base.Verify.verify;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ForwardingObject;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.yang.common.YangVersion;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToModuleCtx;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
-
-/**
- * A concentrator {@link StmtContext}, which makes it appear as though as all effective statements in submodules
- * are included in it.
- */
-final class ModuleStmtContext extends ForwardingObject
-        implements StmtContext<String, ModuleStatement, ModuleEffectiveStatement> {
-
-    private final @NonNull StmtContext<String, ModuleStatement, ModuleEffectiveStatement> delegate;
-    private final @NonNull ImmutableList<StmtContext<?, ?, ?>> effectiveSubstatements;
-    private final @NonNull ImmutableSet<Module> submodules;
-
-    private ModuleStmtContext(final StmtContext<String, ModuleStatement, ModuleEffectiveStatement> delegate,
-            final Collection<StmtContext<?, ?, ?>> submodules) {
-        this.delegate = requireNonNull(delegate);
-
-        final List<StmtContext<?, ?, ?>> statements = new ArrayList<>(delegate.effectiveSubstatements());
-        final Set<Module> subs = new LinkedHashSet<>(submodules.size());
-        for (StmtContext<?, ?, ?> submoduleCtx : submodules) {
-            final EffectiveStatement<?, ?> submodule = submoduleCtx.buildEffective();
-            verify(submodule instanceof Module, "Submodule statement %s is not a Module", submodule);
-            subs.add((Module) submodule);
-
-            for (StmtContext<?, ?, ?> stmt : submoduleCtx.allSubstatements()) {
-                if (stmt.isSupportedByFeatures()) {
-                    final EffectiveStatement<?, ?> effective = stmt.buildEffective();
-                    if (effective instanceof SchemaNode || effective instanceof DataNodeContainer) {
-                        statements.add(stmt);
-                    }
-                }
-            }
-        }
-
-        this.effectiveSubstatements = ImmutableList.copyOf(statements);
-        this.submodules = ImmutableSet.copyOf(subs);
-    }
-
-    static @NonNull ModuleStmtContext create(
-            final StmtContext<String, ModuleStatement, ModuleEffectiveStatement> delegate) {
-        final Map<String, StmtContext<?, ?, ?>> includedSubmodules = delegate.getAllFromCurrentStmtCtxNamespace(
-            IncludedSubmoduleNameToModuleCtx.class);
-        return new ModuleStmtContext(delegate, includedSubmodules == null || includedSubmodules.isEmpty()
-                ? ImmutableList.of() : includedSubmodules.values());
-    }
-
-    @Override
-    protected @NonNull StmtContext<String, ModuleStatement, ModuleEffectiveStatement> delegate() {
-        return delegate;
-    }
-
-    ImmutableSet<Module> getSubmodules() {
-        return submodules;
-    }
-
-    @Override
-    public ImmutableList<StmtContext<?, ?, ?>> effectiveSubstatements() {
-        return effectiveSubstatements;
-    }
-
-    @Override
-    public ModuleEffectiveStatement buildEffective() {
-        throw new UnsupportedOperationException("Attempted to instantiate proxy context " + this);
-    }
-
-    @Override
-    public ModuleStatement buildDeclared() {
-        return delegate.buildDeclared();
-    }
-
-    @Override
-    public StatementSource getStatementSource() {
-        return delegate.getStatementSource();
-    }
-
-    @Override
-    public StatementSourceReference getStatementSourceReference() {
-        return delegate.getStatementSourceReference();
-    }
-
-    @Override
-    public StatementDefinition getPublicDefinition() {
-        return delegate.getPublicDefinition();
-    }
-
-    @Override
-    public StmtContext<?, ?, ?> getParentContext() {
-        return delegate.getParentContext();
-    }
-
-    @Override
-    public String rawStatementArgument() {
-        return delegate.rawStatementArgument();
-    }
-
-    @Override
-    public @Nullable String getStatementArgument() {
-        return delegate.getStatementArgument();
-    }
-
-    @Override
-    public @NonNull Optional<SchemaPath> getSchemaPath() {
-        return delegate.getSchemaPath();
-    }
-
-    @Override
-    public boolean isConfiguration() {
-        return delegate.isConfiguration();
-    }
-
-    @Override
-    public boolean isEnabledSemanticVersioning() {
-        return delegate.isEnabledSemanticVersioning();
-    }
-
-    @Override
-    public <K, V, T extends K, N extends IdentifierNamespace<K, V>> V getFromNamespace(final Class<N> type,
-            final T key) {
-        return delegate.getFromNamespace(type, key);
-    }
-
-    @Override
-    public <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromNamespace(final Class<N> type) {
-        return delegate.getAllFromNamespace(type);
-    }
-
-    @Override
-    public <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromCurrentStmtCtxNamespace(
-            final Class<N> type) {
-        return delegate.getAllFromCurrentStmtCtxNamespace(type);
-    }
-
-    @Override
-    public StmtContext<?, ?, ?> getRoot() {
-        return delegate.getRoot();
-    }
-
-    @Override
-    public Collection<? extends StmtContext<?, ?, ?>> declaredSubstatements() {
-        return delegate.declaredSubstatements();
-    }
-
-    @Override
-    public boolean isSupportedToBuildEffective() {
-        return delegate.isSupportedToBuildEffective();
-    }
-
-    @Override
-    public boolean isSupportedByFeatures() {
-        return delegate.isSupportedByFeatures();
-    }
-
-    @Override
-    public Collection<? extends StmtContext<?, ?, ?>> getEffectOfStatement() {
-        return delegate.getEffectOfStatement();
-    }
-
-    @Override
-    public CopyHistory getCopyHistory() {
-        return delegate.getCopyHistory();
-    }
-
-    @Override
-    public Optional<StmtContext<String, ModuleStatement, ModuleEffectiveStatement>> getOriginalCtx() {
-        return delegate.getOriginalCtx();
-    }
-
-    @Override
-    public Optional<StmtContext<String, ModuleStatement, ModuleEffectiveStatement>> getPreviousCopyCtx() {
-        return delegate.getPreviousCopyCtx();
-    }
-
-    @Override
-    public ModelProcessingPhase getCompletedPhase() {
-        return delegate.getCompletedPhase();
-    }
-
-    @Override
-    public @NonNull YangVersion getRootVersion() {
-        return delegate.getRootVersion();
-    }
-}
index db6523f8a2d1bd16b690990109987fad921f5bd9..849ba958527f9477e2ac1468636b910227c5b7e3 100644 (file)
@@ -10,15 +10,18 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.submodule;
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.findFirstDeclaredSubstatement;
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
 
+import com.google.common.collect.ImmutableList;
 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.BelongsToStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
 import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.SubmoduleNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
 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;
@@ -26,7 +29,7 @@ import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModule
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 abstract class AbstractSubmoduleStatementSupport
-        extends AbstractStatementSupport<String, SubmoduleStatement, SubmoduleEffectiveStatement> {
+        extends BaseStatementSupport<String, SubmoduleStatement, SubmoduleEffectiveStatement> {
     AbstractSubmoduleStatementSupport() {
         super(YangStmtMapping.SUBMODULE);
     }
@@ -36,17 +39,6 @@ abstract class AbstractSubmoduleStatementSupport
         return value;
     }
 
-    @Override
-    public final SubmoduleStatement createDeclared(final StmtContext<String, SubmoduleStatement, ?> ctx) {
-        return new SubmoduleStatementImpl(ctx);
-    }
-
-    @Override
-    public final SubmoduleEffectiveStatement createEffective(
-            final StmtContext<String, SubmoduleStatement, SubmoduleEffectiveStatement> ctx) {
-        return new SubmoduleEffectiveStatementImpl(ctx);
-    }
-
     @Override
     public final void onPreLinkageDeclared(
             final Mutable<String, SubmoduleStatement, SubmoduleEffectiveStatement> stmt) {
@@ -78,4 +70,33 @@ abstract class AbstractSubmoduleStatementSupport
 
         stmt.addToNs(BelongsToPrefixToModuleName.class, prefix, belongsToModuleName);
     }
+
+    @Override
+    protected final SubmoduleStatement createDeclared(final StmtContext<String, SubmoduleStatement, ?> ctx,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        return new SubmoduleStatementImpl(ctx.coerceRawStatementArgument(), substatements);
+    }
+
+    @Override
+    protected final SubmoduleStatement createEmptyDeclared(final StmtContext<String, SubmoduleStatement, ?> ctx) {
+        throw noBelongsTo(ctx);
+    }
+
+    @Override
+    protected final SubmoduleEffectiveStatement createEffective(
+            final StmtContext<String, SubmoduleStatement, SubmoduleEffectiveStatement> ctx,
+            final SubmoduleStatement declared, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        return new SubmoduleEffectiveStatementImpl(ctx, declared, substatements);
+    }
+
+    @Override
+    protected final SubmoduleEffectiveStatement createEmptyEffective(
+            final StmtContext<String, SubmoduleStatement, SubmoduleEffectiveStatement> ctx,
+            final SubmoduleStatement declared) {
+        throw noBelongsTo(ctx);
+    }
+
+    private static SourceException noBelongsTo(final StmtContext<?, ?, ?> ctx) {
+        return new SourceException("No belongs-to declared in submodule", ctx.getStatementSourceReference());
+    }
 }
index dcdd68bd7cda96a123716f279bfd1918d2afc1da..473ae8ba82ed7a455d40e6900c8571b780ffcefb 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.submodule;
 import static com.google.common.base.Preconditions.checkState;
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.collect.ImmutableSet;
@@ -53,8 +54,9 @@ final class SubmoduleEffectiveStatementImpl
     private ImmutableSet<Module> submodules;
     private boolean sealed;
 
-    SubmoduleEffectiveStatementImpl(final StmtContext<String, SubmoduleStatement, SubmoduleEffectiveStatement> ctx) {
-        super(ctx, findSubmodulePrefix(ctx));
+    SubmoduleEffectiveStatementImpl(final StmtContext<String, SubmoduleStatement, SubmoduleEffectiveStatement> ctx,
+            final SubmoduleStatement declared, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        super(declared, ctx, substatements, findSubmodulePrefix(ctx));
 
         final String belongsToModuleName = firstAttributeOf(ctx.declaredSubstatements(), BelongsToStatement.class);
         final QNameModule belongsToModuleQName = ctx.getFromNamespace(ModuleNameToModuleQName.class,
index 514f57c41ccdcf8a4d4467c9454f9a838483666a..4aa5a0ef29b50f2940adfb7bd1a4247665997014 100644 (file)
@@ -7,12 +7,15 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.submodule;
 
+import com.google.common.collect.ImmutableList;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
-import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractRootStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveRootStatement;
 
-final class SubmoduleStatementImpl extends AbstractRootStatement<SubmoduleStatement> implements SubmoduleStatement {
-    SubmoduleStatementImpl(final StmtContext<String, SubmoduleStatement, ?> context) {
-        super(context);
+final class SubmoduleStatementImpl extends AbstractDeclaredEffectiveRootStatement<SubmoduleStatement>
+        implements SubmoduleStatement {
+    SubmoduleStatementImpl(final String rawArgument,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        super(rawArgument, substatements);
     }
 }