Hide CodecContextSupplier
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / DataContainerCodecContext.java
index 15363426a8ceecd52dfa92a00e065fc20194e7d6..4dec5e68c35795b85817906898d0d9f09d065982 100644 (file)
@@ -12,6 +12,7 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableSet;
 import edu.umd.cs.findbugs.annotations.CheckReturnValue;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
@@ -42,8 +43,9 @@ import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+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.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizationResultHolder;
@@ -79,6 +81,7 @@ abstract sealed class DataContainerCodecContext<D extends BindingObject & DataCo
 
     // Accessed via a VarHandle
     @SuppressWarnings("unused")
+    @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749")
     private volatile DataContainerSerializer eventStreamSerializer;
 
     DataContainerCodecContext(final T type) {
@@ -94,8 +97,21 @@ abstract sealed class DataContainerCodecContext<D extends BindingObject & DataCo
 
     protected abstract @NonNull T type();
 
+    // Non-final for ChoiceCodecContext
     @Override
-    public abstract CodecContext yangPathArgumentChild(YangInstanceIdentifier.PathArgument arg);
+    public CodecContext yangPathArgumentChild(final YangInstanceIdentifier.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()).getCodecContext();
+    }
+
+    abstract @Nullable CodecContextSupplier yangChildSupplier(@NonNull NodeIdentifier arg);
 
     @Override
     public CommonDataObjectCodecContext<?, ?> bindingPathArgumentChild(final PathArgument arg,
@@ -130,8 +146,14 @@ abstract sealed class DataContainerCodecContext<D extends BindingObject & DataCo
             "Child %s is not valid child of %s", getBindingClass(), childClass);
     }
 
+    @SuppressWarnings("unchecked")
     @Override
-    public abstract <C extends DataObject> CommonDataObjectCodecContext<C, ?> streamChild(Class<C> childClass);
+    public final <C extends DataObject> CommonDataObjectCodecContext<C, ?> streamChild(final Class<C> childClass) {
+        final var childProto = streamChildPrototype(requireNonNull(childClass));
+        return childProto == null ? null : (CommonDataObjectCodecContext<C, ?>) childProto.getCodecContext();
+    }
+
+    abstract @Nullable CommonDataObjectCodecPrototype<?> streamChildPrototype(@NonNull Class<?> childClass);
 
     @Override
     public String toString() {
@@ -171,8 +193,8 @@ abstract sealed class DataContainerCodecContext<D extends BindingObject & DataCo
 
     @CheckReturnValue
     private IllegalArgumentException childNullException(final QName child, final String message, final Object... args) {
-        final QNameModule module = child.getModule();
-        if (!factory().getRuntimeContext().getEffectiveModelContext().findModule(module).isPresent()) {
+        final var module = child.getModule();
+        if (!factory().getRuntimeContext().modelContext().findModule(module).isPresent()) {
             return new MissingSchemaException("Module " + module + " is not present in current schema context.");
         }
         return new IncorrectNestingException(message, args);