Rework BindingRuntimeTypes
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / DataContainerCodecPrototype.java
index 2a6abd3d7942472a169cdb8dfbac015303d0f5e2..4ab8c5e161924d9c34c85091d701d50da1786e18 100644 (file)
@@ -7,16 +7,29 @@
  */
 package org.opendaylight.mdsal.binding.dom.codec.impl;
 
+import static com.google.common.base.Verify.verify;
+
 import com.google.common.collect.Iterables;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode.ChildAddressabilitySummary;
 import org.opendaylight.mdsal.binding.dom.codec.impl.NodeCodecContext.CodecContextFactory;
+import org.opendaylight.mdsal.binding.runtime.api.AugmentRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeTypes;
+import org.opendaylight.mdsal.binding.runtime.api.CaseRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.ContainerLikeRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.ListRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.NotificationRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.RuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.RuntimeTypeContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.DataRoot;
 import org.opendaylight.yangtools.yang.binding.Identifiable;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
@@ -26,20 +39,16 @@ import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerLike;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-final class DataContainerCodecPrototype<T extends WithStatus> implements NodeContextSupplier {
+final class DataContainerCodecPrototype<T extends RuntimeTypeContainer> implements NodeContextSupplier {
     private static final Logger LOG = LoggerFactory.getLogger(DataContainerCodecPrototype.class);
 
     private static final VarHandle INSTANCE;
@@ -53,7 +62,7 @@ final class DataContainerCodecPrototype<T extends WithStatus> implements NodeCon
         }
     }
 
-    private final T schema;
+    private final T type;
     private final QNameModule namespace;
     private final CodecContextFactory factory;
     private final Item<?> bindingArg;
@@ -65,16 +74,16 @@ final class DataContainerCodecPrototype<T extends WithStatus> implements NodeCon
     private volatile DataContainerCodecContext<?, T> instance;
 
     @SuppressWarnings("unchecked")
-    private DataContainerCodecPrototype(final Class<?> cls, final PathArgument arg, final T nodeSchema,
+    private DataContainerCodecPrototype(final Class<?> cls, final PathArgument arg, final T type,
             final CodecContextFactory factory) {
-        this(Item.of((Class<? extends DataObject>) cls), arg, nodeSchema, factory);
+        this(Item.of((Class<? extends DataObject>) cls), arg, type, factory);
     }
 
-    private DataContainerCodecPrototype(final Item<?> bindingArg, final PathArgument arg, final T nodeSchema,
+    private DataContainerCodecPrototype(final Item<?> bindingArg, final PathArgument arg, final T type,
             final CodecContextFactory factory) {
         this.bindingArg = bindingArg;
         this.yangArg = arg;
-        this.schema = nodeSchema;
+        this.type = type;
         this.factory = factory;
 
         if (arg instanceof AugmentationIdentifier) {
@@ -84,10 +93,14 @@ final class DataContainerCodecPrototype<T extends WithStatus> implements NodeCon
             this.namespace = arg.getNodeType().getModule();
         }
 
-        this.childAddressabilitySummary = computeChildAddressabilitySummary(nodeSchema);
+        this.childAddressabilitySummary = type instanceof RuntimeType
+            ? computeChildAddressabilitySummary(((RuntimeType) type).statement())
+                // BindingRuntimeTypes, does not matter
+                : ChildAddressabilitySummary.MIXED;
     }
 
-    private static ChildAddressabilitySummary computeChildAddressabilitySummary(final WithStatus nodeSchema) {
+    private static ChildAddressabilitySummary computeChildAddressabilitySummary(final Object nodeSchema) {
+        // FIXME: rework this to work on EffectiveStatements
         if (nodeSchema instanceof DataNodeContainer) {
             boolean haveAddressable = false;
             boolean haveUnaddressable = false;
@@ -160,35 +173,40 @@ final class DataContainerCodecPrototype<T extends WithStatus> implements NodeCon
         return ChildAddressabilitySummary.UNADDRESSABLE;
     }
 
-    static DataContainerCodecPrototype<EffectiveModelContext> rootPrototype(final CodecContextFactory factory) {
-        final EffectiveModelContext schema = factory.getRuntimeContext().getEffectiveModelContext();
-        final NodeIdentifier arg = NodeIdentifier.create(SchemaContext.NAME);
-        return new DataContainerCodecPrototype<>(DataRoot.class, arg, schema, factory);
+    static DataContainerCodecPrototype<BindingRuntimeTypes> rootPrototype(final CodecContextFactory factory) {
+        return new DataContainerCodecPrototype<>(DataRoot.class, NodeIdentifier.create(SchemaContext.NAME),
+            factory.getRuntimeContext().getTypes(), factory);
     }
 
-    static <T extends DataSchemaNode> DataContainerCodecPrototype<T> from(final Class<?> cls, final T schema,
+    static <T extends CompositeRuntimeType> DataContainerCodecPrototype<T> from(final Class<?> cls, final T type,
             final CodecContextFactory factory) {
-        return new DataContainerCodecPrototype<>(cls, NodeIdentifier.create(schema.getQName()), schema, factory);
+        return new DataContainerCodecPrototype<>(cls, createIdentifier(type), type, factory);
     }
 
-    static <T extends DataSchemaNode> DataContainerCodecPrototype<T> from(final Item<?> bindingArg, final T schema,
+    static <T extends CompositeRuntimeType> DataContainerCodecPrototype<T> from(final Item<?> bindingArg, final T type,
             final CodecContextFactory factory) {
-        return new DataContainerCodecPrototype<>(bindingArg, NodeIdentifier.create(schema.getQName()), schema, factory);
+        return new DataContainerCodecPrototype<>(bindingArg, createIdentifier(type), type, factory);
+    }
+
+    static DataContainerCodecPrototype<AugmentRuntimeType> from(final Class<?> augClass,
+            final AugmentationIdentifier arg, final AugmentRuntimeType schema, final CodecContextFactory factory) {
+        return new DataContainerCodecPrototype<>(augClass, arg, schema, factory);
     }
 
-    static DataContainerCodecPrototype<AugmentationSchemaNode> from(final Class<?> augClass,
-            final AugmentationIdentifier arg, final AugmentationSchemaNode schema, final CodecContextFactory factory) {
+    static DataContainerCodecPrototype<NotificationRuntimeType> from(final Class<?> augClass,
+            final NotificationRuntimeType schema, final CodecContextFactory factory) {
+        final PathArgument arg = NodeIdentifier.create(schema.statement().argument());
         return new DataContainerCodecPrototype<>(augClass, arg, schema, factory);
     }
 
-    static DataContainerCodecPrototype<NotificationDefinition> from(final Class<?> augClass,
-            final NotificationDefinition schema, final CodecContextFactory factory) {
-        final PathArgument arg = NodeIdentifier.create(schema.getQName());
-        return new DataContainerCodecPrototype<>(augClass,arg, schema, factory);
+    private static @NonNull NodeIdentifier createIdentifier(final CompositeRuntimeType type) {
+        final Object arg = type.statement().argument();
+        verify(arg instanceof QName, "Unexpected type %s argument %s", type, arg);
+        return NodeIdentifier.create((QName) arg);
     }
 
-    T getSchema() {
-        return schema;
+    @NonNull T getType() {
+        return type;
     }
 
     ChildAddressabilitySummary getChildAddressabilitySummary() {
@@ -231,24 +249,19 @@ final class DataContainerCodecPrototype<T extends WithStatus> implements NodeCon
     // This method must allow concurrent loading, i.e. nothing in it may have effects outside of the loaded object
     private @NonNull DataContainerCodecContext<?, T> createInstance() {
         // FIXME: make protected abstract
-        if (schema instanceof ContainerLike) {
+        if (type instanceof ContainerLikeRuntimeType) {
             return new ContainerNodeCodecContext(this);
-        } else if (schema instanceof ListSchemaNode) {
+        } else if (type instanceof ListRuntimeType) {
             return Identifiable.class.isAssignableFrom(getBindingClass())
-                    ? KeyedListNodeCodecContext.create((DataContainerCodecPrototype<ListSchemaNode>) this)
+                    ? KeyedListNodeCodecContext.create((DataContainerCodecPrototype<ListRuntimeType>) this)
                             : new ListNodeCodecContext(this);
-        } else if (schema instanceof ChoiceSchemaNode) {
+        } else if (type instanceof ChoiceRuntimeType) {
             return new ChoiceNodeCodecContext(this);
-        } else if (schema instanceof AugmentationSchemaNode) {
+        } else if (type instanceof AugmentRuntimeType) {
             return new AugmentationNodeContext(this);
-        } else if (schema instanceof CaseSchemaNode) {
+        } else if (type instanceof CaseRuntimeType) {
             return new CaseNodeCodecContext(this);
         }
-        throw new IllegalArgumentException("Unsupported type " + getBindingClass() + " " + schema);
-    }
-
-    // FIXME: eliminate with above createInstance() item
-    boolean isChoice() {
-        return schema instanceof ChoiceSchemaNode;
+        throw new IllegalArgumentException("Unsupported type " + getBindingClass() + " " + type);
     }
 }