Hide CodecContextSupplier
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / CodecDataObject.java
index a7d01e51ea92b83fd8930477faabdc8ba8e16100..a32e7ea3094eb8ad498349f388231385df1f1729 100644 (file)
@@ -7,17 +7,17 @@
  */
 package org.opendaylight.mdsal.binding.dom.codec.impl;
 
-import static com.google.common.base.Verify.verify;
 import static java.util.Objects.requireNonNull;
 
+import com.google.common.base.VerifyException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.lang.invoke.MethodHandles;
 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 +42,22 @@ 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)
+    @SuppressWarnings("unused")
+    @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749")
     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();
     }
 
@@ -78,12 +77,12 @@ public abstract class CodecDataObject<T extends DataObject> implements DataObjec
 
     protected final Object codecMember(final VarHandle handle, final Class<? extends DataObject> bindingClass) {
         final Object cached = handle.getAcquire(this);
-        return cached != null ? unmaskNull(cached) : loadMember(handle, context.streamChild(bindingClass));
+        return cached != null ? unmaskNull(cached) : loadMember(handle, context.getStreamChild(bindingClass));
     }
 
-    protected final Object codecMember(final VarHandle handle, final NodeContextSupplier supplier) {
+    protected final Object codecMember(final VarHandle handle, final CodecContextSupplier supplier) {
         final Object cached = handle.getAcquire(this);
-        return cached != null ? unmaskNull(cached) : loadMember(handle, supplier.get());
+        return cached != null ? unmaskNull(cached) : loadMember(handle, supplier.getCodecContext());
     }
 
     protected final @NonNull Object codecMemberOrEmpty(final @Nullable Object value,
@@ -92,9 +91,11 @@ public abstract class CodecDataObject<T extends DataObject> implements DataObjec
     }
 
     private @NonNull Object emptyObject(final @NonNull Class<? extends DataObject> bindingClass) {
-        final var childContext = context.streamChild(bindingClass);
-        verify(childContext instanceof NonPresenceContainerNodeCodecContext, "Unexpected context %s", childContext);
-        return ((NonPresenceContainerNodeCodecContext<?>) childContext).emptyObject();
+        final var childContext = context.getStreamChild(bindingClass);
+        if (childContext instanceof StructuralContainerCodecContext<?> structural) {
+            return structural.emptyObject();
+        }
+        throw new VerifyException("Unexpected context " + childContext);
     }
 
     protected final @NonNull Object codecKey(final VarHandle handle) {
@@ -110,15 +111,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());
+    private Object loadMember(final VarHandle handle, final CodecContext childCtx) {
+        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.
@@ -129,10 +128,14 @@ public abstract class CodecDataObject<T extends DataObject> implements DataObjec
 
     // Helper split out of codecKey to aid its inlining
     private @NonNull Object loadKey(final VarHandle handle) {
-        verify(data instanceof MapEntryNode, "Unsupported value %s", data);
-        verify(context instanceof KeyedListNodeCodecContext, "Unexpected context %s", context);
-        final Object obj = ((KeyedListNodeCodecContext<?, ?>) context)
-                .deserialize(((MapEntryNode) data).getIdentifier());
+        if (!(data instanceof MapEntryNode mapEntry)) {
+            throw new VerifyException("Unsupported value " + data);
+        }
+        if (!(context instanceof MapCodecContext<?, ?> listContext)) {
+            throw new VerifyException("Unexpected context " + context);
+        }
+
+        final Object obj = listContext.deserialize(mapEntry.name());
         // key is known to be non-null, no need to mask it
         final Object witness = handle.compareAndExchangeRelease(this, null, obj);
         return witness == null ? obj : witness;