Tighten AbstractDOMRpcImplementationAdapter.serialize()
[mdsal.git] / binding / mdsal-binding-dom-adapter / src / main / java / org / opendaylight / mdsal / binding / dom / adapter / AbstractDOMRpcImplementationAdapter.java
index 09e48806de0d8ac135c3640c275d2cdd70fb18e2..2778a0bca0d609223904318262366e703d151dd9 100644 (file)
@@ -7,22 +7,31 @@
  */
 package org.opendaylight.mdsal.binding.dom.adapter;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Verify.verifyNotNull;
 import static java.util.Objects.requireNonNull;
+import static org.opendaylight.mdsal.binding.dom.adapter.StaticConfiguration.ENABLE_CODEC_SHORTCUT;
 
 import com.google.common.util.concurrent.ListenableFuture;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingLazyContainerNode;
 import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.yang.binding.RpcInput;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
 abstract sealed class AbstractDOMRpcImplementationAdapter implements DOMRpcImplementation
         permits BindingDOMRpcImplementationAdapter, LegacyDOMRpcImplementationAdapter {
     private final AdapterContext adapterContext;
+    private final @NonNull QName inputName;
 
-    AbstractDOMRpcImplementationAdapter(final AdapterContext adapterContext) {
+    AbstractDOMRpcImplementationAdapter(final AdapterContext adapterContext, @NonNull QName inputName) {
         this.adapterContext = requireNonNull(adapterContext);
+        this.inputName = requireNonNull(inputName);
     }
 
     @Override
@@ -37,6 +46,24 @@ abstract sealed class AbstractDOMRpcImplementationAdapter implements DOMRpcImple
         return LazyDOMRpcResultFuture.create(serializer, invokeRpc(serializer, rpc, input));
     }
 
-    abstract @NonNull ListenableFuture<RpcResult<?>> invokeRpc(CurrentAdapterSerializer serializer,
-        DOMRpcIdentifier rpc, ContainerNode input);
+    abstract @NonNull ListenableFuture<RpcResult<?>> invokeRpc(@NonNull CurrentAdapterSerializer serializer,
+        @NonNull DOMRpcIdentifier rpc, @NonNull ContainerNode input);
+
+    final @NonNull RpcInput deserialize(final @NonNull CurrentAdapterSerializer serializer,
+            final @NonNull QName rpcName, final @NonNull ContainerNode input) {
+        if (ENABLE_CODEC_SHORTCUT && input instanceof BindingLazyContainerNode<?> lazy) {
+            return (RpcInput) lazy.getDataObject();
+        }
+
+        // TODO: this is a bit inefficient: typically we get the same CurrentAdapterSerializer and the path is also
+        //       constant, hence we should be able to cache this lookup and just have the appropriate
+        //       BindingDataObjectCodecTreeNode and reuse it directly
+        checkArgument(inputName.equals(input.getIdentifier().getNodeType()),
+            "Unexpected RPC %s input %s", rpcName, input);
+        // TODO: this is a bit inefficient: typically we get the same CurrentAdapterSerializer and the path is also
+        //       constant, hence we should be able to cache this lookup and just have the appropriate
+        //       BindingDataObjectCodecTreeNode and reuse it directly
+        // FIXME: should be a guaranteed return, as innput is @NonNull
+        return verifyNotNull((RpcInput) serializer.fromNormalizedNodeRpcData(Absolute.of(rpcName, inputName), input));
+    }
 }