Refactor PathArgument to DataObjectStep
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / AbstractDataObjectCodecContext.java
index f5a31aa9825f760b07a8e5424be990ccc301f239..83e9b0f721511dafc0b1aa28e148adba2ddac910 100644 (file)
@@ -7,10 +7,8 @@
  */
 package org.opendaylight.mdsal.binding.dom.codec.impl;
 
-import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import java.lang.invoke.MethodHandle;
 import java.util.List;
 import java.util.Map;
 import org.eclipse.jdt.annotation.NonNull;
@@ -19,9 +17,8 @@ import org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException;
 import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.DataObjectStep;
 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.DataContainerNode;
 import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
@@ -46,103 +43,57 @@ import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
 public abstract sealed class AbstractDataObjectCodecContext<D extends DataObject, T extends CompositeRuntimeType>
         extends CommonDataObjectCodecContext<D, T>
         permits AugmentationCodecContext, DataObjectCodecContext {
-    private final ImmutableMap<Class<?>, CommonDataObjectCodecPrototype<?>> byBindingArgClass;
-    private final ImmutableMap<Class<?>, CommonDataObjectCodecPrototype<?>> byStreamClass;
+    private final ImmutableMap<Class<?>, DataContainerPrototype<?, ?>> byBindingArgClass;
+    private final ImmutableMap<Class<?>, DataContainerPrototype<?, ?>> byStreamClass;
     private final ImmutableMap<NodeIdentifier, CodecContextSupplier> byYang;
     private final ImmutableMap<String, ValueNodeCodecContext> leafChild;
-    private final MethodHandle proxyConstructor;
 
     AbstractDataObjectCodecContext(final CommonDataObjectCodecPrototype<T> prototype,
-            final CodecDataObjectAnalysis<T> analysis) {
+            final DataContainerAnalysis<T> analysis) {
         super(prototype);
         byBindingArgClass = analysis.byBindingArgClass;
         byStreamClass = analysis.byStreamClass;
         byYang = analysis.byYang;
         leafChild = analysis.leafNodes;
-        proxyConstructor = analysis.proxyConstructor;
     }
 
     @Override
     public final WithStatus getSchema() {
         // FIXME: Bad cast, we should be returning an EffectiveStatement perhaps?
-        return (WithStatus) type().statement();
+        return (WithStatus) prototype().runtimeType().statement();
     }
 
     @Override
-    public final <C extends DataObject> CommonDataObjectCodecContext<C, ?> getStreamChild(final Class<C> childClass) {
-        return childNonNull(streamChild(childClass), childClass,
-            "Child %s is not valid child of %s", getBindingClass(), childClass);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public final <C extends DataObject> CommonDataObjectCodecContext<C, ?> streamChild(final Class<C> childClass) {
-        final var childProto = streamChildPrototype(childClass);
-        return childProto == null ? null : (CommonDataObjectCodecContext<C, ?>) childProto.get();
-    }
-
-    @Nullable CommonDataObjectCodecPrototype<?> streamChildPrototype(final @NonNull Class<?> childClass) {
+    DataContainerPrototype<?, ?> streamChildPrototype(final Class<?> childClass) {
         return byStreamClass.get(childClass);
     }
 
     @Override
-    public final CommonDataObjectCodecContext<?, ?> bindingPathArgumentChild(final InstanceIdentifier.PathArgument arg,
+    public final CommonDataObjectCodecContext<?, ?> bindingPathArgumentChild(final DataObjectStep<?> step,
             final List<PathArgument> builder) {
-        final var argType = arg.getType();
-        final var context = childNonNull(pathChildPrototype(argType), argType,
-            "Class %s is not valid child of %s", argType, getBindingClass())
-            .get();
-        if (context instanceof ChoiceCodecContext<?> choice) {
-            choice.addYangPathArgument(arg, builder);
-
-            final var caseType = arg.getCaseType();
-            final var type = arg.getType();
-            final DataContainerCodecContext<?, ?> caze;
-            if (caseType.isPresent()) {
-                // Non-ambiguous addressing this should not pose any problems
-                caze = choice.getStreamChild(caseType.orElseThrow());
-            } else {
-                caze = choice.getCaseByChildClass(type);
-            }
-
-            caze.addYangPathArgument(arg, builder);
-            return caze.bindingPathArgumentChild(arg, builder);
+        final var type = step.type();
+        final var context = childNonNull(pathChildPrototype(type), type,
+            "Class %s is not valid child of %s", type, getBindingClass())
+            .getCodecContext();
+        context.addYangPathArgument(step, builder);
+        if (context instanceof CommonDataObjectCodecContext<?, ?> dataObject) {
+            return dataObject;
+        } else if (context instanceof ChoiceCodecContext<?> choice) {
+            return choice.bindingPathArgumentChild(step, builder);
+        } else {
+            throw new IllegalStateException("Unhandled context " + context);
         }
-        context.addYangPathArgument(arg, builder);
-        return context;
     }
 
-    @Nullable CommonDataObjectCodecPrototype<?> pathChildPrototype(final @NonNull Class<? extends DataObject> argType) {
+    @Nullable DataContainerPrototype<?, ?> pathChildPrototype(final @NonNull Class<? extends DataObject> argType) {
         return byBindingArgClass.get(argType);
     }
 
     @Override
-    public final CodecContext yangPathArgumentChild(final PathArgument arg) {
-        CodecContextSupplier supplier;
-        if (arg instanceof NodeIdentifier nodeId) {
-            supplier = yangChildSupplier(nodeId);
-        } else if (arg instanceof NodeIdentifierWithPredicates nip) {
-            supplier = yangChildSupplier(new NodeIdentifier(nip.getNodeType()));
-        } else {
-            supplier = null;
-        }
-        return childNonNull(supplier, arg, "Argument %s is not valid child of %s", arg, getSchema()).get();
-    }
-
-    @Nullable CodecContextSupplier yangChildSupplier(final @NonNull NodeIdentifier arg) {
+    CodecContextSupplier yangChildSupplier(final NodeIdentifier arg) {
         return byYang.get(arg);
     }
 
-    @SuppressWarnings("checkstyle:illegalCatch")
-    final @NonNull D createBindingProxy(final DataContainerNode node) {
-        try {
-            return (D) proxyConstructor.invokeExact(this, node);
-        } catch (final Throwable e) {
-            Throwables.throwIfUnchecked(e);
-            throw new IllegalStateException(e);
-        }
-    }
-
     final ValueNodeCodecContext getLeafChild(final String name) {
         final ValueNodeCodecContext value = leafChild.get(name);
         if (value == null) {