Seal ModelStatement 07/100507/12
authorRobert Varga <robert.varga@pantheon.tech>
Sat, 9 Apr 2022 19:47:48 +0000 (21:47 +0200)
committerRobert Varga <nite@hq.sk>
Tue, 26 Apr 2022 09:10:06 +0000 (09:10 +0000)
ModelStatement can either be a DeclaredStatement or an
EffectiveStatement. Make sure we enforce that invariant.

Change-Id: Ib54d7136527b3c49fd36e813a9f1acc5b02a8894
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
14 files changed:
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractDeclaredStatement.java [new file with mode: 0644]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractEffectiveStatement.java [new file with mode: 0644]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractModelStatement.java [moved from model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractModelStatement.java with 94% similarity]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/DeclaredStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/EffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/ModelStatement.java
model/yang-model-spi/src/main/java/module-info.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractDeclaredEffectiveStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractDeclaredStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractIndexedEffectiveStatement.java [moved from model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractEffectiveStatement.java with 90% similarity]
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractUndeclaredEffectiveStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/ForwardingDeclaredStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/ForwardingModelStatement.java [deleted file]
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/SubstatementIndexingException.java

diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractDeclaredStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractDeclaredStatement.java
new file mode 100644 (file)
index 0000000..322446d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 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.model.api.meta;
+
+import com.google.common.collect.ImmutableList;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Empty;
+
+/**
+ * Abstract base class for {@link DeclaredStatement} implementations.
+ *
+ * @param <A> Argument type ({@link Empty} if statement does not have argument.)
+ */
+public abstract non-sealed class AbstractDeclaredStatement<A> extends AbstractModelStatement<A>
+        implements DeclaredStatement<A> {
+    /**
+     * Utility method for recovering singleton lists squashed by {@link #maskList(ImmutableList)}.
+     *
+     * @param masked list to unmask
+     * @return Unmasked list
+     * @throws NullPointerException if masked is null
+     * @throws ClassCastException if masked object does not match DeclaredStatement
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    protected static final @NonNull ImmutableList<? extends DeclaredStatement<?>> unmaskList(
+            final @NonNull Object masked) {
+        return (ImmutableList) unmaskList(masked, DeclaredStatement.class);
+    }
+}
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractEffectiveStatement.java
new file mode 100644 (file)
index 0000000..1144f79
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022 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.model.api.meta;
+
+import com.google.common.collect.ImmutableList;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Empty;
+
+/**
+ * Abstract base class for {@link EffectiveStatement} implementations.
+ *
+ * @param <A> Argument type ({@link Empty} if statement does not have argument.)
+ * @param <D> Class representing declared version of this statement.
+ */
+public abstract non-sealed class AbstractEffectiveStatement<A, D extends DeclaredStatement<A>>
+        extends AbstractModelStatement<A> implements EffectiveStatement<A, D> {
+    /**
+     * Utility method for recovering singleton lists squashed by {@link #maskList(ImmutableList)}.
+     *
+     * @param masked list to unmask
+     * @return Unmasked list
+     * @throws NullPointerException if masked is null
+     * @throws ClassCastException if masked object does not match EffectiveStatement
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    protected static final @NonNull ImmutableList<? extends @NonNull EffectiveStatement<?, ?>> unmaskList(
+            final @NonNull Object masked) {
+        return (ImmutableList) unmaskList(masked, EffectiveStatement.class);
+    }
+}
similarity index 94%
rename from model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractModelStatement.java
rename to model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractModelStatement.java
index 0ae7e01b244e81b1ea78364ab9e9ffe07c6a976c..c424c6acbd759cc664b5d47061e6e274afc59e76 100644 (file)
@@ -5,7 +5,7 @@
  * 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.model.spi.meta;
+package org.opendaylight.yangtools.yang.model.api.meta;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.MoreObjects.ToStringHelper;
@@ -13,7 +13,6 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.Empty;
-import org.opendaylight.yangtools.yang.model.api.meta.ModelStatement;
 
 /**
  * Abstract base class for {@link ModelStatement} implementations. It mostly provides static methods for efficiently
@@ -21,8 +20,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.ModelStatement;
  *
  * @param <A> Argument type ({@link Empty} if statement does not have argument.)
  */
-abstract class AbstractModelStatement<A> implements ModelStatement<A> {
-
+abstract sealed class AbstractModelStatement<A> implements ModelStatement<A>
+        permits AbstractDeclaredStatement, AbstractEffectiveStatement {
     @Override
     public final int hashCode() {
         return System.identityHashCode(this);
index 639e52cef6e335cf56db4df79d81e51535718e4e..b4d253de7522c8e59995e0d07aa8cfd1e639e1d7 100644 (file)
@@ -24,7 +24,7 @@ import org.opendaylight.yangtools.yang.common.Empty;
  *
  * @param <A> Argument type ({@link Empty} if statement does not have argument.)
  */
-public interface DeclaredStatement<A> extends ModelStatement<A> {
+public non-sealed interface DeclaredStatement<A> extends ModelStatement<A> {
     /**
      * Returns statement argument as was present in original source.
      *
index 42b8daf03dca54278d3b93f519f7837f039db5fe..019034ffbd2f5f0d402b1c48c6b7f3699375420c 100644 (file)
@@ -22,7 +22,7 @@ import org.opendaylight.yangtools.yang.common.Empty;
  * @param <A> Argument type ({@link Empty} if statement does not have argument.)
  * @param <D> Class representing declared version of this statement.
  */
-public interface EffectiveStatement<A, D extends DeclaredStatement<A>> extends ModelStatement<A> {
+public non-sealed interface EffectiveStatement<A, D extends DeclaredStatement<A>> extends ModelStatement<A> {
     /**
      * Returns {@link StatementOrigin}, which denotes if statement was explicitly declared in original model or inferred
      * during semantic processing of model.
index 3a4e3b7c9d185fb7f5ad51eff5049b1c07c1b7ce..c9487c9fc44528074db2ab0dfa48f766295aec11 100644 (file)
@@ -26,8 +26,7 @@ import org.opendaylight.yangtools.yang.common.Empty;
  *
  * @param <A> Argument type ({@link Empty} if statement does not have argument.)
  */
-// FIXME: sealed interface when we have JDK17+
-public interface ModelStatement<A> {
+public sealed interface ModelStatement<A> permits DeclaredStatement, EffectiveStatement, AbstractModelStatement {
     /**
      * Statement Definition of this statement.
      *
index f6707b673ea14bc6a82ca27057eda2d880bfff12..4a54a3f500b3394aba46e18e380c5141f3dfeea8 100644 (file)
@@ -19,5 +19,6 @@ module org.opendaylight.yangtools.yang.model.spi {
     requires org.slf4j;
 
     // Annotations
+    requires static com.github.spotbugs.annotations;
     requires static transitive org.eclipse.jdt.annotation;
 }
index f6c1c7a5aaf42131caff53d61544f5d2ab0449fe..5ec3fe08f7ccd94390639f06ea81ed904262b76b 100644 (file)
@@ -44,8 +44,8 @@ import org.opendaylight.yangtools.yang.model.api.stmt.TypedefNamespace;
  * @param <D> Class representing declared version of this statement.
  */
 @Beta
-public abstract class AbstractDeclaredEffectiveStatement<A, D extends DeclaredStatement<A>>
-        extends AbstractEffectiveStatement<A, D> {
+public abstract non-sealed class AbstractDeclaredEffectiveStatement<A, D extends DeclaredStatement<A>>
+        extends AbstractIndexedEffectiveStatement<A, D> {
     @Override
     public abstract @NonNull D getDeclared();
 
index 274baf62a39215ee3772f06749c6d6f1c9595d93..904cd36236b61aed8260ab8de9793270f7bd3d8c 100644 (file)
@@ -12,6 +12,7 @@ import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -22,27 +23,15 @@ import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
  * stateful subclasses.
  */
 @Beta
-public abstract class AbstractDeclaredStatement<A> extends AbstractModelStatement<A> implements DeclaredStatement<A> {
+@SuppressFBWarnings(value = "NM_SAME_SIMPLE_NAME_AS_SUPERCLASS", justification = "Migration")
+public abstract class AbstractDeclaredStatement<A>
+        extends org.opendaylight.yangtools.yang.model.api.meta.AbstractDeclaredStatement<A> {
     @Override
     public ImmutableList<? extends DeclaredStatement<?>> declaredSubstatements() {
         // Default to reduce load on subclasses and keep the number of implementations down
         return ImmutableList.of();
     }
 
-    /**
-     * Utility method for recovering singleton lists squashed by {@link #maskList(ImmutableList)}.
-     *
-     * @param masked list to unmask
-     * @return Unmasked list
-     * @throws NullPointerException if masked is null
-     * @throws ClassCastException if masked object does not match DeclaredStatement
-     */
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    protected static final @NonNull ImmutableList<? extends DeclaredStatement<?>> unmaskList(
-            final @NonNull Object masked) {
-        return (ImmutableList) unmaskList(masked, DeclaredStatement.class);
-    }
-
     public abstract static class WithRawArgument<A> extends AbstractDeclaredStatement<A> {
         public abstract static class WithSubstatements<A> extends WithRawArgument<A> {
             private final @NonNull Object substatements;
@@ -19,6 +19,7 @@ import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.AbstractEffectiveStatement;
 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.IdentifierNamespace;
@@ -41,8 +42,9 @@ import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
  * @param <A> Argument type ({@link Empty} if statement does not have argument.)
  * @param <D> Class representing declared version of this statement.
  */
-abstract class AbstractEffectiveStatement<A, D extends DeclaredStatement<A>>
-        extends AbstractModelStatement<A> implements EffectiveStatement<A, D> {
+abstract sealed class AbstractIndexedEffectiveStatement<A, D extends DeclaredStatement<A>>
+        extends AbstractEffectiveStatement<A, D>
+        permits AbstractDeclaredEffectiveStatement, AbstractUndeclaredEffectiveStatement {
     @Override
     public final <K, V, N extends IdentifierNamespace<K, V>> Optional<V> get(final Class<N> namespace,
             final K identifier) {
@@ -71,20 +73,6 @@ abstract class AbstractEffectiveStatement<A, D extends DeclaredStatement<A>>
         return Optional.empty();
     }
 
-    /**
-     * Utility method for recovering singleton lists squashed by {@link #maskList(ImmutableList)}.
-     *
-     * @param masked list to unmask
-     * @return Unmasked list
-     * @throws NullPointerException if masked is null
-     * @throws ClassCastException if masked object does not match EffectiveStatement
-     */
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    protected static final @NonNull ImmutableList<? extends @NonNull EffectiveStatement<?, ?>> unmaskList(
-            final @NonNull Object masked) {
-        return (ImmutableList) unmaskList(masked, EffectiveStatement.class);
-    }
-
     // TODO: below methods need to find a better place, this is just a temporary hideout as their public class is on
     //       its way out
     /**
index 2cd305ef1bd4b1bebb71c10bfe23787d52847517..f7f2c0c0b62d435477b764d79e60c80a2a16d54a 100644 (file)
@@ -31,8 +31,8 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveSt
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 
 @Beta
-public abstract class AbstractUndeclaredEffectiveStatement<A, D extends DeclaredStatement<A>>
-        extends AbstractEffectiveStatement<A, D>  {
+public abstract non-sealed class AbstractUndeclaredEffectiveStatement<A, D extends DeclaredStatement<A>>
+        extends AbstractIndexedEffectiveStatement<A, D>  {
     @Override
     public final D getDeclared() {
         return null;
index 5ed27974b3b5367a1557f1100deebe74650297a1..f26a1355d1e9acddaebaeaa284a5228bfa791e14 100644 (file)
@@ -8,18 +8,30 @@
 package org.opendaylight.yangtools.yang.model.spi.meta;
 
 import com.google.common.annotations.Beta;
+import com.google.common.collect.ForwardingObject;
 import java.util.List;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclarationReference;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 /**
  * Common base class for forwarding implementations of {@link DeclaredStatement}.
  */
 @Beta
 public abstract class ForwardingDeclaredStatement<A, D extends DeclaredStatement<A>>
-        extends ForwardingModelStatement<A, D> implements DeclaredStatement<A> {
+        extends ForwardingObject implements DeclaredStatement<A> {
+    @Override
+    public StatementDefinition statementDefinition() {
+        return delegate().statementDefinition();
+    }
+
+    @Override
+    public A argument() {
+        return delegate().argument();
+    }
+
     @Override
     public String rawArgument() {
         return delegate().rawArgument();
diff --git a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/ForwardingModelStatement.java b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/ForwardingModelStatement.java
deleted file mode 100644 (file)
index fdf4071..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2021 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.model.spi.meta;
-
-import com.google.common.collect.ForwardingObject;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.model.api.meta.ModelStatement;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
-
-/**
- * Common base class for forwarding implementations of {@link ModelStatement}.
- */
-public abstract class ForwardingModelStatement<A, S extends ModelStatement<A>> extends ForwardingObject
-        implements ModelStatement<A> {
-    @Override
-    public StatementDefinition statementDefinition() {
-        return delegate().statementDefinition();
-    }
-
-    @Override
-    public A argument() {
-        return delegate().argument();
-    }
-
-    @Override
-    protected abstract @NonNull S delegate();
-}
index 0b6f131435064f9fdcbdd6dfb802fadf6c381f99..e93ffef77a766e18772b9bd8c018ae51b183bc8a 100644 (file)
@@ -12,7 +12,8 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.annotations.Beta;
 
 /**
- * Exception thrown when indexing of substatements of a {@link AbstractEffectiveStatement} fails.
+ * Exception thrown when indexing of substatements of either a {@link AbstractDeclaredEffectiveStatement} or
+ * {@link AbstractUndeclaredEffectiveStatement} fails.
  */
 @Beta
 public final class SubstatementIndexingException extends IllegalArgumentException {