Hide CodecContextSupplier
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / AbstractDataObjectCodecContext.java
index 8b07157ad295e239818002057b24f92e32791288..0afa5e63e45a932d1ba14757198ffe58c21c7cda 100644 (file)
@@ -7,13 +7,10 @@
  */
 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 java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException;
@@ -22,14 +19,12 @@ 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.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;
 
 /**
- * Abstract base for {@link DataObjectCodecContext} and {@link AugmentationNodeContext}. They share most of their
+ * Abstract base for {@link DataObjectCodecContext} and {@link AugmentationCodecContext}. They share most of their
  * mechanics, but notably:
  * <ol>
  *   <li>DataObjectCodecContext has an exact DistinctNodeContainer and YangInstanceIdentifier mapping and can be the
@@ -45,60 +40,42 @@ import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
  * While this class is public, it not part of API surface and is an implementation detail. The only reason for it being
  * public is that it needs to be accessible by code generated at runtime.
  */
-public abstract class AbstractDataObjectCodecContext<D extends DataObject, T extends CompositeRuntimeType>
-        extends DataContainerCodecContext<D, T> {
-    private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byBindingArgClass;
-    private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byStreamClass;
-    private final ImmutableMap<PathArgument, NodeContextSupplier> byYang;
+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<NodeIdentifier, CodecContextSupplier> byYang;
     private final ImmutableMap<String, ValueNodeCodecContext> leafChild;
-    private final MethodHandle proxyConstructor;
 
-    AbstractDataObjectCodecContext(final DataContainerCodecPrototype<T> prototype,
-            final CodecDataObjectAnalysis<T> analysis) {
+    AbstractDataObjectCodecContext(final CommonDataObjectCodecPrototype<T> prototype,
+            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) getType().statement();
+        return (WithStatus) type().statement();
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public final <C extends DataObject> DataContainerCodecContext<C, ?> streamChild(final Class<C> childClass) {
-        return (DataContainerCodecContext<C, ?>) childNonNull(streamChildPrototype(childClass), childClass,
-            "Child %s is not valid child of %s", getBindingClass(), childClass).get();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public final <C extends DataObject> Optional<DataContainerCodecContext<C, ?>> possibleStreamChild(
-            final Class<C> childClass) {
-        final var childProto = streamChildPrototype(childClass);
-        if (childProto != null) {
-            return Optional.of((DataContainerCodecContext<C, ?>) childProto.get());
-        }
-        return Optional.empty();
-    }
-
-    @Nullable DataContainerCodecPrototype<?> streamChildPrototype(final @NonNull Class<?> childClass) {
+    CommonDataObjectCodecPrototype<?> streamChildPrototype(final Class<?> childClass) {
         return byStreamClass.get(childClass);
     }
 
     @Override
-    public final DataContainerCodecContext<?, ?> bindingPathArgumentChild(final InstanceIdentifier.PathArgument arg,
+    public final CommonDataObjectCodecContext<?, ?> bindingPathArgumentChild(final InstanceIdentifier.PathArgument arg,
             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 ChoiceNodeCodecContext<?> choice) {
+            .getCodecContext();
+        if (context instanceof ChoiceCodecContext<?> choice) {
             choice.addYangPathArgument(arg, builder);
 
             final var caseType = arg.getCaseType();
@@ -106,7 +83,7 @@ public abstract class AbstractDataObjectCodecContext<D extends DataObject, T ext
             final DataContainerCodecContext<?, ?> caze;
             if (caseType.isPresent()) {
                 // Non-ambiguous addressing this should not pose any problems
-                caze = choice.streamChild(caseType.orElseThrow());
+                caze = choice.getStreamChild(caseType.orElseThrow());
             } else {
                 caze = choice.getCaseByChildClass(type);
             }
@@ -118,34 +95,15 @@ public abstract class AbstractDataObjectCodecContext<D extends DataObject, T ext
         return context;
     }
 
-    @Nullable DataContainerCodecPrototype<?> pathChildPrototype(final @NonNull Class<? extends DataObject> argType) {
+    @Nullable CommonDataObjectCodecPrototype<?> pathChildPrototype(final @NonNull Class<? extends DataObject> argType) {
         return byBindingArgClass.get(argType);
     }
 
     @Override
-    public final NodeCodecContext yangPathArgumentChild(final PathArgument arg) {
-        final var lookup = arg instanceof NodeIdentifierWithPredicates ? new NodeIdentifier(arg.getNodeType()) : arg;
-        return childNonNull(yangChildSupplier(lookup), arg,
-            "Argument %s is not valid child of %s", arg, getSchema())
-            .get();
-    }
-
-    // FIXME: Never contains NodeIdentifierWithPredicates, what about NodeWithValue?
-    //        If it can't be here, it is always NodeIdentifier and we should specify that
-    @Nullable NodeContextSupplier yangChildSupplier(final @NonNull PathArgument arg) {
+    CodecContextSupplier yangChildSupplier(final NodeIdentifier arg) {
         return byYang.get(arg);
     }
 
-    @SuppressWarnings("checkstyle:illegalCatch")
-    final @NonNull D createBindingProxy(final DistinctNodeContainer<?, ?> 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) {
@@ -154,10 +112,10 @@ public abstract class AbstractDataObjectCodecContext<D extends DataObject, T ext
         return value;
     }
 
-    final @NonNull ImmutableSet<PathArgument> byYangKeySet() {
+    final @NonNull ImmutableSet<NodeIdentifier> byYangKeySet() {
         return byYang.keySet();
     }
 
-    abstract Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentationsFrom(
-        DistinctNodeContainer<PathArgument, NormalizedNode> data);
+    abstract @NonNull Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentationsFrom(
+        DataContainerNode data);
 }