Bump odlparent to 10.0.0
[yangtools.git] / parser / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / uses / UsesStatementSupport.java
index 22986ca4c00ca02afcba61df02292e1355b52dd6..b2be7e546521c3c7df7f24378eb28942e685840b 100644 (file)
@@ -12,7 +12,6 @@ import static com.google.common.base.Verify.verifyNotNull;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedHashMap;
@@ -39,14 +38,15 @@ import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
 import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatementDecorators;
 import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements;
-import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins;
 import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
 import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.YangValidationBundles;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStmtUtils;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.refine.RefineEffectiveStatementImpl;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.refine.RefineTargetNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.SchemaTreeNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.BoundStmtCtx;
 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
@@ -63,7 +63,6 @@ import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -102,17 +101,15 @@ public final class UsesStatementSupport
 
         final Prerequisite<StmtContext<?, ?, ?>> sourceGroupingPre = usesAction.requiresCtx(usesNode,
                 GroupingNamespace.class, groupingName, ModelProcessingPhase.EFFECTIVE_MODEL);
-        final Prerequisite<? extends StmtContext.Mutable<?, ?, ?>> targetNodePre = usesAction.mutatesEffectiveCtx(
+        final Prerequisite<? extends Mutable<?, ?, ?>> targetNodePre = usesAction.mutatesEffectiveCtx(
                 usesNode.getParentContext());
 
         usesAction.apply(new InferenceAction() {
 
             @Override
             public void apply(final InferenceContext ctx) {
-                final StatementContextBase<?, ?, ?> targetNodeStmtCtx =
-                        (StatementContextBase<?, ?, ?>) targetNodePre.resolve(ctx);
-                final StatementContextBase<?, ?, ?> sourceGrpStmtCtx =
-                        (StatementContextBase<?, ?, ?>) sourceGroupingPre.resolve(ctx);
+                final Mutable<?, ?, ?> targetNodeStmtCtx = targetNodePre.resolve(ctx);
+                final StmtContext<?, ?, ?> sourceGrpStmtCtx = sourceGroupingPre.resolve(ctx);
 
                 copyFromSourceToTarget(sourceGrpStmtCtx, targetNodeStmtCtx, usesNode);
                 resolveUsesNode(usesNode, targetNodeStmtCtx);
@@ -130,8 +127,8 @@ public final class UsesStatementSupport
     }
 
     @Override
-    protected UsesStatement createDeclared(final StmtContext<QName, UsesStatement, ?> ctx,
-            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+    protected UsesStatement createDeclared(final BoundStmtCtx<QName> ctx,
+            final ImmutableList<DeclaredStatement<?>> substatements) {
         return DeclaredStatements.createUses(ctx.getRawArgument(), ctx.getArgument(), substatements);
     }
 
@@ -148,7 +145,7 @@ public final class UsesStatementSupport
         verify(source instanceof GroupingDefinition, "Unexpected source %s", source);
         final GroupingDefinition sourceGrouping = (GroupingDefinition) source;
 
-        final int flags = EffectiveStatementMixins.historyAndStatusFlags(stmt.history(), substatements);
+        final int flags = EffectiveStmtUtils.historyAndStatusFlags(stmt.history(), substatements);
         final QName argument = stmt.getArgument();
         final UsesStatement declared = stmt.declared();
 
@@ -193,23 +190,25 @@ public final class UsesStatementSupport
      * @throws SourceException
      *             instance of SourceException
      */
-    @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
-            justification = "https://github.com/spotbugs/spotbugs/issues/811")
-    private static void copyFromSourceToTarget(final Mutable<?, ?, ?> sourceGrpStmtCtx,
-            final StatementContextBase<?, ?, ?> targetCtx,
-            final Mutable<QName, UsesStatement, UsesEffectiveStatement> usesNode) {
-        final Collection<? extends Mutable<?, ?, ?>> declared = sourceGrpStmtCtx.mutableDeclaredSubstatements();
-        final Collection<? extends Mutable<?, ?, ?>> effective = sourceGrpStmtCtx.mutableEffectiveSubstatements();
-        final Collection<Mutable<?, ?, ?>> buffer = new ArrayList<>(declared.size() + effective.size());
+    private static void copyFromSourceToTarget(final StmtContext<?, ?, ?> sourceGrpStmtCtx,
+            final Mutable<?, ?, ?> targetCtx, final Mutable<QName, UsesStatement, UsesEffectiveStatement> usesNode) {
+        final var declared = sourceGrpStmtCtx.declaredSubstatements();
+        final var effective = sourceGrpStmtCtx.effectiveSubstatements();
+        final var buffer = new ArrayList<Mutable<?, ?, ?>>(declared.size() + effective.size());
         final QNameModule newQNameModule = getNewQNameModule(targetCtx, sourceGrpStmtCtx);
 
-        for (final Mutable<?, ?, ?> original : declared) {
-            if (original.isSupportedByFeatures() && shouldCopy(original)) {
-                original.copyAsChildOf(targetCtx, CopyType.ADDED_BY_USES, newQNameModule).ifPresent(buffer::add);
+        for (StmtContext<?, ?, ?> original : declared) {
+            if (shouldCopy(original)) {
+                original.copyAsChildOf(targetCtx, CopyType.ADDED_BY_USES, newQNameModule).ifPresent(copy -> {
+                    if (!original.isSupportedByFeatures() || !original.isSupportedToBuildEffective()) {
+                        copy.setUnsupported();
+                    }
+                    buffer.add(copy);
+                });
             }
         }
 
-        for (final Mutable<?, ?, ?> original : effective) {
+        for (StmtContext<?, ?, ?> original : effective) {
             if (shouldCopy(original)) {
                 original.copyAsChildOf(targetCtx, CopyType.ADDED_BY_USES, newQNameModule).ifPresent(buffer::add);
             }
@@ -273,11 +272,9 @@ public final class UsesStatementSupport
         return null;
     }
 
-    @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
-            justification = "https://github.com/spotbugs/spotbugs/issues/811")
     private static void resolveUsesNode(final Mutable<QName, UsesStatement, UsesEffectiveStatement> usesNode,
             final StmtContext<?, ?, ?> targetNodeStmtCtx) {
-        for (final Mutable<?, ?, ?> subStmtCtx : usesNode.mutableDeclaredSubstatements()) {
+        for (Mutable<?, ?, ?> subStmtCtx : usesNode.mutableDeclaredSubstatements()) {
             if (subStmtCtx.producesDeclared(RefineStatement.class) && areFeaturesSupported(subStmtCtx)) {
                 performRefine(subStmtCtx, targetNodeStmtCtx);
             }
@@ -296,6 +293,8 @@ public final class UsesStatementSupport
         InferenceException.throwIf(!(refineArgument instanceof SchemaNodeIdentifier), subStmtCtx,
             "Invalid refine argument %s. It must be instance of SchemaNodeIdentifier.", refineArgument);
 
+        // FIXME: this really should be handled via separate inference, i.e. we first instantiate the template and when
+        //        it appears, this refine will trigger on it. This reinforces the FIXME below.
         final Optional<StmtContext<?, ?, ?>> optRefineTargetCtx = SchemaTreeNamespace.findNode(
             usesParentCtx, (SchemaNodeIdentifier) refineArgument);
         InferenceException.throwIf(!optRefineTargetCtx.isPresent(), subStmtCtx, "Refine target node %s not found.",
@@ -311,8 +310,8 @@ public final class UsesStatementSupport
                 subStmtCtx.coerceParentContext().argument(), refineTargetNodeCtx.argument(),
                 subStmtCtx.sourceReference());
         } else {
-            verify(refineTargetNodeCtx instanceof StatementContextBase);
-            addOrReplaceNodes(subStmtCtx, (StatementContextBase<?, ?, ?>) refineTargetNodeCtx);
+            verify(refineTargetNodeCtx instanceof Mutable, "Unexpected target %s", refineTargetNodeCtx);
+            addOrReplaceNodes(subStmtCtx, (Mutable<?, ?, ?>) refineTargetNodeCtx);
         }
 
         // Target is a prerequisite for the 'refine', hence if the target is not supported, the refine is not supported
@@ -320,24 +319,25 @@ public final class UsesStatementSupport
         if (refineTargetNodeCtx.isSupportedToBuildEffective()) {
             subStmtCtx.addToNs(RefineTargetNamespace.class, Empty.value(), refineTargetNodeCtx);
         } else {
-            subStmtCtx.setIsSupportedToBuildEffective(false);
+            subStmtCtx.setUnsupported();
         }
     }
 
-    private static void addOrReplaceNodes(final Mutable<?, ?, ?> subStmtCtx,
-            final StatementContextBase<?, ?, ?> refineTargetNodeCtx) {
-        for (final Mutable<?, ?, ?> refineSubstatementCtx : subStmtCtx.mutableDeclaredSubstatements()) {
+    private static void addOrReplaceNodes(final StmtContext<?, ?, ?> subStmtCtx,
+            final Mutable<?, ?, ?> refineTargetNodeCtx) {
+        for (StmtContext<?, ?, ?> refineSubstatementCtx : subStmtCtx.declaredSubstatements()) {
             if (isSupportedRefineSubstatement(refineSubstatementCtx)) {
                 addOrReplaceNode(refineSubstatementCtx, refineTargetNodeCtx);
             }
         }
     }
 
-    private static void addOrReplaceNode(final Mutable<?, ?, ?> refineSubstatementCtx,
-            final StatementContextBase<?, ?, ?> refineTargetNodeCtx) {
+    private static void addOrReplaceNode(final StmtContext<?, ?, ?> refineSubstatementCtx,
+            final Mutable<?, ?, ?> refineTargetNodeCtx) {
 
         final StatementDefinition refineSubstatementDef = refineSubstatementCtx.publicDefinition();
 
+        // FIXME: this is quite costly, use an explicit block
         SourceException.throwIf(!isSupportedRefineTarget(refineSubstatementCtx, refineTargetNodeCtx),
                 refineSubstatementCtx,
                 "Error in module '%s' in the refine of uses '%s': can not perform refine of '%s' for the target '%s'.",
@@ -347,6 +347,7 @@ public final class UsesStatementSupport
         if (!isAllowedToAddByRefine(refineSubstatementDef)) {
             refineTargetNodeCtx.removeStatementFromEffectiveSubstatements(refineSubstatementDef);
         }
+        // FIXME: childCopyOf() should handle this through per-statement copy policy, right?
         refineTargetNodeCtx.addEffectiveSubstatement(refineSubstatementCtx.replicaAsChildOf(refineTargetNodeCtx));
     }