Bug 3067: Improved error reporting in Binding Data Codec
[yangtools.git] / code-generator / binding-data-codec / src / main / java / org / opendaylight / yangtools / binding / data / codec / impl / DataObjectCodecContext.java
index 6066064c8076daf4b482c8633f10b8abecb52cd2..0ca1d2b8504d3183bb01783312eb1ea4717dcc23 100644 (file)
@@ -31,6 +31,7 @@ import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
 import org.opendaylight.yangtools.yang.binding.Augmentable;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.AugmentationHolder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
@@ -116,7 +117,7 @@ abstract class DataObjectCodecContext<D extends DataObject,T extends DataNodeCon
         byBindingArgClassBuilder.putAll(byStreamClass);
         this.byBindingArgClass = ImmutableMap.copyOf(byBindingArgClassBuilder);
 
-        final Class<?> proxyClass = Proxy.getProxyClass(getBindingClass().getClassLoader(),  new Class[] { getBindingClass() });
+        final Class<?> proxyClass = Proxy.getProxyClass(getBindingClass().getClassLoader(),  new Class[] { getBindingClass(), AugmentationHolder.class });
         try {
             proxyConstructor = LOOKUP.findConstructor(proxyClass, CONSTRUCTOR_TYPE).asType(DATAOBJECT_TYPE);
         } catch (NoSuchMethodException | IllegalAccessException e) {
@@ -153,15 +154,14 @@ abstract class DataObjectCodecContext<D extends DataObject,T extends DataNodeCon
                 }
             }
         }
-        Preconditions.checkArgument(childProto != null, " Child %s is not valid child.",childClass);
-        return (DataContainerCodecContext<DV, ?>) childProto.get();
+        return (DataContainerCodecContext<DV, ?>) childNonNull(childProto, childClass, " Child %s is not valid child.").get();
     }
 
 
     @SuppressWarnings("unchecked")
     @Override
     public <DV extends DataObject> Optional<DataContainerCodecContext<DV, ?>> possibleStreamChild(
-            Class<DV> childClass) {
+            final Class<DV> childClass) {
         final DataContainerCodecPrototype<?> childProto = byStreamClass.get(childClass);
         if(childProto != null) {
             return Optional.<DataContainerCodecContext<DV,?>>of((DataContainerCodecContext<DV,?>) childProto.get());
@@ -175,23 +175,17 @@ abstract class DataObjectCodecContext<D extends DataObject,T extends DataNodeCon
 
         final Class<? extends DataObject> argType = arg.getType();
         final DataContainerCodecPrototype<?> ctxProto = byBindingArgClass.get(argType);
-        if(ctxProto != null) {
-            final DataContainerCodecContext<?,?> context = ctxProto.get();
-            if(context instanceof ChoiceNodeCodecContext) {
-                final ChoiceNodeCodecContext<?> choice = (ChoiceNodeCodecContext<?>) context;
-                final DataContainerCodecContext<?,?> caze = choice.getCazeByChildClass(arg.getType());
-                if(caze != null) {
-                    choice.addYangPathArgument(arg, builder);
-                    caze.addYangPathArgument(arg, builder);
-                    return caze.bindingPathArgumentChild(arg, builder);
-                }
-                return null;
-            }
-            context.addYangPathArgument(arg, builder);
-            return context;
+        final DataContainerCodecContext<?, ?> context =
+                childNonNull(ctxProto, argType, "Class %s is not valid child of %s", argType, getBindingClass()).get();
+        if (context instanceof ChoiceNodeCodecContext) {
+            final ChoiceNodeCodecContext<?> choice = (ChoiceNodeCodecContext<?>) context;
+            final DataContainerCodecContext<?, ?> caze = choice.getCazeByChildClass(arg.getType());
+            choice.addYangPathArgument(arg, builder);
+            caze.addYangPathArgument(arg, builder);
+            return caze.bindingPathArgumentChild(arg, builder);
         }
-        // Argument is not valid child.
-        return null;
+        context.addYangPathArgument(arg, builder);
+        return context;
     }
 
     @SuppressWarnings("unchecked")
@@ -201,14 +195,13 @@ abstract class DataObjectCodecContext<D extends DataObject,T extends DataNodeCon
             arg = new NodeIdentifier(arg.getNodeType());
         }
         final NodeContextSupplier childSupplier = byYang.get(arg);
-        Preconditions.checkArgument(childSupplier != null, "Argument %s is not valid child of %s", arg, schema());
+        childNonNull(childSupplier != null, arg, "Argument %s is not valid child of %s", arg, schema());
         return (NodeCodecContext<D>) childSupplier.get();
     }
 
     protected final LeafNodeCodecContext<?> getLeafChild(final String name) {
         final LeafNodeCodecContext<?> value = leafChild.get(name);
-        Preconditions.checkArgument(value != null, "Leaf %s is not valid for %s", name, getBindingClass());
-        return value;
+        return IncorrectNestingException.checkNonNull(value, "Leaf %s is not valid for %s", name, getBindingClass());
     }
 
     private DataContainerCodecPrototype<?> loadChildPrototype(final Class<?> childClass) {
@@ -246,8 +239,9 @@ abstract class DataObjectCodecContext<D extends DataObject,T extends DataNodeCon
                 childSchema = null;
             }
         }
-        Preconditions.checkArgument(childSchema != null, "Node %s does not have child named %s", schema(), childClass);
-        return DataContainerCodecPrototype.from(childClass, childSchema, factory());
+        final DataSchemaNode nonNullChild =
+                childNonNull(childSchema, childClass, "Node %s does not have child named %s", schema(), childClass);
+        return DataContainerCodecPrototype.from(childClass, nonNullChild, factory());
     }
 
     private DataContainerCodecPrototype<?> getAugmentationPrototype(final Type value) {
@@ -309,4 +303,15 @@ abstract class DataObjectCodecContext<D extends DataObject,T extends DataNodeCon
         return byMethod.keySet();
     }
 
+    @Override
+    public InstanceIdentifier.PathArgument deserializePathArgument(final YangInstanceIdentifier.PathArgument arg) {
+        Preconditions.checkArgument(getDomPathArgument().equals(arg));
+        return bindingArg();
+    }
+
+    @Override
+    public YangInstanceIdentifier.PathArgument serializePathArgument(final InstanceIdentifier.PathArgument arg) {
+        Preconditions.checkArgument(bindingArg().equals(arg));
+        return getDomPathArgument();
+    }
 }