Merge changes I412fb3fc,Iccef8d2e
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / TransformerGenerator.xtend
index 975365081ad40c58267b563191e35f96d3ced118..f399f767b4d14e94a70b823d87e8db79d3c44e6f 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.yangtools.sal.binding.generator.impl
 
 import javassist.ClassPool
@@ -64,6 +71,10 @@ import java.util.Collections
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit
 import java.util.Set
 import org.opendaylight.yangtools.sal.binding.generator.util.XtendHelper
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
+import org.opendaylight.yangtools.yang.binding.BindingMapping
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition
+import java.util.Collection
 
 class TransformerGenerator {
 
@@ -103,7 +114,10 @@ class TransformerGenerator {
     var Map<Type, AugmentationSchema> typeToAugmentation = new ConcurrentHashMap();
 
     @Property
-    var GeneratorListener listener;
+    var LazyGeneratedCodecRegistry listener;
+
+    @Property
+    var extension GeneratedClassLoadingStrategy classLoadingStrategy
 
     public static val CLASS_TYPE = Types.typeForClass(Class);
 
@@ -113,6 +127,8 @@ class TransformerGenerator {
 
         BINDING_CODEC = BindingCodec.asCtClass;
         ctQName = QName.asCtClass
+
+        this.classLoadingStrategy = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
     }
 
     def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
@@ -124,6 +140,7 @@ class TransformerGenerator {
             }
             val ref = Types.typeForClass(inputType)
             val node = typeToSchemaNode.get(ref)
+            createMapping(inputType, node, null)
             val typeSpecBuilder = typeToDefinition.get(ref)
             checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
             val typeSpec = typeSpecBuilder.toInstance();
@@ -135,6 +152,7 @@ class TransformerGenerator {
 
     def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
         return withClassLoaderAndLock(inputType.classLoader, lock) [ |
+            createMapping(inputType, node, null)
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
                 listener.onClassProcessed(inputType);
@@ -145,13 +163,10 @@ class TransformerGenerator {
             if (typeSpecBuilder == null) {
                 typeSpecBuilder = pathToType.get(node.path);
             }
-            var schemaNode = typeToSchemaNode.get(ref);
-            if(schemaNode === null) {
-                schemaNode = node;
-            }
+
             checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
             val typeSpec = typeSpecBuilder.toInstance();
-            val newret = generateTransformerFor(inputType, typeSpec, schemaNode);
+            val newret = generateTransformerFor(inputType, typeSpec, node);
             listener.onClassProcessed(inputType);
             return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
         ]
@@ -159,6 +174,7 @@ class TransformerGenerator {
 
     def Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(Class<?> inputType) {
         return withClassLoaderAndLock(inputType.classLoader, lock) [ |
+
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
                 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
@@ -167,6 +183,7 @@ class TransformerGenerator {
             val node = typeToAugmentation.get(ref)
             val typeSpecBuilder = typeToDefinition.get(ref)
             val typeSpec = typeSpecBuilder.toInstance();
+            //mappingForNodes(node.childNodes, typeSpec.allProperties, bindingId)
             val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
             listener.onClassProcessed(inputType);
             return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
@@ -175,6 +192,7 @@ class TransformerGenerator {
 
     def Class<? extends BindingCodec<Object, Object>> caseCodecFor(Class<?> inputType, ChoiceCaseNode node) {
         return withClassLoaderAndLock(inputType.classLoader, lock) [ |
+            createMapping(inputType, node, null)
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
                 return ret as Class<? extends BindingCodec<Object, Object>>;
@@ -190,7 +208,7 @@ class TransformerGenerator {
     def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(Class<?> parentType) {
         return withClassLoaderAndLock(parentType.classLoader, lock) [ |
             val inputName = parentType.name + "Key";
-            val inputType = loadClassWithTCCL(inputName);
+            val inputType = loadClass(inputName);
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
                 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
@@ -204,6 +222,62 @@ class TransformerGenerator {
         ]
     }
 
+    private def void createMapping(Class<?> inputType, SchemaNode node, InstanceIdentifier<?> parentId) {
+        var ClassLoader cl = inputType.classLoader
+        if (cl === null) {
+            cl = Thread.currentThread.contextClassLoader
+        }
+        withClassLoader(cl,
+            [ |
+                if (!(node instanceof DataNodeContainer)) {
+                    return null
+                }
+                var InstanceIdentifier<?> bindingId = listener.getBindingIdentifierByPath(node.path)
+                if (bindingId != null) {
+                    return null
+                }
+                val ref = Types.typeForClass(inputType)
+                var typeSpecBuilder = typeToDefinition.get(ref)
+                if (typeSpecBuilder == null) {
+                    typeSpecBuilder = pathToType.get(node.path);
+                }
+                checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s, $s", inputType.name, node);
+                val typeSpec = typeSpecBuilder.toInstance();
+                var InstanceIdentifier<?> parent
+                if (parentId == null) {
+                    bindingId = InstanceIdentifier.create(inputType as Class)
+                    parent = bindingId
+                    listener.putPathToBindingIdentifier(node.path, bindingId)
+                } else {
+                    parent = listener.putPathToBindingIdentifier(node.path, parentId, inputType)
+                }
+                val Map<String, Type> properties = typeSpec.allProperties
+                if (node instanceof DataNodeContainer) {
+                    mappingForNodes((node as DataNodeContainer).childNodes, properties, parent)
+                } else if (node instanceof ChoiceNode) {
+                    mappingForNodes((node as ChoiceNode).cases, properties, parent)
+                }
+                return null;
+            ])
+    }
+
+    private def void mappingForNodes(Collection<? extends DataSchemaNode> childNodes, Map<String, Type> properties,
+        InstanceIdentifier<?> parent) {
+        for (DataSchemaNode child : childNodes) {
+            val signature = properties.getFor(child)
+            if (signature != null) {
+                val Type childType = signature.value
+                var Class<?> childTypeClass = null;
+                if (child instanceof ListSchemaNode && childType instanceof ParameterizedType) {
+                    childTypeClass = loadClass((childType as ParameterizedType).actualTypeArguments.get(0))
+                } else {
+                    childTypeClass = loadClass(childType)
+                }
+                createMapping(childTypeClass, child, parent)
+            }
+        }
+    }
+
     def getIdentifierDefinition(GeneratedTypeBuilder builder) {
         val inst = builder.toInstance
         val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
@@ -239,24 +313,24 @@ class TransformerGenerator {
     private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
 
         try {
-            return loadClassWithTCCL(cls.codecClassName)
+            return loadClass(cls.codecClassName)
         } catch (ClassNotFoundException e) {
             return null;
         }
     }
 
     private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
-        val cls = loadClassWithTCCL(type.resolvedName + "Key");
+        val cls = loadClass(type.resolvedName + "Key");
         keyTransformerFor(cls, type, node);
     }
 
     private def serializer(Type type, DataSchemaNode node) {
-        val cls = loadClassWithTCCL(type.resolvedName);
+        val cls = loadClass(type.resolvedName);
         transformerFor(cls, node);
     }
 
     private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
-        val cls = loadClassWithTCCL(type.resolvedName);
+        val cls = loadClass(type.resolvedName);
         val transformer = cls.generatedClass;
         if (transformer !== null) {
             return transformer;
@@ -273,7 +347,7 @@ class TransformerGenerator {
     }
 
     private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
-        val cls = loadClassWithTCCL(type.resolvedName);
+        val cls = loadClass(type.resolvedName);
         val transformer = cls.generatedClass;
         if (transformer !== null) {
             return transformer;
@@ -296,7 +370,7 @@ class TransformerGenerator {
                 staticField(it, IDENTITYREF_CODEC, BindingCodec)
                 staticQNameField(node.QName);
                 implementsType(BINDING_CODEC)
-                method(Object, "toDomStatic", QName, Object) [
+                method(Object, "toDomStatic", #[QName, Object]) [
                     modifiers = PUBLIC + FINAL + STATIC
                     bodyChecked = '''
                         {
@@ -318,7 +392,7 @@ class TransformerGenerator {
                         }
                     '''
                 ]
-                method(Object, "fromDomStatic", QName, Object) [
+                method(Object, "fromDomStatic", #[QName, Object]) [
                     modifiers = PUBLIC + FINAL + STATIC
                     bodyChecked = '''
                         {
@@ -352,7 +426,13 @@ class TransformerGenerator {
                 ]
                 method(Object, "deserialize", Object) [
                     bodyChecked = '''
-                        return fromDomStatic(QNAME,$1);
+                        {
+                            «QName.name» _qname = QNAME;
+                            if($1 instanceof java.util.Map.Entry) {
+                                _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
+                            }
+                            return fromDomStatic(_qname,$1);
+                        }
                     '''
                 ]
             ]
@@ -368,7 +448,6 @@ class TransformerGenerator {
     private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
         ChoiceCaseNode node) {
         try {
-
             //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
             val ctCls = createClass(type.codecClassName) [
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
@@ -377,7 +456,7 @@ class TransformerGenerator {
                 staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
                 staticField(it, AUGMENTATION_CODEC, BindingCodec)
                 staticField(it, IDENTITYREF_CODEC, BindingCodec)
-                method(Object, "toDomStatic", QName, Object) [
+                method(Object, "toDomStatic", #[QName, Object]) [
                     modifiers = PUBLIC + FINAL + STATIC
                     bodyChecked = '''
                         {
@@ -401,16 +480,16 @@ class TransformerGenerator {
                         }
                     '''
                 ]
-                method(Object, "fromDomStatic", QName, Object) [
+                method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
                     modifiers = PUBLIC + FINAL + STATIC
-                    bodyChecked = deserializeBody(type, node)
+                    bodyChecked = deserializeBody(type, node, listener.getBindingIdentifierByPath(node.path))
                 ]
-                method(Object, "deserialize", Object) [
+                method(Object, "deserialize", #[Object, InstanceIdentifier]) [
                     bodyChecked = '''
                         {
                             //System.out.println("«type.name»#deserialize: " +$1);
                             java.util.Map.Entry _input = (java.util.Map.Entry) $1;
-                            return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue());
+                            return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue(),$2);
                         }
                     '''
                 ]
@@ -438,7 +517,8 @@ class TransformerGenerator {
                 staticField(it, IDENTITYREF_CODEC, BindingCodec)
                 staticField(it, AUGMENTATION_CODEC, BindingCodec)
                 implementsType(BINDING_CODEC)
-                method(Object, "toDomStatic", QName, Object) [
+
+                method(Object, "toDomStatic", #[QName, Object]) [
                     modifiers = PUBLIC + FINAL + STATIC
                     bodyChecked = serializeBodyFacade(typeSpec, node)
                 ]
@@ -454,13 +534,21 @@ class TransformerGenerator {
                         }
                     '''
                 ]
-                method(Object, "fromDomStatic", QName, Object) [
+
+                method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
                     modifiers = PUBLIC + FINAL + STATIC
-                    bodyChecked = deserializeBody(typeSpec, node)
+                    bodyChecked = deserializeBody(typeSpec, node, listener.getBindingIdentifierByPath(node.path))
                 ]
-                method(Object, "deserialize", Object) [
+
+                method(Object, "deserialize", #[Object, InstanceIdentifier]) [
                     bodyChecked = '''
-                        return fromDomStatic(QNAME,$1);
+                        {
+                            «QName.name» _qname = QNAME;
+                            if($1 instanceof java.util.Map.Entry) {
+                                _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
+                            }
+                            return fromDomStatic(_qname,$1,$2);
+                        }
                     '''
                 ]
             ]
@@ -488,7 +576,8 @@ class TransformerGenerator {
                 staticField(it, AUGMENTATION_CODEC, BindingCodec)
                 staticField(it, IDENTITYREF_CODEC, BindingCodec)
                 implementsType(BINDING_CODEC)
-                method(Object, "toDomStatic", QName, Object) [
+
+                method(Object, "toDomStatic", #[QName, Object]) [
                     modifiers = PUBLIC + FINAL + STATIC
                     bodyChecked = '''
                         {
@@ -518,7 +607,8 @@ class TransformerGenerator {
                         }
                     '''
                 ]
-                method(Object, "fromDomStatic", QName, Object) [
+
+                method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
                     modifiers = PUBLIC + FINAL + STATIC
                     bodyChecked = '''
                         {
@@ -537,15 +627,16 @@ class TransformerGenerator {
                                 _builder.«signature.key.toSetter»(«signature.key»);
                             «ENDFOR»
                             if(_is_empty) {
-                                return null;
+                            return null;
                             }
                             return _builder.build();
                         }
                     '''
                 ]
-                method(Object, "deserialize", Object) [
+
+                method(Object, "deserialize", #[Object, InstanceIdentifier]) [
                     bodyChecked = '''
-                        return fromDomStatic(QNAME,$1);
+                        return fromDomStatic(QNAME,$1,$2);
                     '''
                 ]
             ]
@@ -573,7 +664,7 @@ class TransformerGenerator {
                 staticField(it, COMPOSITE_TO_CASE, Map)
                 //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
                 implementsType(BINDING_CODEC)
-                method(List, "toDomStatic", QName, Object) [
+                method(List, "toDomStatic", #[QName, Object]) [
                     modifiers = PUBLIC + FINAL + STATIC
                     bodyChecked = '''
                         {
@@ -598,19 +689,19 @@ class TransformerGenerator {
                         throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
                     '''
                 ]
-                method(Object, "fromDomStatic", QName, Map) [
+                method(Object, "fromDomStatic", #[QName, Map, InstanceIdentifier]) [
                     modifiers = PUBLIC + FINAL + STATIC
                     bodyChecked = '''
                         {
                             «BINDING_CODEC.name» _codec = («BINDING_CODEC.name») «COMPOSITE_TO_CASE».get($2);
                             if(_codec != null) {
-                                return _codec.deserialize(new «SimpleEntry.name»($1,$2));
+                                return _codec.deserialize(new «SimpleEntry.name»($1,$2),$3);
                             }
                             return null;
                         }
                     '''
                 ]
-                method(Object, "deserialize", Object) [
+                method(Object, "deserialize", #[Object, InstanceIdentifier]) [
                     bodyChecked = '''
                         throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
                     '''
@@ -642,8 +733,8 @@ class TransformerGenerator {
         return ret;
     }
 
-    private def String deserializeBody(GeneratedType type, SchemaNode node) {
-        val ret = deserializeBodyImpl(type, node);
+    private def String deserializeBody(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) {
+        val ret = deserializeBodyImpl(type, node, bindingId);
         return ret;
     }
 
@@ -656,36 +747,35 @@ class TransformerGenerator {
         }
     }
 
-    private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node) '''
+    private def String deserializeBodyWithAugmentations(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) '''
         {
             «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
-
             if($2 == null) {
                 return null;
             }
             java.util.Map _compositeNode = (java.util.Map) $2;
+            //System.out.println(_localQName + " " + _compositeNode);
             «type.builderName» _builder = new «type.builderName»();
+            «deserializeDataNodeContainerBody(type, node, bindingId)»
+            «type.deserializeAugmentations»
             return _builder.build();
         }
     '''
 
-    private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node) '''
+    private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) '''
         {
             «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
+
             if($2 == null) {
-                return null;
+            return null;
             }
             java.util.Map _compositeNode = (java.util.Map) $2;
-            //System.out.println(_localQName + " " + _compositeNode);
             «type.builderName» _builder = new «type.builderName»();
-            «deserializeKey(type, node)»
-            «deserializeDataNodeContainerBody(type, node)»
-            «deserializeAugmentations»
             return _builder.build();
         }
     '''
 
-    private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node) '''
+    private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node, InstanceIdentifier<?> bindingId) '''
         {
             «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
             if($2 == null) {
@@ -694,34 +784,31 @@ class TransformerGenerator {
             java.util.Map _compositeNode = (java.util.Map) $2;
             //System.out.println(_localQName + " " + _compositeNode);
             «type.builderName» _builder = new «type.builderName»();
-            «deserializeDataNodeContainerBody(type, node)»
-            «deserializeAugmentations»
+            «deserializeKey(type, node)»
+            «deserializeDataNodeContainerBody(type, node, bindingId)»
+            «type.deserializeAugmentations»
             return _builder.build();
         }
     '''
 
-    private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node) '''
-        {
-            «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
+    private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node, InstanceIdentifier<?> bindingId) {
+        return deserializeBodyWithAugmentations(type, node, bindingId);
+    }
 
-            if($2 == null) {
-                return null;
-            }
-            java.util.Map _compositeNode = (java.util.Map) $2;
-            //System.out.println(_localQName + " " + _compositeNode);
-            «type.builderName» _builder = new «type.builderName»();
-            «deserializeDataNodeContainerBody(type, node)»
-            «deserializeAugmentations»
-            return _builder.build();
-        }
-    '''
+    private def dispatch String deserializeBodyImpl(GeneratedType type, NotificationDefinition node, InstanceIdentifier<?> bindingId) {
+        return deserializeBodyWithAugmentations(type, node, bindingId);
+    }
+
+    private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node, InstanceIdentifier<?> bindingId) {
+        return deserializeBodyWithAugmentations(type, node, bindingId);
+    }
 
-    private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node) {
-        deserializeNodeContainerBodyImpl(type, type.allProperties, node);
+    private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) {
+        deserializeNodeContainerBodyImpl(type, type.allProperties, node, bindingId);
     }
 
     private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
-        DataNodeContainer node) {
+        DataNodeContainer node, InstanceIdentifier<?> bindingId) {
         val ret = '''
             boolean _is_empty = true;
             «FOR child : node.childNodes»
@@ -735,8 +822,9 @@ class TransformerGenerator {
         return ret;
     }
 
-    def deserializeAugmentations() '''
-        java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode);
+    def deserializeAugmentations(GeneratedType type) '''
+        «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
+        java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode,$3);
         if(_augmentation != null) {
             «Iterator.name» _entries = _augmentation.entrySet().iterator();
             while(_entries.hasNext()) {
@@ -765,7 +853,9 @@ class TransformerGenerator {
                 Object _listItem = _iterator.next();
                 _is_empty = false;
                 ////System.out.println("  item" + _listItem);
-                Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem);
+                «val param = type.actualTypeArguments.get(0)»
+                «InstanceIdentifier.resolvedName» iid = $3.builder().child(«param.resolvedName».class).build();
+                Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem,iid);
                 ////System.out.println("  value" + _value);
                 «propertyName».add(_value);
                 _hasNext = _iterator.hasNext();
@@ -817,12 +907,13 @@ class TransformerGenerator {
         if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
             _is_empty = false;
             java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
-            «propertyName» =  «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»);
+            «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
+            «propertyName» =  «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»,iid);
         }
     '''
 
     private def dispatch CharSequence deserializeProperty(ChoiceNode schema, Type type, String propertyName) '''
-        «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode);
+        «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode,$3);
         if(«propertyName» != null) {
             _is_empty = false;
         }
@@ -864,7 +955,7 @@ class TransformerGenerator {
                             ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
 
                             if($1 == null) {
-                                return null;
+                            return null;
                             }
                             «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
                             ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
@@ -889,7 +980,7 @@ class TransformerGenerator {
                             ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
 
                             if($1 == null) {
-                                return null;
+                            return null;
                             }
                             «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
                             «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
@@ -921,7 +1012,7 @@ class TransformerGenerator {
         try {
             val ctCls = createClass(typeSpec.codecClassName) [
                 val properties = typeSpec.allProperties;
-                val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type | type.QName.getterName];
+                val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type|type.QName.getterName];
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
                 if (inputType.isYangBindingAvailable) {
                     implementsType(BINDING_CODEC)
@@ -932,23 +1023,23 @@ class TransformerGenerator {
                 method(Object, "toDomValue", Object) [
                     modifiers = PUBLIC + FINAL + STATIC
                     val ctSpec = inputType.asCtClass;
-
                     bodyChecked = '''
                         {
                             ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
 
                             if($1 == null) {
-                                return null;
+                            return null;
                             }
                             «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
                             «FOR property : properties.entrySet»
-                                «IF property.key != "getValue"»
-                                    «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
+                            «IF property.key != "getValue"»
+                                «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
                             key»();
-                                    if(«property.key» != null) {
-                                        return «serializeValue(property.value, property.key, getterToTypeDefinition.get(property.key))»;
-                                    }
-                                «ENDIF»
+                                if(«property.key» != null) {
+                                    return «serializeValue(property.value, property.key,
+                            getterToTypeDefinition.get(property.key))»;
+                                }
+                            «ENDIF»
                             «ENDFOR»
 
                             return null;
@@ -969,11 +1060,11 @@ class TransformerGenerator {
                             ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
 
                             if($1 == null) {
-                                return null;
+                            return null;
                             }
                             if($1 instanceof String) {
-                                String _simpleValue = (String) $1;
-                                return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
+                            String _simpleValue = (String) $1;
+                            return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
                             }
                             return null;
                         }
@@ -998,7 +1089,6 @@ class TransformerGenerator {
         }
     }
 
-
     private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
         Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
         try {
@@ -1018,17 +1108,17 @@ class TransformerGenerator {
                             ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
 
                             if($1 == null) {
-                                return null;
+                            return null;
                             }
                             «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
                             «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
                             //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
 
                             «FOR bit : typeDef.bits»
-                                «val getter = bit.getterName()»
-                                if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
-                                    _value.add("«bit.name»");
-                                }
+                            «val getter = bit.getterName()»
+                            if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
+                                _value.add("«bit.name»");
+                            }
                             «ENDFOR»
                             «Set.resolvedName» _domValue =  «Collections.resolvedName».unmodifiableSet(_value);
                             //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
@@ -1052,11 +1142,11 @@ class TransformerGenerator {
                             //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
 
                             if($1 == null) {
-                                return null;
+                            return null;
                             }
                             «Set.resolvedName» _domValue = («Set.resolvedName») $1;
                             «FOR bit : sortedBits»
-                                Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
+                            Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
                             «ENDFOR»
 
                             return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
@@ -1244,6 +1334,12 @@ class TransformerGenerator {
             return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
         } else if (CLASS_TYPE.equals(type)) {
             return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
+        } else if (typeDef!=null && typeDef instanceof EmptyTypeDefinition) {
+            if(domParameter == null) {
+                return ''' Boolean.FALSE '''
+            } else {
+                return ''' Boolean.TRUE '''
+            }
         }
         return '''(«type.resolvedName») «domParameter»'''
 
@@ -1290,38 +1386,32 @@ class TransformerGenerator {
             '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
     }
 
-    private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) '''
+    private def String serializeBodyImpl(GeneratedType type, DataNodeContainer nodeContainer) '''
         {
             «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
             java.util.List _childNodes = new java.util.ArrayList();
             «type.resolvedName» value = («type.resolvedName») $2;
-            «transformDataContainerBody(type, type.allProperties, node)»
+            «transformDataContainerBody(type, type.allProperties, nodeContainer
             «serializeAugmentations»
             return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
         }
     '''
 
-    private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) '''
-        {
-            «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
-            java.util.List _childNodes = new java.util.ArrayList();
-            «type.resolvedName» value = («type.resolvedName») $2;
-            «transformDataContainerBody(type, type.allProperties, node)»
-            «serializeAugmentations»
-            return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
-        }
-    '''
+    private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) {
+        return serializeBodyImpl(type, node);
+    }
 
-    private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) '''
-        {
-        «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
-            java.util.List _childNodes = new java.util.ArrayList();
-            «type.resolvedName» value = («type.resolvedName») $2;
-            «transformDataContainerBody(type, type.allProperties, node)»
-            «serializeAugmentations»
-            return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
-        }
-    '''
+    private def dispatch String serializeBody(GeneratedType type, NotificationDefinition node) {
+        return serializeBodyImpl(type, node);
+    }
+
+    private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) {
+        return serializeBodyImpl(type, node);
+    }
+
+    private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) {
+        return serializeBodyImpl(type, node);
+    }
 
     private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
         {
@@ -1365,15 +1455,15 @@ class TransformerGenerator {
     }
 
     private static def String getBooleanGetterName(DataSchemaNode node) {
-        return "is" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
+        return "is" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
     }
 
     private static def String getGetterName(DataSchemaNode node) {
-        return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
+        return "get" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
     }
 
     private static def String getGetterName(QName node) {
-        return "get" + BindingGeneratorUtil.parseToClassName(node.localName);
+        return "get" + BindingMapping.getPropertyName(node.localName).toFirstUpper;
     }
 
     private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
@@ -1413,7 +1503,19 @@ class TransformerGenerator {
         '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
     }
 
+    private def dispatch serializeValue(Type type, String parameter, EmptyTypeDefinition typeDefinition) {
+        '''(«parameter».booleanValue() ? "" : null)'''
+    }
+
     private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
+        serializeValue(signature,property)
+    }
+
+    private def dispatch serializeValue(Type signature, String property, Void typeDefinition) {
+        serializeValue(signature,property)
+    }
+
+    private def dispatch serializeValue(Type signature, String property) {
         if (INSTANCE_IDENTIFIER == signature) {
             return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
         } else if (CLASS_TYPE.equals(signature)) {
@@ -1520,7 +1622,7 @@ class TransformerGenerator {
     }
 
     def CtClass asCtClass(Type type) {
-        val cls = loadClassWithTCCL(type.fullyQualifiedName)
+        val cls = loadClass(type.fullyQualifiedName)
         return cls.asCtClass;
     }