Sharpen CodecDataObject.data 73/106373/2
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 4 Jun 2023 19:51:49 +0000 (21:51 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 4 Jun 2023 20:07:24 +0000 (22:07 +0200)
Since we do not have AugmentationNodes, we now know that all
DistinctNodeContainers backing CodecDataObject are DataContainerNodes.
Sharpen the contract, which gets rid of some ugliness around generic
arguments.

Change-Id: I097e6fda0ca312fc808f2ac2d4e0bbc6ac679315
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/AbstractDataObjectCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/AugmentableCodecDataObject.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/AugmentationNodeContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecDataObject.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecDataObjectAnalysis.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/LazyBindingList.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/NotificationCodecContext.java

index d993fb5d137a32558bd5817e3f9584bed63e596f..8849c2ef177c88f3a5279376ea2f1fc25a60a6ac 100644 (file)
@@ -24,8 +24,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
 
 /**
@@ -140,7 +139,7 @@ public abstract class AbstractDataObjectCodecContext<D extends DataObject, T ext
     }
 
     @SuppressWarnings("checkstyle:illegalCatch")
-    final @NonNull D createBindingProxy(final DistinctNodeContainer<?, ?> node) {
+    final @NonNull D createBindingProxy(final DataContainerNode node) {
         try {
             return (D) proxyConstructor.invokeExact(this, node);
         } catch (final Throwable e) {
@@ -161,6 +160,6 @@ public abstract class AbstractDataObjectCodecContext<D extends DataObject, T ext
         return byYang.keySet();
     }
 
-    abstract Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentationsFrom(
-        DistinctNodeContainer<PathArgument, NormalizedNode> data);
+    abstract @NonNull Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentationsFrom(
+        DataContainerNode data);
 }
index 25eadbf195c7a55ffff3bf277ede79c697dab7ef..5791d5f817e1e7ebb96fa46c10932dc44a708c25 100644 (file)
@@ -12,13 +12,13 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.collect.ImmutableMap;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
+import java.util.Map;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.binding.Augmentable;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
 
 /**
  * A base class for {@link DataObject}s which are also {@link Augmentable}, backed by {@link DataObjectCodecContext}.
@@ -45,7 +45,7 @@ public abstract class AugmentableCodecDataObject<T extends DataObject & Augmenta
     private volatile ImmutableMap<Class<? extends Augmentation<T>>, Augmentation<T>> cachedAugmentations;
 
     protected AugmentableCodecDataObject(final AbstractDataObjectCodecContext<T, ?> context,
-            final DistinctNodeContainer<?, ?> data) {
+            final DataContainerNode data) {
         super(context, data);
     }
 
@@ -69,7 +69,7 @@ public abstract class AugmentableCodecDataObject<T extends DataObject & Augmenta
             // the augmentation the user is requesting -- otherwise a strict receiver would end up with a cryptic
             // ClassCastException.
             if (augmentationType.isAssignableFrom(augCtx.getBindingClass())) {
-                final var augObj = augCtx.filterFrom((DataContainerNode) codecData());
+                final var augObj = augCtx.filterFrom(codecData());
                 if (augObj != null) {
                     return augObj;
                 }
@@ -80,7 +80,7 @@ public abstract class AugmentableCodecDataObject<T extends DataObject & Augmenta
 
     @Override
     public final ImmutableMap<Class<? extends Augmentation<T>>, Augmentation<T>> augmentations() {
-        final ImmutableMap<Class<? extends Augmentation<T>>, Augmentation<T>> local = acquireAugmentations();
+        final var local = acquireAugmentations();
         return local != null ? local : loadAugmentations();
     }
 
@@ -90,7 +90,9 @@ public abstract class AugmentableCodecDataObject<T extends DataObject & Augmenta
 
     @SuppressWarnings("unchecked")
     private @NonNull ImmutableMap<Class<? extends Augmentation<T>>, Augmentation<T>> loadAugmentations() {
-        final var ret = ImmutableMap.copyOf(codecContext().getAllAugmentationsFrom(codecData()));
+        @SuppressWarnings("rawtypes")
+        final Map extracted = codecContext().getAllAugmentationsFrom(codecData());
+        final var ret = ImmutableMap.<Class<? extends Augmentation<T>>, Augmentation<T>>copyOf(extracted);
         final Object witness = CACHED_AUGMENTATIONS.compareAndExchangeRelease(this, null, ret);
         return witness == null ? ret : (ImmutableMap<Class<? extends Augmentation<T>>, Augmentation<T>>) witness;
     }
index 10a591063e9a3a540d59953784f4317f4b8d89be..1abdb5f58f169f7a026c96f108c72f1cafd17898 100644 (file)
@@ -18,7 +18,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 final class AugmentationNodeContext<D extends DataObject & Augmentation<?>>
@@ -73,8 +72,7 @@ final class AugmentationNodeContext<D extends DataObject & Augmentation<?>>
     }
 
     @Override
-    Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentationsFrom(
-            final DistinctNodeContainer<PathArgument, NormalizedNode> data) {
+    Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentationsFrom(final DataContainerNode data) {
         return Map.of();
     }
 }
index 24e3af78bfea1a00e211889cf125817e1383bd86..1aa856a3dea4cc3b5e49035d79cfdab31c39215e 100644 (file)
@@ -15,9 +15,8 @@ import java.lang.invoke.VarHandle;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 /**
  * A base class for {@link DataObject}s backed by {@link DataObjectCodecContext}. While this class is public, it not
@@ -42,23 +41,21 @@ public abstract class CodecDataObject<T extends DataObject> implements DataObjec
     }
 
     private final @NonNull AbstractDataObjectCodecContext<T, ?> context;
-    @SuppressWarnings("rawtypes")
-    private final @NonNull DistinctNodeContainer data;
+    private final @NonNull DataContainerNode data;
 
     // Accessed via a VarHandle
     @SuppressWarnings("unused")
     // FIXME: consider using a primitive int-based cache (with 0 being uninit)
     private volatile Integer cachedHashcode;
 
-    protected CodecDataObject(final AbstractDataObjectCodecContext<T, ?> context,
-            final DistinctNodeContainer<?, ?> data) {
+    protected CodecDataObject(final AbstractDataObjectCodecContext<T, ?> context, final DataContainerNode data) {
         this.data = requireNonNull(data, "Data must not be null");
         this.context = requireNonNull(context, "Context must not be null");
     }
 
     @Override
     public final int hashCode() {
-        final Integer cached = (Integer) CACHED_HASH_CODE.getAcquire(this);
+        final var cached = (Integer) CACHED_HASH_CODE.getAcquire(this);
         return cached != null ? cached : loadHashCode();
     }
 
@@ -110,15 +107,13 @@ public abstract class CodecDataObject<T extends DataObject> implements DataObjec
         return context;
     }
 
-    @SuppressWarnings("rawtypes")
-    final @NonNull DistinctNodeContainer codecData() {
+    final @NonNull DataContainerNode codecData() {
         return data;
     }
 
     // Helper split out of codecMember to aid its inlining
     private Object loadMember(final VarHandle handle, final NodeCodecContext childCtx) {
-        @SuppressWarnings("unchecked")
-        final NormalizedNode child = data.childByArg(childCtx.getDomPathArgument());
+        final var child = data.childByArg(childCtx.getDomPathArgument());
 
         // We do not want to use Optional.map() here because we do not want to invoke defaultObject() when we have
         // normal value because defaultObject() may end up throwing an exception intentionally.
index e3b379c32cf9ab47e0118321247671520a02150a..ca447d8a65e0e076347424eed434d808c753f923 100644 (file)
@@ -33,7 +33,7 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.OpaqueObject;
 import org.opendaylight.yangtools.yang.binding.contract.Naming;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 
 /**
  * Analysis of a {@link DataObject} specialization class. The primary point of this class is to separate out creation
@@ -42,9 +42,9 @@ import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
  */
 final class CodecDataObjectAnalysis<R extends CompositeRuntimeType> {
     private static final MethodType CONSTRUCTOR_TYPE = MethodType.methodType(void.class,
-        AbstractDataObjectCodecContext.class, DistinctNodeContainer.class);
+        AbstractDataObjectCodecContext.class, DataContainerNode.class);
     private static final MethodType DATAOBJECT_TYPE = MethodType.methodType(DataObject.class,
-        AbstractDataObjectCodecContext.class, DistinctNodeContainer.class);
+        AbstractDataObjectCodecContext.class, DataContainerNode.class);
 
     final @NonNull ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byStreamClass;
     final @NonNull ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byBindingArgClass;
index bccc10790c05fbfd0d83d2692f8de927ca07a249..99735f9e1ae1342426a6d5029f150f65f7c16296 100644 (file)
@@ -35,7 +35,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
@@ -240,8 +240,7 @@ public abstract class DataObjectCodecContext<D extends DataObject, T extends Com
 
     @Override
     @SuppressWarnings("unchecked")
-    Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentationsFrom(
-            final DistinctNodeContainer<PathArgument, NormalizedNode> data) {
+    Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentationsFrom(final DataContainerNode data) {
         /**
          * Due to augmentation fields are at same level as direct children the data of each augmentation needs to be
          * aggregated into own container node, then only deserialized using associated prototype.
index 3164084cf73a14dbaca2a5eec800486b8c65dfff..adbc7ffeb6fdd047b9fb4782d69a1695b974e87d 100644 (file)
@@ -22,7 +22,7 @@ import java.util.function.UnaryOperator;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -73,7 +73,7 @@ final class LazyBindingList<E extends DataObject> extends AbstractList<E> implem
     }
 
     static <E extends DataObject> @NonNull List<E> create(final ListNodeCodecContext<E> codec, final int size,
-            final Collection<? extends DistinctNodeContainer<?, ?>> entries) {
+            final Collection<? extends DataContainerNode> entries) {
         if (size == 1) {
             // Do not bother with lazy instantiation in case of a singleton
             return List.of(codec.createBindingProxy(entries.iterator().next()));
@@ -82,11 +82,11 @@ final class LazyBindingList<E extends DataObject> extends AbstractList<E> implem
     }
 
     private static <E extends DataObject> @NonNull List<E> eagerList(final ListNodeCodecContext<E> codec,
-            final int size, final Collection<? extends DistinctNodeContainer<?, ?>> entries) {
+            final int size, final Collection<? extends DataContainerNode> entries) {
         @SuppressWarnings("unchecked")
         final E[] objs = (E[]) new DataObject[size];
         int offset = 0;
-        for (DistinctNodeContainer<?, ?> node : entries) {
+        for (var node : entries) {
             objs[offset++] = codec.createBindingProxy(node);
         }
         verify(offset == objs.length);
@@ -107,10 +107,10 @@ final class LazyBindingList<E extends DataObject> extends AbstractList<E> implem
         //
         // We could do a Class.isInstance() check here, but since the implementation is not marked as final (yet) we
         // would be at the mercy of CHA being able to prove this invariant.
-        return obj.getClass() == codec.generatedClass() ? (E) obj : load(index, (DistinctNodeContainer<?, ?>) obj);
+        return obj.getClass() == codec.generatedClass() ? (E) obj : load(index, (DataContainerNode) obj);
     }
 
-    private @NonNull E load(final int index, final DistinctNodeContainer<?, ?> node) {
+    private @NonNull E load(final int index, final DataContainerNode node) {
         final E ret = codec.createBindingProxy(node);
         final Object witness;
         return (witness = OBJ_AA.compareAndExchangeRelease(objects, index, node, ret)) == node ? ret : (E) witness;
index 64615d607f9b4c0ac89661ee21847ab7698830ff..b8cd98075dcbc10aa6592f7ba864db1334646943 100644 (file)
@@ -40,7 +40,7 @@ import org.opendaylight.yangtools.yang.binding.BaseNotification;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.EventInstantAware;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 final class NotificationCodecContext<D extends DataObject & BaseNotification>
@@ -57,11 +57,11 @@ final class NotificationCodecContext<D extends DataObject & BaseNotification>
     }
 
     private static final Generic BB_DOCC = TypeDefinition.Sort.describe(DataObjectCodecContext.class);
-    private static final Generic BB_DNC = TypeDefinition.Sort.describe(DistinctNodeContainer.class);
+    private static final Generic BB_DCN = TypeDefinition.Sort.describe(DataContainerNode.class);
     private static final Generic BB_I = TypeDefinition.Sort.describe(Instant.class);
 
     private static final MethodType CONSTRUCTOR_TYPE = MethodType.methodType(void.class, DataObjectCodecContext.class,
-        DistinctNodeContainer.class, Instant.class);
+        DataContainerNode.class, Instant.class);
     private static final MethodType NOTIFICATION_TYPE = MethodType.methodType(BaseNotification.class,
         NotificationCodecContext.class, ContainerNode.class, Instant.class);
     private static final String INSTANT_FIELD = "instant";
@@ -83,7 +83,7 @@ final class NotificationCodecContext<D extends DataObject & BaseNotification>
                     .name(fqcn)
                     .defineField(INSTANT_FIELD, BB_I, Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC)
                     .defineConstructor(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC)
-                        .withParameters(BB_DOCC, BB_DNC, BB_I)
+                        .withParameters(BB_DOCC, BB_DCN, BB_I)
                         .intercept(ConstructorImplementation.INSTANCE)
                     .defineMethod(EVENT_INSTANT_NAME, EVENT_INSTANT_RETTYPE, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC)
                         .intercept(EventInstantImplementation.INSTANCE)
@@ -131,7 +131,7 @@ final class NotificationCodecContext<D extends DataObject & BaseNotification>
             try {
                 LOAD_CTOR_ARGS = MethodVariableAccess.allArgumentsOf(new MethodDescription.ForLoadedConstructor(
                     AugmentableCodecDataObject.class.getDeclaredConstructor(AbstractDataObjectCodecContext.class,
-                        DistinctNodeContainer.class)));
+                        DataContainerNode.class)));
             } catch (NoSuchMethodException e) {
                 throw new ExceptionInInitializerError(e);
             }