Graduate ChildSchemaNodeNamespace as SchemaTreeNamespace
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / BaseStatementSupport.java
index c7650293fca189f78560376cdb8dd6f669a237fd..8a149087e9cfc5fa0dfea32afb8ad49bb345e3ef 100644 (file)
@@ -7,8 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
 
-import static com.google.common.base.Verify.verifyNotNull;
-
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
 import java.util.ArrayList;
@@ -38,6 +36,10 @@ public abstract class BaseStatementSupport<A, D extends DeclaredStatement<A>,
         super(publicDefinition);
     }
 
+    protected BaseStatementSupport(final StatementDefinition publicDefinition, final CopyPolicy copyPolicy) {
+        super(publicDefinition, copyPolicy);
+    }
+
     @Override
     public final D createDeclared(final StmtContext<A, D, ?> ctx) {
         final ImmutableList<? extends DeclaredStatement<?>> substatements = ctx.declaredSubstatements().stream()
@@ -52,9 +54,10 @@ public abstract class BaseStatementSupport<A, D extends DeclaredStatement<A>,
     protected abstract @NonNull D createEmptyDeclared(@NonNull StmtContext<A, D, ?> ctx);
 
     @Override
-    public final E createEffective(final StmtContext<A, D, E> ctx) {
-        final D declared = buildDeclared(ctx);
-        final ImmutableList<? extends EffectiveStatement<?, ?>> substatements = buildEffectiveSubstatements(ctx);
+    public E createEffective(final StmtContext<A, D, E> ctx) {
+        final D declared = ctx.buildDeclared();
+        final ImmutableList<? extends EffectiveStatement<?, ?>> substatements =
+                buildEffectiveSubstatements(ctx, statementsToBuild(ctx, declaredSubstatements(ctx)));
         return substatements.isEmpty() ? createEmptyEffective(ctx, declared)
                 : createEffective(ctx, declared, substatements);
     }
@@ -64,6 +67,19 @@ public abstract class BaseStatementSupport<A, D extends DeclaredStatement<A>,
 
     protected abstract @NonNull E createEmptyEffective(@NonNull StmtContext<A, D, E> ctx, @NonNull D declared);
 
+    /**
+     * Give statement support a hook to transform statement contexts before they are built. Default implementation
+     * does nothing, but note {@code augment} statement performs a real transformation.
+     *
+     * @param ctx Parent statement context
+     * @param substatements Substatement contexts which have been determined to be built
+     * @return Substatement context which are to be actually built
+     */
+    protected List<? extends StmtContext<?, ?, ?>> statementsToBuild(final StmtContext<A, D, E> ctx,
+            final List<? extends StmtContext<?, ?, ?>> substatements) {
+        return substatements;
+    }
+
     protected static final <E extends EffectiveStatement<?, ?>> @Nullable E findFirstStatement(
             final ImmutableList<? extends EffectiveStatement<?, ?>> statements, final Class<E> type) {
         for (EffectiveStatement<?, ?> stmt : statements) {
@@ -75,30 +91,26 @@ public abstract class BaseStatementSupport<A, D extends DeclaredStatement<A>,
     }
 
     protected static final <A, E extends EffectiveStatement<A, ?>> A findFirstArgument(
-            final ImmutableList<? extends EffectiveStatement<?, ?>> statements, final Class<E> type, final A defValue) {
+            final ImmutableList<? extends EffectiveStatement<?, ?>> statements, final Class<@NonNull E> type,
+                    final A defValue) {
         final @Nullable E stmt = findFirstStatement(statements, type);
         return stmt != null ? stmt.argument() : defValue;
     }
 
-    static final <A, D extends DeclaredStatement<A>> @NonNull D buildDeclared(final StmtContext<A, D, ?> ctx) {
-        /*
-         * Share original instance of declared statement between all effective
-         * statements which have been copied or derived from this original
-         * declared statement.
-         */
-        @SuppressWarnings("unchecked")
-        final StmtContext<?, D, ?> lookupCtx = (StmtContext<?, D, ?>) ctx.getOriginalCtx().orElse(ctx);
-        return verifyNotNull(lookupCtx.buildDeclared(), "Statement %s failed to build declared statement", lookupCtx);
-    }
-
     /**
-     * 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);
+    }
+
+    private static ImmutableList<? extends EffectiveStatement<?, ?>> defaultBuildEffectiveSubstatements(
             final List<? extends StmtContext<?, ?, ?>> substatements) {
         return substatements.stream()
                 .filter(StmtContext::isSupportedToBuildEffective)
@@ -106,12 +118,7 @@ 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) {
+    private static @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
          * the statements were defined -- i.e. if we have something like this:
@@ -136,7 +143,7 @@ public abstract class BaseStatementSupport<A, D extends DeclaredStatement<A>,
          * The reactor would first inline 'uses baz' as that definition is the first one completely resolved and then
          * inline 'uses bar'. Here we are iterating in declaration order re-inline the statements.
          *
-         * FIXME: 5.0.0: this really should be handled by UsesStatementSupport such that 'uses baz' would have a
+         * FIXME: 7.0.0: this really should be handled by UsesStatementSupport such that 'uses baz' would have a
          *               prerequisite of a resolved 'uses bar'.
          */
         final List<StmtContext<?, ?, ?>> substatementsInit = new ArrayList<>();