Merge "BUG-990: fixed deserialization of enums."
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / TransformerGenerator.xtend
index a7c3772302fe2a8183bcb090bc02d520224bfcfe..81f39e4e5de9c877c2badba835b02507f2fceac8 100644 (file)
  */
 package org.opendaylight.yangtools.sal.binding.generator.impl
 
+import com.google.common.base.Joiner
+import java.io.File
+import java.security.ProtectionDomain
+import java.util.AbstractMap.SimpleEntry
+import java.util.Collection
+import java.util.Collections
+import java.util.HashMap
+import java.util.HashSet
+import java.util.Iterator
+import java.util.List
+import java.util.Map
+import java.util.Map.Entry
+import java.util.Set
+import java.util.TreeSet
+import javassist.CannotCompileException
 import javassist.ClassPool
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
-import org.opendaylight.yangtools.yang.model.api.SchemaNode
-import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils
 import javassist.CtClass
-import java.util.Map
-import org.opendaylight.yangtools.yang.common.QName
 import javassist.CtField
-import static javassist.Modifier.*
-import static org.opendaylight.yangtools.sal.binding.generator.impl.CodecMapping.*
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
-import org.opendaylight.yangtools.sal.binding.model.api.Type
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
-import org.opendaylight.yangtools.binding.generator.util.Types
-import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
-import java.util.HashMap
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import javassist.CtMethod
 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
-import java.util.List
-import java.util.TreeSet
-import com.google.common.base.Joiner
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
-import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
-import static org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils.*;
-import org.opendaylight.yangtools.yang.binding.BindingDeserializer
-import org.opendaylight.yangtools.yang.binding.BindingCodec
-import org.slf4j.LoggerFactory
+import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
+import org.opendaylight.yangtools.binding.generator.util.Types
+import org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils
 import org.opendaylight.yangtools.sal.binding.generator.util.CodeGenerationException
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode
-import java.security.ProtectionDomain
-import java.io.File
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.sal.binding.generator.util.XtendHelper
+import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
-import java.util.Map.Entry
-import java.util.AbstractMap.SimpleEntry
-import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
+import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
+import org.opendaylight.yangtools.sal.binding.model.api.Type
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
 import org.opendaylight.yangtools.yang.binding.Augmentation
-import java.util.Iterator
+import org.opendaylight.yangtools.yang.binding.BindingCodec
+import org.opendaylight.yangtools.yang.binding.BindingDeserializer
+import org.opendaylight.yangtools.yang.binding.BindingMapping
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.common.QName
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
-import java.util.concurrent.ConcurrentHashMap
-import static extension org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils.*;
-import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
-import org.opendaylight.yangtools.yang.model.util.ExtendedType
-import org.opendaylight.yangtools.yang.model.util.EnumerationType
-import static com.google.common.base.Preconditions.*
-import org.opendaylight.yangtools.yang.model.api.SchemaPath
-import javassist.CtMethod
-import javassist.CannotCompileException
-import java.util.concurrent.locks.Lock
-import java.util.concurrent.Callable
-import org.opendaylight.yangtools.sal.binding.generator.util.ClassLoaderUtils
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode
+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.LeafListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
+import org.opendaylight.yangtools.yang.model.api.SchemaNode
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
-import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
-import java.util.HashSet
-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
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition
+import org.opendaylight.yangtools.yang.model.util.EnumerationType
+import org.opendaylight.yangtools.yang.model.util.ExtendedType
+import org.slf4j.LoggerFactory
+
+import static com.google.common.base.Preconditions.*
+import static javassist.Modifier.*
+import static org.opendaylight.yangtools.sal.binding.generator.impl.CodecMapping.*
 
-class TransformerGenerator {
+import static extension org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils.*
 
-    private static val log = LoggerFactory.getLogger(TransformerGenerator)
+class TransformerGenerator extends AbstractTransformerGenerator {
+    private static val LOG = LoggerFactory.getLogger(TransformerGenerator)
 
     public static val STRING = Types.typeForClass(String);
     public static val BOOLEAN = Types.typeForClass(Boolean);
     public static val INTEGER = Types.typeForClass(Integer);
-    public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier)
-
+    public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier);
     //public static val DECIMAL = Types.typeForClass(Decimal);
     public static val LONG = Types.typeForClass(Long);
-
-    val extension JavassistUtils utils;
-
-    CtClass BINDING_CODEC
-
-    CtClass ctQName
+    public static val CLASS_TYPE = Types.typeForClass(Class);
 
     @Property
     var File classFileCapturePath;
 
-    @Property
-    var Map<Type, Type> typeDefinitions = new ConcurrentHashMap();
-
-    @Property
-    var Map<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
-
-    @Property
-    var Map<SchemaPath, GeneratedTypeBuilder> pathToType = new ConcurrentHashMap();
-
-    @Property
-    var Map<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
-
-    @Property
-    var Map<Type, AugmentationSchema> typeToAugmentation = new ConcurrentHashMap();
-
-    @Property
-    var LazyGeneratedCodecRegistry listener;
-
-    @Property
-    var extension GeneratedClassLoadingStrategy classLoadingStrategy
-
-    public static val CLASS_TYPE = Types.typeForClass(Class);
+    val CtClass BINDING_CODEC
+    val CtClass ctQName
 
-    public new(ClassPool pool) {
-        utils = JavassistUtils.forClassPool(pool)
+    public new(TypeResolver typeResolver, ClassPool pool) {
+        super(typeResolver, pool)
 
         BINDING_CODEC = BindingCodec.asCtClass;
         ctQName = QName.asCtClass
-
-        this.classLoadingStrategy = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
     }
 
-    def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
-        return withClassLoaderAndLock(inputType.classLoader, lock) [ |
+    override transformerForImpl(Class inputType) {
+        return runOnClassLoader(inputType.classLoader) [ |
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
                 listener.onClassProcessed(inputType);
                 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
             }
             val ref = Types.typeForClass(inputType)
-            val node = typeToSchemaNode.get(ref)
+            val node = getSchemaNode(ref)
             createMapping(inputType, node, null)
-            val typeSpecBuilder = typeToDefinition.get(ref)
+            val typeSpecBuilder = getDefinition(ref)
             checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
             val typeSpec = typeSpecBuilder.toInstance();
             val newret = generateTransformerFor(inputType, typeSpec, node);
@@ -149,7 +116,7 @@ class TransformerGenerator {
     }
 
     def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
-        return withClassLoaderAndLock(inputType.classLoader, lock) [ |
+        return runOnClassLoader(inputType.classLoader) [ |
             createMapping(inputType, node, null)
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
@@ -157,9 +124,9 @@ class TransformerGenerator {
                 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
             }
             val ref = Types.typeForClass(inputType)
-            var typeSpecBuilder = typeToDefinition.get(ref)
+            var typeSpecBuilder = getDefinition(ref)
             if (typeSpecBuilder == null) {
-                typeSpecBuilder = pathToType.get(node.path);
+                typeSpecBuilder = getTypeBuilder(node.path);
             }
 
             checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
@@ -170,16 +137,16 @@ class TransformerGenerator {
         ]
     }
 
-    def Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(Class<?> inputType) {
-        return withClassLoaderAndLock(inputType.classLoader, lock) [ |
+    override augmentationTransformerForImpl(Class inputType) {
+        return runOnClassLoader(inputType.classLoader) [ |
 
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
                 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
             }
             val ref = Types.typeForClass(inputType)
-            val node = typeToAugmentation.get(ref)
-            val typeSpecBuilder = typeToDefinition.get(ref)
+            val node = getAugmentation(ref)
+            val typeSpecBuilder = getDefinition(ref)
             val typeSpec = typeSpecBuilder.toInstance();
             //mappingForNodes(node.childNodes, typeSpec.allProperties, bindingId)
             val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
@@ -188,23 +155,23 @@ class TransformerGenerator {
         ]
     }
 
-    def Class<? extends BindingCodec<Object, Object>> caseCodecFor(Class<?> inputType, ChoiceCaseNode node) {
-        return withClassLoaderAndLock(inputType.classLoader, lock) [ |
+    override caseCodecForImpl(Class inputType, ChoiceCaseNode node) {
+        return runOnClassLoader(inputType.classLoader) [ |
             createMapping(inputType, node, null)
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
                 return ret as Class<? extends BindingCodec<Object, Object>>;
             }
             val ref = Types.typeForClass(inputType)
-            val typeSpecBuilder = typeToDefinition.get(ref)
+            val typeSpecBuilder = getDefinition(ref)
             val typeSpec = typeSpecBuilder.toInstance();
             val newret = generateCaseCodec(inputType, typeSpec, node);
             return newret as Class<? extends BindingCodec<Object, Object>>;
         ]
     }
 
-    def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(Class<?> parentType) {
-        return withClassLoaderAndLock(parentType.classLoader, lock) [ |
+    override keyTransformerForIdentifiableImpl(Class parentType) {
+        return runOnClassLoader(parentType.classLoader) [ |
             val inputName = parentType.name + "Key";
             val inputType = loadClass(inputName);
             val ret = getGeneratedClass(inputType)
@@ -212,8 +179,8 @@ class TransformerGenerator {
                 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
             }
             val ref = Types.typeForClass(parentType)
-            val node = typeToSchemaNode.get(ref) as ListSchemaNode
-            val typeSpecBuilder = typeToDefinition.get(ref)
+            val node = getSchemaNode(ref) as ListSchemaNode
+            val typeSpecBuilder = getDefinition(ref)
             val typeSpec = typeSpecBuilder.identifierDefinition;
             val newret = generateKeyTransformerFor(inputType, typeSpec, node);
             return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
@@ -225,29 +192,29 @@ class TransformerGenerator {
         if (cl === null) {
             cl = Thread.currentThread.contextClassLoader
         }
-        withClassLoader(cl,
+        ClassLoaderUtils.withClassLoader(cl,
             [ |
                 if (!(node instanceof DataNodeContainer)) {
                     return null
                 }
-                var InstanceIdentifier<?> bindingId = listener.getBindingIdentifierByPath(node.path)
+                var InstanceIdentifier<?> bindingId = getBindingIdentifierByPath(node.path)
                 if (bindingId != null) {
                     return null
                 }
                 val ref = Types.typeForClass(inputType)
-                var typeSpecBuilder = typeToDefinition.get(ref)
+                var typeSpecBuilder = getDefinition(ref)
                 if (typeSpecBuilder == null) {
-                    typeSpecBuilder = pathToType.get(node.path);
+                    typeSpecBuilder = getTypeBuilder(node.path);
                 }
-                checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s, $s", inputType.name, node);
+                checkState(typeSpecBuilder !== null, "Could not find type definition 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)
+                    putPathToBindingIdentifier(node.path, bindingId)
                 } else {
-                    parent = listener.putPathToBindingIdentifier(node.path, parentId, inputType)
+                    parent = putPathToBindingIdentifier(node.path, parentId, inputType)
                 }
                 val Map<String, Type> properties = typeSpec.allProperties
                 if (node instanceof DataNodeContainer) {
@@ -282,15 +249,15 @@ class TransformerGenerator {
         return keyMethod.returnType as GeneratedTransferObject
     }
 
-    def Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(Class<?> inputType) {
-        return withClassLoaderAndLock(inputType.classLoader, lock) [ |
+    override keyTransformerForIdentifierImpl(Class inputType) {
+        return runOnClassLoader(inputType.classLoader) [ |
             val ret = getGeneratedClass(inputType)
             if (ret !== null) {
                 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
             }
             val ref = Types.typeForClass(inputType)
-            val node = typeToSchemaNode.get(ref) as ListSchemaNode
-            val typeSpecBuilder = typeToDefinition.get(ref)
+            val node = getSchemaNode(ref) as ListSchemaNode
+            val typeSpecBuilder = getDefinition(ref)
             val typeSpec = typeSpecBuilder.toInstance();
             val newret = generateKeyTransformerFor(inputType, typeSpec, node);
             return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
@@ -298,7 +265,7 @@ class TransformerGenerator {
     }
 
     private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
-        return withClassLoaderAndLock(inputType.classLoader, lock) [ |
+        return runOnClassLoader(inputType.classLoader) [ |
             val transformer = getGeneratedClass(inputType)
             if (transformer != null) {
                 return transformer;
@@ -338,7 +305,7 @@ class TransformerGenerator {
             baseType = baseType.baseType;
         }
         val finalType = baseType;
-        return withClassLoaderAndLock(cls.classLoader, lock) [ |
+        return runOnClassLoader(cls.classLoader) [ |
             val valueTransformer = generateValueTransformer(cls, type, finalType);
             return valueTransformer;
         ]
@@ -351,8 +318,8 @@ class TransformerGenerator {
             return transformer;
         }
 
-        return withClassLoaderAndLock(cls.classLoader, lock) [ |
-            val valueTransformer = generateValueTransformer(cls, type);
+        return runOnClassLoader(cls.classLoader) [ |
+            val valueTransformer = generateValueTransformer(cls, type, typeDefinition);
             return valueTransformer;
         ]
     }
@@ -435,7 +402,7 @@ class TransformerGenerator {
                 ]
             ]
             val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
-            log.debug("DOM Codec for {} was generated {}", inputType, ret)
+            LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
             return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
         } catch (Exception e) {
             processException(inputType, e);
@@ -480,7 +447,7 @@ class TransformerGenerator {
                 ]
                 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
                     modifiers = PUBLIC + FINAL + STATIC
-                    bodyChecked = deserializeBody(type, node, listener.getBindingIdentifierByPath(node.path))
+                    bodyChecked = deserializeBody(type, node, getBindingIdentifierByPath(node.path))
                 ]
                 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
                     bodyChecked = '''
@@ -495,7 +462,7 @@ class TransformerGenerator {
 
             val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)  as Class<? extends BindingCodec<Object, Object>>
             listener?.onDataContainerCodecCreated(inputType, ret);
-            log.debug("DOM Codec for {} was generated {}", inputType, ret)
+            LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
             return ret;
         } catch (Exception e) {
             processException(inputType, e);
@@ -535,7 +502,7 @@ class TransformerGenerator {
 
                 method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
                     modifiers = PUBLIC + FINAL + STATIC
-                    bodyChecked = deserializeBody(typeSpec, node, listener.getBindingIdentifierByPath(node.path))
+                    bodyChecked = deserializeBody(typeSpec, node, getBindingIdentifierByPath(node.path))
                 ]
 
                 method(Object, "deserialize", #[Object, InstanceIdentifier]) [
@@ -553,7 +520,7 @@ class TransformerGenerator {
 
             val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
             listener?.onDataContainerCodecCreated(inputType, ret);
-            log.debug("DOM Codec for {} was generated {}", inputType, ret)
+            LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
             return ret;
         } catch (Exception e) {
             processException(inputType, e);
@@ -709,7 +676,7 @@ class TransformerGenerator {
             val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
             val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
             listener?.onChoiceCodecCreated(inputType, ret, node);
-            log.debug("DOM Codec for {} was generated {}", inputType, ret)
+            LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
             return ret;
         } catch (Exception e) {
             processException(inputType, e);
@@ -926,6 +893,21 @@ class TransformerGenerator {
         («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
     '''
 
+    private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
+        if (INSTANCE_IDENTIFIER.equals(type)) {
+            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»'''
+    }
+
     private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
         Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
         try {
@@ -995,10 +977,10 @@ class TransformerGenerator {
             ]
 
             val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
-            log.debug("DOM Codec for {} was generated {}", inputType, ret)
+            LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
             return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
         } catch (Exception e) {
-            log.error("Cannot compile DOM Codec for {}", inputType, e);
+            LOG.error("Cannot compile DOM Codec for {}", inputType, e);
             val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
             exception.addSuppressed(e);
             throw exception;
@@ -1077,10 +1059,10 @@ class TransformerGenerator {
             ]
 
             val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
-            log.debug("DOM Codec for {} was generated {}", inputType, ret)
+            LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
             return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
         } catch (Exception e) {
-            log.error("Cannot compile DOM Codec for {}", inputType, e);
+            LOG.error("Cannot compile DOM Codec for {}", inputType, e);
             val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
             exception.addSuppressed(e);
             throw exception;
@@ -1160,10 +1142,10 @@ class TransformerGenerator {
             ]
 
             val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
-            log.debug("DOM Codec for {} was generated {}", inputType, ret)
+            LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
             return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
         } catch (Exception e) {
-            log.error("Cannot compile DOM Codec for {}", inputType, e);
+            LOG.error("Cannot compile DOM Codec for {}", inputType, e);
             val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
             exception.addSuppressed(e);
             throw exception;
@@ -1190,7 +1172,7 @@ class TransformerGenerator {
     }
 
     private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
-        log.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
+        LOG.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
         return createClass(typeSpec.codecClassName) [
             if (object.isYangBindingAvailable) {
                 implementsType(BINDING_CODEC)
@@ -1241,12 +1223,17 @@ class TransformerGenerator {
         return null;
     }
 
-    private def Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec) {
-        try {
+    private def Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec, TypeDefinition<?> type) {
+        var EnumerationType enumSchemaType
+        if (type instanceof EnumerationType) {
+            enumSchemaType = type as EnumerationType
+        } else {
             val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
-            val schema = typeToSchemaNode.get(typeRef) as ExtendedType;
-            val enumSchema = schema.baseType as EnumerationType;
-
+            val schema = getSchemaNode(typeRef) as ExtendedType;
+            enumSchemaType = schema.baseType as EnumerationType;
+        }
+        val enumSchema = enumSchemaType;
+        try {
             //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
             val ctCls = createClass(typeSpec.codecClassName) [
                 //staticField(Map,"AUGMENTATION_SERIALIZERS");
@@ -1259,7 +1246,7 @@ class TransformerGenerator {
                             }
                             «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
                             «FOR en : enumSchema.values»
-                            if(«typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)».equals(_value)) {
+                            if(«typeSpec.resolvedName».«BindingMapping.getClassName(en.name)».equals(_value)) {
                                 return "«en.name»";
                             }
                             «ENDFOR»
@@ -1282,7 +1269,7 @@ class TransformerGenerator {
                             String _value = (String) $1;
                             «FOR en : enumSchema.values»
                                 if("«en.name»".equals(_value)) {
-                                    return «typeSpec.resolvedName».«BindingGeneratorUtil.parseToClassName(en.name)»;
+                                    return «typeSpec.resolvedName».«BindingMapping.getClassName(en.name)»;
                                 }
                             «ENDFOR»
                             return null;
@@ -1297,12 +1284,12 @@ class TransformerGenerator {
             ]
 
             val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
-            log.debug("DOM Codec for {} was generated {}", inputType, ret)
+            LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
             return ret;
         } catch (CodeGenerationException e) {
             throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
         } catch (Exception e) {
-            log.error("Cannot compile DOM Codec for {}", inputType, e);
+            LOG.error("Cannot compile DOM Codec for {}", inputType, e);
             val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
             exception.addSuppressed(e);
             throw exception;
@@ -1327,22 +1314,6 @@ class TransformerGenerator {
 
     }
 
-    private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
-        if (INSTANCE_IDENTIFIER.equals(type)) {
-            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»'''
-
-    }
-
     /**
      * Default catch all
      *
@@ -1356,7 +1327,7 @@ class TransformerGenerator {
         _deserializeProperty(container, type.toInstance, propertyName)
     }
 
-    public static def toSetter(String it) {
+    static def toSetter(String it) {
 
         if (startsWith("is")) {
             return "set" + substring(2);
@@ -1433,14 +1404,14 @@ class TransformerGenerator {
         return ret;
     }
 
-    private def serializeAugmentations() '''
+    private static def serializeAugmentations() '''
         java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
         if(_augmentations != null) {
             _childNodes.addAll(_augmentations);
         }
     '''
 
-    def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
+    private static def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
         var sig = map.get(node.getterName);
         if (sig != null) {
             return new SimpleEntry(node.getterName, sig);
@@ -1625,12 +1596,12 @@ class TransformerGenerator {
     }
 
     private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
-        log.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
+        LOG.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
         throw e;
     }
 
     private def dispatch processException(Class<?> inputType, Exception e) {
-        log.error("Cannot compile DOM Codec for {}", inputType, e);
+        LOG.error("Cannot compile DOM Codec for {}", inputType, e);
         val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
         throw exception;
     }
@@ -1639,17 +1610,11 @@ class TransformerGenerator {
         try {
             method.setBody(body);
         } catch (CannotCompileException e) {
-            log.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
+            LOG.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
                 method.signature, e.message, body)
             throw e;
         }
     }
-
-    private def <V> V withClassLoaderAndLock(ClassLoader cls, Lock lock, Callable<V> function) throws Exception {
-        appendClassLoaderIfMissing(cls);
-        ClassLoaderUtils.withClassLoaderAndLock(cls, lock, function);
-    }
-
 }
 
 @Data