Add BaseSchemaTreeStatementSupport statement policies 17/94717/4
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 21 Jan 2021 19:49:17 +0000 (20:49 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 21 Jan 2021 23:06:40 +0000 (00:06 +0100)
All current subclasses are using at least two broadly-applicable
policies:

- uninstantiated statements, i.e. action, notification, input, output
  These are always EffectiveConfig.IGNORED anyway.

- instantiated statements, i.e. leaf, container and the like, who
  need to adjust their view of EffectiveConfig.

Introduce these two and convert uninstantiated users.

JIRA: YANGTOOLS-1208
Change-Id: I7847bda9d9b5ef782deda4df40f7c449daafbf4f
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/BaseOperationContainerStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/BaseSchemaTreeStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/action/ActionStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/AbstractNotificationStatementSupport.java

index 580b999540bb8a6abecaadef37da5b24e6aa3bd4..e5d0027189c49487da950376925d27b03e23ce5f 100644 (file)
@@ -38,7 +38,7 @@ public abstract class BaseOperationContainerStatementSupport<D extends DeclaredS
 
     protected BaseOperationContainerStatementSupport(final StatementDefinition publicDefinition,
             final Function<QNameModule, QName> createArgument) {
-        super(publicDefinition, StatementPolicy.legacyDeclaredCopy());
+        super(publicDefinition, uninstantiatedPolicy());
         this.createArgument = requireNonNull(createArgument);
     }
 
index 70bc25ade362204cd883422d5fa804272a48fbbd..d01bc67b2af24d0d06e4097ded09578e203f00fe 100644 (file)
@@ -7,12 +7,19 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
 
+import java.util.Collection;
+import java.util.Objects;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.CopyableNode;
 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.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 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.CopyHistory;
+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.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
@@ -26,11 +33,98 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
  */
 public abstract class BaseSchemaTreeStatementSupport<D extends DeclaredStatement<QName>,
         E extends SchemaTreeEffectiveStatement<D>> extends AbstractQNameStatementSupport<D, E> {
+    private static class SchemaTreeEquality<D extends DeclaredStatement<QName>>
+            implements StatementEquality<QName, D> {
+        private static final class Instantiated<D extends DeclaredStatement<QName>> extends SchemaTreeEquality<D> {
+            @Override
+            public boolean canReuseCurrent(final Current<QName, D> copy, final Current<QName, D> current,
+                    final Collection<? extends EffectiveStatement<?, ?>> substatements) {
+                return copy.effectiveConfig() == current.effectiveConfig()
+                    && super.canReuseCurrent(copy, current, substatements)
+                    // This weird quirk is needed for ... something somewhere
+                    && Objects.equals(copy.original(), current.original());
+            }
+        }
+
+        @Override
+        public boolean canReuseCurrent(final Current<QName, D> copy, final Current<QName, D> current,
+                final Collection<? extends EffectiveStatement<?, ?>> substatements) {
+            return equalHistory(copy, current)
+                // FIXME: this should devolve to getArgument() equality
+                && copy.getSchemaPath().equals(current.getSchemaPath());
+        }
+
+        // TODO: can we speed this up?
+        private static boolean equalHistory(final Current<?, ?> copy, final Current<?, ?> current) {
+            return isAugmenting(copy) == isAugmenting(current)
+                && isAddedByUses(copy) == isAddedByUses(current);
+        }
+
+        private static boolean isAugmenting(final Current<?, ?> stmt) {
+            final CopyHistory history = stmt.history();
+            return history.contains(CopyType.ADDED_BY_AUGMENTATION)
+                || history.contains(CopyType.ADDED_BY_USES_AUGMENTATION);
+        }
+
+        private static boolean isAddedByUses(final Current<?, ?> stmt) {
+            final CopyHistory history = stmt.history();
+            return history.contains(CopyType.ADDED_BY_USES)
+                || history.contains(CopyType.ADDED_BY_USES_AUGMENTATION);
+        }
+    }
+
+    private static final StatementPolicy<QName, ?> INSTANTIATED_POLICY =
+        StatementPolicy.copyDeclared(new SchemaTreeEquality.Instantiated<>());
+    private static final StatementPolicy<QName, ?> UNINSTANTIATED_POLICY =
+        StatementPolicy.copyDeclared(new SchemaTreeEquality<>());
+
     protected BaseSchemaTreeStatementSupport(final StatementDefinition publicDefinition,
             final StatementPolicy<QName, D> policy) {
         super(publicDefinition, policy);
     }
 
+    /**
+     * Return the {@link StatementPolicy} corresponding to a potentially-instantiated YANG statement. Statements are
+     * reused as long as:
+     * <ul>
+     *   <li>{@link Current#schemaPath()} does not change</li>
+     *   <li>{@link Current#argument()} does not change</li>
+     *   <li>{@link Current#history()} does not change as far as {@link CopyableNode} is concerned</li>
+     *   <li>{@link Current#effectiveConfig()} does not change</li>
+     *   <li>{@link Current#original()} does not change</li>
+     * </ul>
+     *
+     * <p>
+     * Typical users include {@code container} and {@code leaf}.
+     *
+     * @param <D> Declared Statement representation
+     * @return A StatementPolicy
+     */
+    @SuppressWarnings("unchecked")
+    public static final <D extends DeclaredStatement<QName>> StatementPolicy<QName, D> instantiatedPolicy() {
+        return (StatementPolicy<QName, D>) INSTANTIATED_POLICY;
+    }
+
+    /**
+     * Return the {@link StatementPolicy} corresponding to an uninstantiated YANG statement. Statements are
+     * reused as long as:
+     * <ul>
+     *   <li>{@link Current#schemaPath()} does not change</li>
+     *   <li>{@link Current#argument()} does not change</li>
+     *   <li>{@link Current#history()} does not change as far as {@link CopyableNode} is concerned</li>
+     * </ul>
+     *
+     * <p>
+     * Typical users include {@code action} and {@code notification} (in its YANG 1.1 form).
+     *
+     * @param <D> Declared Statement representation
+     * @return A StatementPolicy
+     */
+    @SuppressWarnings("unchecked")
+    public static final <D extends DeclaredStatement<QName>> StatementPolicy<QName, D> uninstantiatedPolicy() {
+        return (StatementPolicy<QName, D>) UNINSTANTIATED_POLICY;
+    }
+
     /**
      * {@inheritDoc}
      *
index 6e240e5596fc878cd53b53ee680681cde8470092..9af9e29914c4cc61ecf506fa21f4a5bb34228e64 100644 (file)
@@ -54,7 +54,7 @@ public final class ActionStatementSupport extends
     private static final ActionStatementSupport INSTANCE = new ActionStatementSupport();
 
     private ActionStatementSupport() {
-        super(YangStmtMapping.ACTION, StatementPolicy.legacyDeclaredCopy());
+        super(YangStmtMapping.ACTION, uninstantiatedPolicy());
     }
 
     public static ActionStatementSupport getInstance() {
index fb587a1f2c3705e75cdc15a80d48f0093ab6ae06..dfe4a374c0612e23e2bfacb2029d6cfb50b92d1b 100644 (file)
@@ -24,7 +24,7 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 abstract class AbstractNotificationStatementSupport
         extends BaseSchemaTreeStatementSupport<NotificationStatement, NotificationEffectiveStatement> {
     AbstractNotificationStatementSupport() {
-        super(YangStmtMapping.NOTIFICATION, StatementPolicy.legacyDeclaredCopy());
+        super(YangStmtMapping.NOTIFICATION, uninstantiatedPolicy());
     }
 
     @Override