StatementSupport is not a StatementDefinition 96/100996/2
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 4 May 2022 21:10:35 +0000 (23:10 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 4 May 2022 21:18:32 +0000 (23:18 +0200)
Differentiate between StatementSupport and StatementDefinition, so as
to separate their lifecycle.

Change-Id: Id96ece0e6890b1aa1463e5f4e9a378fa3f5949fe
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/OperationsCreateLeafStatements.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java
parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedStatementSupport.java
parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractBooleanStatementSupport.java
parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java
parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java
parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinition.java
parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMap.java
parser/yang-parser-spi/src/test/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMapTest.java

index 8703cbddf8aadd6d5260bfe8fb956a86458d2a14..1f78430f0470057d3acb7694fd1bddb241863118 100644 (file)
@@ -101,7 +101,7 @@ final class OperationsCreateLeafStatements implements InferenceAction {
             StatementSupport<X, Y, Z> getSupport(final StatementDefinition def, final Class<Z> effectiveClass) {
         final var tmp = verifyNotNull(operations.getFromNamespace(StatementSupportNamespace.class,
             def.getStatementName()));
-        final var repr = tmp.getEffectiveRepresentationClass();
+        final var repr = tmp.definition().getEffectiveRepresentationClass();
         verify(effectiveClass.equals(repr), "Unexpected support %s representation %s", tmp, repr);
 
         @SuppressWarnings("unchecked")
index d34b4e19af1e6e313f630a9aa25da07f97ebeb97..4626f24fc10b44a25a643b4f2526c4f5e8e88668 100644 (file)
@@ -76,17 +76,21 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha
 
         @Override
         public StatementSupport<?, ?, ?> getFrom(final NamespaceStorageNode storage, final QName key) {
-            return statementDefinitions.get(key);
+            return statementDefinitions.getSupport(key);
         }
 
         @Override
         public Map<QName, StatementSupport<?, ?, ?>> getAllFrom(final NamespaceStorageNode storage) {
-            throw new UnsupportedOperationException("StatementSupportNamespace is immutable");
+            throw uoe();
         }
 
         @Override
         public void addTo(final NamespaceStorageNode storage, final QName key, final StatementSupport<?, ?, ?> value) {
-            throw new UnsupportedOperationException("StatementSupportNamespace is immutable");
+            throw uoe();
+        }
+
+        private static UnsupportedOperationException uoe() {
+            return new UnsupportedOperationException("StatementSupportNamespace is immutable");
         }
     }
 
@@ -135,7 +139,7 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha
         if (def == null) {
             def = globalContext.getModelDefinedStatementDefinition(name);
             if (def == null) {
-                final StatementSupport<?, ?, ?> extension = qnameToStmtDefMap.get(name);
+                final StatementSupport<?, ?, ?> extension = qnameToStmtDefMap.getSupport(name);
                 if (extension != null) {
                     def = new StatementDefinitionContext<>(extension);
                     globalContext.putModelDefinedStatementDefinition(name, def);
index 5eaa0ac8097ca751b1bad4aadc4a249bff95f114..64d30e8fe3c9a2043d26da88b4dea154fdd6f507 100644 (file)
@@ -91,7 +91,7 @@ final class StatementDefinitionContext<A, D extends DeclaredStatement<A>, E exte
     }
 
     @NonNull QName getStatementName() {
-        return support.getStatementName();
+        return support.statementName();
     }
 
     @Override
index c5e09340c2fbd5b1b7c6a8459d55952382aa8c47..b741dd9287f9c0dd8e7931809a8b2644b7a530d5 100644 (file)
@@ -52,13 +52,13 @@ final class UnrecognizedStatementSupport
          * This code wraps statements encountered inside an extension so they do not get confused with regular
          * statements.
          */
-        final QName baseQName = getStatementName();
-        final QName statementName = QName.create(baseQName, childDef.getStatementName().getLocalName());
+        // FIXME: remove this bit?
+        final QName statementName = QName.create(statementName(), childDef.getStatementName().getLocalName());
 
-        final ModelDefinedStatementDefinition def;
+        final StatementDefinition def;
         final Optional<ArgumentDefinition> optArgDef = childDef.getArgumentDefinition();
         if (optArgDef.isPresent()) {
-            final ArgumentDefinition argDef = optArgDef.get();
+            final ArgumentDefinition argDef = optArgDef.orElseThrow();
             def = new ModelDefinedStatementDefinition(statementName, argDef.getArgumentName(), argDef.isYinElement());
         } else {
             def = new ModelDefinedStatementDefinition(statementName);
index 7d1fc01c68d0034ec1b7b83d8b662df9e6c11f14..acce56a415363c7d885b76190f8ccbe45a5f0fda 100644 (file)
@@ -54,7 +54,7 @@ public abstract class AbstractBooleanStatementSupport<D extends DeclaredStatemen
             return Boolean.FALSE;
         } else {
             throw new SourceException(ctx, "Invalid '%s' statement %s '%s', it can be either 'true' or 'false'",
-                getStatementName(), getArgumentDefinition().get().getArgumentName(), value);
+                statementName(), argumentName(), value);
         }
     }
 
index 340f3224e865eabd666f670517958a5c5070709c..0cef4bc7b1dfa763c37d45cad948eeae4e74992e 100644 (file)
@@ -39,7 +39,7 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
  * @param <E> Effective Statement representation
  */
 public abstract class StatementSupport<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
-        implements StatementDefinition, StatementFactory<A, D, E> {
+        implements StatementFactory<A, D, E> {
     /**
      * A baseline class for implementing the {@link StatementFactory#canReuseCurrent(Current, Current, Collection)}
      * contract in a manner which is consistent with a statement's {@link CopyPolicy}.
@@ -196,21 +196,20 @@ public abstract class StatementSupport<A, D extends DeclaredStatement<A>, E exte
     }
 
     private final @NonNull StatementPolicy<A, D> policy;
-    private final @NonNull StatementDefinition def;
+    private final @NonNull StatementDefinition publicDefinition;
     private final @NonNull CopyPolicy copyPolicy;
 
     @Beta
     protected StatementSupport(final StatementSupport<A, D, E> delegate) {
         checkArgument(delegate != this);
-        this.def = delegate.def;
+        this.publicDefinition = delegate.publicDefinition;
         this.policy = delegate.policy;
         this.copyPolicy = delegate.copyPolicy;
     }
 
     @Beta
     protected StatementSupport(final StatementDefinition publicDefinition, final StatementPolicy<A, D> policy) {
-        checkArgument(publicDefinition != this);
-        this.def = requireNonNull(publicDefinition);
+        this.publicDefinition = requireNonNull(publicDefinition);
         this.policy = requireNonNull(policy);
         this.copyPolicy = policy.copyPolicy;
     }
@@ -225,7 +224,13 @@ public abstract class StatementSupport<A, D extends DeclaredStatement<A>, E exte
      * @return public statement definition, which will be present in built statements.
      */
     public final @NonNull StatementDefinition getPublicView() {
-        return def;
+        return publicDefinition;
+    }
+
+    // Appropriate to most definitions
+    // Non-final for compatible extensions
+    public @NonNull StatementDefinition definition() {
+        return publicDefinition;
     }
 
     /**
@@ -438,26 +443,16 @@ public abstract class StatementSupport<A, D extends DeclaredStatement<A>, E exte
         return false;
     }
 
-    @Override
-    public final QName getStatementName() {
-        return def.getStatementName();
+    public final @NonNull QName statementName() {
+        return publicDefinition.getStatementName();
     }
 
-    @Override
-    public final Optional<ArgumentDefinition> getArgumentDefinition() {
-        return def.getArgumentDefinition();
+    public final @Nullable QName argumentName() {
+        return publicDefinition.getArgumentDefinition().map(ArgumentDefinition::getArgumentName).orElse(null);
     }
 
-    @Override
-    // Non-final for compatible extensions
-    public Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass() {
-        return def.getDeclaredRepresentationClass();
-    }
-
-    @Override
-    // Non-final for compatible extensions
-    public Class<? extends EffectiveStatement<?,?>> getEffectiveRepresentationClass() {
-        return def.getEffectiveRepresentationClass();
+    public final @NonNull Optional<ArgumentDefinition> getArgumentDefinition() {
+        return publicDefinition.getArgumentDefinition();
     }
 
     /**
index 8e74f508e5dc46f6982043ede903d430bbd37319..33bb8b64545de1727629d77a1ea988f931f2fd1d 100644 (file)
@@ -176,7 +176,7 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
         }
 
         public @NonNull Builder addSupport(final StatementSupport<?, ?, ?> support) {
-            final QName identifier = support.getStatementName();
+            final QName identifier = support.statementName();
             checkNoParentDefinition(identifier);
 
             checkState(!commonStatements.containsKey(identifier),
@@ -195,10 +195,10 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
         }
 
         public @NonNull Builder addVersionSpecificSupport(final YangVersion version,
-                final StatementSupport<?, ?, ?> definition) {
+                final StatementSupport<?, ?, ?> support) {
             checkArgument(supportedVersions.contains(requireNonNull(version)));
 
-            final QName identifier = definition.getStatementName();
+            final QName identifier = support.statementName();
             checkState(!commonStatements.containsKey(identifier),
                     "Statement %s already defined in common statement bundle.", identifier);
             checkState(!versionSpecificStatements.contains(version, identifier),
@@ -206,7 +206,7 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
             checkNoParentDefinition(identifier);
             checkState(parent.getVersionSpecificStatementDefinition(version, identifier) == null,
                     "Statement %s already defined for version %s in parent's statement bundle.", identifier, version);
-            versionSpecificStatements.put(version, identifier, definition);
+            versionSpecificStatements.put(version, identifier, support);
             return this;
         }
 
@@ -220,7 +220,7 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
         }
 
         public @NonNull Builder overrideSupport(final StatementSupport<?, ?, ?> support) {
-            final QName identifier = support.getStatementName();
+            final QName identifier = support.statementName();
             checkNoParentDefinition(identifier);
 
             final StatementSupport<?, ?, ?> previousSupport = commonStatements.replace(identifier, support);
index 7113ecc7b46fa0e91d9eecb83d683f6df4074565..b52edf93f2aa45a7340e255def0ddbed0337b67b 100644 (file)
@@ -23,7 +23,7 @@ public interface QNameToStatementDefinition {
      * @param identifier QName of requested statement
      * @return StatementDefinition
      */
-    StatementDefinition get(QName identifier);
+    @Nullable StatementDefinition get(QName identifier);
 
     /**
      * Returns StatementDefinition with specified namespace and localName.
index 9d7ac23c74e688614d677de8f2f5cd2868fc6e83..88535b6cb4c8684a4ac3aa12013445987cd2697a 100644 (file)
@@ -11,12 +11,13 @@ import static java.util.Objects.requireNonNull;
 
 import java.util.HashMap;
 import java.util.Map;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.XMLNamespace;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
 
-public class QNameToStatementDefinitionMap implements QNameToStatementDefinition {
+public final class QNameToStatementDefinitionMap implements QNameToStatementDefinition {
     private final Map<QName, StatementSupport<?, ?, ?>> noRevQNameToSupport;
     private final Map<QName, StatementSupport<?, ?, ?>> qnameToSupport;
 
@@ -60,12 +61,26 @@ public class QNameToStatementDefinitionMap implements QNameToStatementDefinition
     }
 
     @Override
-    public StatementSupport<?, ?, ?> get(final QName identifier) {
-        return qnameToSupport.get(identifier);
+    public StatementDefinition get(final QName identifier) {
+        return definitionOf(getSupport(identifier));
     }
 
     @Override
     public StatementDefinition getByNamespaceAndLocalName(final XMLNamespace namespace, final String localName) {
-        return noRevQNameToSupport.get(QName.create(namespace, localName));
+        return definitionOf(noRevQNameToSupport.get(QName.create(namespace, localName)));
+    }
+
+    /**
+     * Returns StatementSupport with specified QName.
+     *
+     * @param identifier QName of requested statement
+     * @return StatementSupport
+     */
+    public @Nullable StatementSupport<?, ?, ?> getSupport(final QName identifier) {
+        return qnameToSupport.get(requireNonNull(identifier));
+    }
+
+    private static @Nullable StatementDefinition definitionOf(final @Nullable StatementSupport<?, ?, ?> support) {
+        return support != null ? support.definition() : null;
     }
 }
index 783bc837e5abfb125bf733bab43fc51605447bed..91e6e087c4646c7f868d531567eae6088e641892 100644 (file)
@@ -9,10 +9,13 @@ package org.opendaylight.yangtools.yang.parser.spi.source;
 
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
 
 public class QNameToStatementDefinitionMapTest {
@@ -20,6 +23,12 @@ public class QNameToStatementDefinitionMapTest {
 
     private final QNameToStatementDefinitionMap map = new QNameToStatementDefinitionMap();
     private final StatementSupport<?, ?, ?> support = mock(StatementSupport.class);
+    private final StatementDefinition definition = mock(StatementDefinition.class);
+
+    @Before
+    public void before() {
+        doReturn(definition).when(support).definition();
+    }
 
     @Test
     public void testPutNullNull() {
@@ -28,7 +37,7 @@ public class QNameToStatementDefinitionMapTest {
 
     @Test
     public void testPutNullSome() {
-        assertThrows(NullPointerException.class, () -> map.put(null, mock(StatementSupport.class)));
+        assertThrows(NullPointerException.class, () -> map.put(null, support));
     }
 
     @Test
@@ -39,6 +48,7 @@ public class QNameToStatementDefinitionMapTest {
     @Test
     public void testPut() {
         map.put(QNAME, support);
-        assertSame(support, map.get(QNAME));
+        assertSame(definition, map.get(QNAME));
+        assertSame(support, map.getSupport(QNAME));
     }
 }