Reduce use of BindingReflections in BindingNormalizedNodeSerializer
[yangtools.git] / binding / mdsal-binding-dom-codec-api / src / main / java / org / opendaylight / mdsal / binding / dom / codec / api / BindingNormalizedNodeSerializer.java
index 962a24f8b348bcceceb2b88a659e328f11ed31de..a3ce9deeaae14b7d57ef357d84af3c2c86811eed 100644 (file)
@@ -7,13 +7,19 @@
  */
 package org.opendaylight.mdsal.binding.dom.codec.api;
 
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import java.time.Instant;
 import java.util.Map.Entry;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.yangtools.yang.binding.Action;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.BaseNotification;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -24,14 +30,54 @@ import org.opendaylight.yangtools.yang.common.YangConstants;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
 /**
- * Serialization service, which provides two-way serialization between Java
- * Binding Data representation and NormalizedNode representation.
+ * Serialization service, which provides two-way serialization between Java Binding Data representation and
+ * NormalizedNode representation.
  */
 public interface BindingNormalizedNodeSerializer {
+    /**
+     * Result of a {@link BindingNormalizedNodeSerializer#toNormalizedNode(InstanceIdentifier, DataObject)}. Since the
+     * Binding {@link Augmentation} does not have an exact equivalent, there are two specializations of this class:
+     * {@link NodeResult} and {@link AugmentationResult}.
+     */
+    sealed interface NormalizedResult {
+        /**
+         * Return the {@link YangInstanceIdentifier} path of this result.
+         *
+         * @return A {@link YangInstanceIdentifier}
+         */
+        @NonNull YangInstanceIdentifier path();
+    }
+
+    /**
+     * A {@link NormalizedResult} for an {@link Augmentation}.
+     *
+     * @param path A YangInstanceIdentifier identifying the parent of this augmentation
+     * @param possibleChildren {@link NodeIdentifier}s of each possible child
+     * @param children Augmentation children
+     */
+    record AugmentationResult(
+            @NonNull YangInstanceIdentifier path,
+            @NonNull ImmutableSet<NodeIdentifier> possibleChildren,
+            @NonNull ImmutableList<DataContainerChild> children) implements NormalizedResult {
+        public AugmentationResult {
+            requireNonNull(path);
+            requireNonNull(possibleChildren);
+            requireNonNull(children);
+        }
+    }
+
+    record NodeResult(@NonNull YangInstanceIdentifier path, @NonNull NormalizedNode node) implements NormalizedResult {
+        public NodeResult {
+            requireNonNull(path);
+            requireNonNull(node);
+        }
+    }
+
     /**
      * Translates supplied Binding Instance Identifier into NormalizedNode instance identifier.
      *
@@ -39,7 +85,8 @@ public interface BindingNormalizedNodeSerializer {
      * @return DOM Instance Identifier
      * @throws IllegalArgumentException If supplied Instance Identifier is not valid.
      */
-    YangInstanceIdentifier toYangInstanceIdentifier(@NonNull InstanceIdentifier<?> binding);
+    // FIXME: MDSAL-525: reconcile this with BindingInstanceIdentifierCodec
+    @NonNull YangInstanceIdentifier toYangInstanceIdentifier(@NonNull InstanceIdentifier<?> binding);
 
     /**
      * Translates supplied YANG Instance Identifier into Binding instance identifier.
@@ -47,6 +94,7 @@ public interface BindingNormalizedNodeSerializer {
      * @param dom YANG Instance Identifier
      * @return Binding Instance Identifier, or null if the instance identifier is not representable.
      */
+    // FIXME: MDSAL-525: reconcile this with BindingInstanceIdentifierCodec
     <T extends DataObject> @Nullable InstanceIdentifier<T> fromYangInstanceIdentifier(
             @NonNull YangInstanceIdentifier dom);
 
@@ -55,11 +103,31 @@ public interface BindingNormalizedNodeSerializer {
      *
      * @param path Binding Instance Identifier pointing to data
      * @param data Data object representing data
-     * @return NormalizedNode representation
+     * @return {@link NormalizedResult} representation
      * @throws IllegalArgumentException If supplied Instance Identifier is not valid.
      */
-    <T extends DataObject> Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
-            InstanceIdentifier<T> path, T data);
+    <T extends DataObject> @NonNull NormalizedResult toNormalizedNode(InstanceIdentifier<T> path, T data);
+
+    /**
+     * Translates supplied Binding Instance Identifier and data into NormalizedNode representation.
+     *
+     * @param path Binding Instance Identifier pointing to data
+     * @param data Data object representing data
+     * @return {@link NormalizedResult} representation
+     * @throws IllegalArgumentException If supplied Instance Identifier is not valid.
+     */
+    <A extends Augmentation<?>> @NonNull AugmentationResult toNormalizedAugmentation(InstanceIdentifier<A> path,
+        A data);
+
+    /**
+     * Translates supplied Binding Instance Identifier and data into NormalizedNode representation.
+     *
+     * @param path Binding Instance Identifier pointing to data
+     * @param data Data object representing data
+     * @return {@link NormalizedResult} representation
+     * @throws IllegalArgumentException If supplied Instance Identifier is not valid.
+     */
+    <T extends DataObject> @NonNull NodeResult toNormalizedDataObject(InstanceIdentifier<T> path, T data);
 
     /**
      * Translates supplied YANG Instance Identifier and NormalizedNode into Binding data.
@@ -69,7 +137,7 @@ public interface BindingNormalizedNodeSerializer {
      * @return DOM Instance Identifier
      */
     @Nullable Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode(@NonNull YangInstanceIdentifier path,
-            NormalizedNode<?, ?> data);
+            NormalizedNode data);
 
     /**
      * Translates supplied NormalizedNode Notification into Binding data.
@@ -78,7 +146,7 @@ public interface BindingNormalizedNodeSerializer {
      * @param data NormalizedNode representing data
      * @return Binding representation of Notification
      */
-    @Nullable Notification fromNormalizedNodeNotification(@NonNull SchemaPath path, @NonNull ContainerNode data);
+    @NonNull BaseNotification fromNormalizedNodeNotification(@NonNull Absolute path, @NonNull ContainerNode data);
 
     /**
      * Translates supplied NormalizedNode Notification into Binding data, optionally taking an instant
@@ -90,17 +158,17 @@ public interface BindingNormalizedNodeSerializer {
      * @return Binding representation of Notification
      */
     @Beta
-    @Nullable Notification fromNormalizedNodeNotification(@NonNull SchemaPath path, @NonNull ContainerNode data,
+    @NonNull BaseNotification fromNormalizedNodeNotification(@NonNull Absolute path, @NonNull ContainerNode data,
             @Nullable Instant eventInstant);
 
     /**
      * Translates supplied NormalizedNode RPC input or output into Binding data.
      *
-     * @param path Schema path of RPC data, Schema path consists of rpc QName and input / output QName.
+     * @param containerPath Container path (RPC type + input/output)
      * @param data NormalizedNode representing data
      * @return Binding representation of RPC data
      */
-    @Nullable DataObject fromNormalizedNodeRpcData(@NonNull SchemaPath path, @NonNull ContainerNode data);
+    @Nullable DataObject fromNormalizedNodeRpcData(@NonNull Absolute containerPath, @NonNull ContainerNode data);
 
     /**
      * Translates supplied ContainerNode action input.
@@ -129,10 +197,19 @@ public interface BindingNormalizedNodeSerializer {
     /**
      * Translates supplied Binding Notification or output into NormalizedNode notification.
      *
-     * @param data NormalizedNode representing notification data
+     * @param data {@link Notification} representing notification data
      * @return NormalizedNode representation of notification
      */
-    @NonNull ContainerNode toNormalizedNodeNotification(@NonNull Notification data);
+    @NonNull ContainerNode toNormalizedNodeNotification(@NonNull Notification<?> data);
+
+    /**
+     * Translates supplied Binding Notification or output into NormalizedNode notification.
+     *
+     * @param path schema node identifier of the notification
+     * @param data {@link BaseNotification} representing notification data
+     * @return NormalizedNode representation of notification
+     */
+    @NonNull ContainerNode toNormalizedNodeNotification(@NonNull Absolute path, @NonNull BaseNotification data);
 
     /**
      * Translates supplied Binding RPC input or output into NormalizedNode data.
@@ -163,7 +240,8 @@ public interface BindingNormalizedNodeSerializer {
      * @return NormalizedNode representation of action input
      * @throws NullPointerException if any of the arguments is null
      */
-    @Beta default @NonNull BindingLazyContainerNode<RpcInput> toLazyNormalizedNodeActionInput(
+    @Beta
+    default @NonNull BindingLazyContainerNode<RpcInput> toLazyNormalizedNodeActionInput(
             @NonNull final Class<? extends Action<?, ?, ?>> action, @NonNull final RpcInput input) {
         return toLazyNormalizedNodeActionInput(action,
             new NodeIdentifier(YangConstants.operationInputQName(BindingReflections.getQNameModule(action))), input);
@@ -177,12 +255,9 @@ public interface BindingNormalizedNodeSerializer {
      * @return NormalizedNode representation of action input
      * @throws NullPointerException if any of the arguments is null
      */
-    @Beta default @NonNull ContainerNode toNormalizedNodeActionInput(
-            @NonNull final Class<? extends Action<?, ?, ?>> action, @NonNull final RpcInput input) {
-        return toLazyNormalizedNodeActionInput(action,
-            new NodeIdentifier(YangConstants.operationInputQName(BindingReflections.getQNameModule(action))), input)
-                .getDelegate();
-    }
+    @Beta
+    @NonNull ContainerNode toNormalizedNodeActionInput(@NonNull Class<? extends Action<?, ?, ?>> action,
+        @NonNull RpcInput input);
 
     /**
      * Lazily translates supplied Binding action output into NormalizedNode data.
@@ -206,7 +281,7 @@ public interface BindingNormalizedNodeSerializer {
     @Beta default @NonNull BindingLazyContainerNode<RpcOutput> toLazyNormalizedNodeActionOutput(
             @NonNull final Class<? extends Action<?, ?, ?>> action, @NonNull final RpcOutput output) {
         return toLazyNormalizedNodeActionOutput(action,
-            new NodeIdentifier(YangConstants.operationInputQName(BindingReflections.getQNameModule(action))), output);
+            new NodeIdentifier(YangConstants.operationOutputQName(BindingReflections.getQNameModule(action))), output);
     }
 
     /**
@@ -215,10 +290,7 @@ public interface BindingNormalizedNodeSerializer {
      * @param output Binding action output
      * @return NormalizedNode representation of action output
      */
-    @Beta default @NonNull ContainerNode toNormalizedNodeActionOutput(
-            @NonNull final Class<? extends Action<?, ?, ?>> action, @NonNull final RpcOutput output) {
-        return toLazyNormalizedNodeActionOutput(action,
-            new NodeIdentifier(YangConstants.operationInputQName(BindingReflections.getQNameModule(action))), output)
-                .getDelegate();
-    }
+    @Beta
+    @NonNull ContainerNode toNormalizedNodeActionOutput(@NonNull Class<? extends Action<?, ?, ?>> action,
+        @NonNull RpcOutput output);
 }