Binding v2 - Use YangTextSnippet for generation
[mdsal.git] / binding2 / mdsal-binding2-generator-impl / src / main / java / org / opendaylight / mdsal / binding / javav2 / generator / impl / GenHelperUtil.java
old mode 100644 (file)
new mode 100755 (executable)
index 73ea200..dc28d50
@@ -12,7 +12,6 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.addTOToTypeBuilder;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.annotateDeprecatedIfNecessary;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.constructGetter;
-import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createDescription;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createReturnTypeForUnion;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.getAugmentIdentifier;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.isInnerType;
@@ -23,21 +22,22 @@ import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenU
 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.computeDefaultSUID;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.encodeAngleBrackets;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
+import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.IDENTIFIABLE;
+import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.IDENTIFIER;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.NOTIFICATION;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.parameterizedTypeFor;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.wildcardTypeFor;
-import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
+import javax.annotation.Nullable;
 import org.opendaylight.mdsal.binding.javav2.generator.context.ModuleContext;
 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
@@ -45,9 +45,9 @@ import org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes;
 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer;
 import org.opendaylight.mdsal.binding.javav2.generator.util.ReferencedTypeImpl;
+import org.opendaylight.mdsal.binding.javav2.generator.util.TypeComments;
 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
-import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
 import org.opendaylight.mdsal.binding.javav2.generator.yang.types.GroupingDefinitionDependencySort;
 import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl;
@@ -56,6 +56,7 @@ import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedType;
 import org.opendaylight.mdsal.binding.javav2.model.api.ParameterizedType;
 import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
+import org.opendaylight.mdsal.binding.javav2.model.api.YangSourceDefinition;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder;
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
@@ -68,8 +69,8 @@ import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+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.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
@@ -124,9 +125,14 @@ final class GenHelperUtil {
                 genCtx.get(module));
         addImplementedInterfaceFromUses(module, moduleDataTypeBuilder, genCtx);
         moduleDataTypeBuilder.addImplementsType(BindingTypes.TREE_ROOT);
-        moduleDataTypeBuilder.addComment(module.getDescription());
-        moduleDataTypeBuilder.setDescription(createDescription(module, verboseClassComments));
-        moduleDataTypeBuilder.setReference(module.getReference());
+
+        if (verboseClassComments) {
+            YangSourceDefinition.of(module).ifPresent(moduleDataTypeBuilder::setYangSourceDefinition);
+            TypeComments.description(module).ifPresent(moduleDataTypeBuilder::addComment);
+            module.getDescription().ifPresent(moduleDataTypeBuilder::setDescription);
+            module.getReference().ifPresent(moduleDataTypeBuilder::setReference);
+        }
+
         return moduleDataTypeBuilder;
     }
 
@@ -153,8 +159,12 @@ final class GenHelperUtil {
         final String moduleName = new StringBuilder(module.getName()).append('_').append(postfix).toString();
 
         final GeneratedTypeBuilderImpl moduleBuilder = new GeneratedTypeBuilderImpl(packageName, moduleName, context);
-        moduleBuilder.setDescription(createDescription(module, verboseClassComments));
-        moduleBuilder.setReference(module.getReference());
+        if (verboseClassComments) {
+            YangSourceDefinition.of(module).ifPresent(moduleBuilder::setYangSourceDefinition);
+            TypeComments.description(module).ifPresent(moduleBuilder::addComment);
+            module.getDescription().ifPresent(moduleBuilder::setDescription);
+            module.getReference().ifPresent(moduleBuilder::setReference);
+        }
         moduleBuilder.setModuleName(moduleName);
         return moduleBuilder;
     }
@@ -199,9 +209,9 @@ final class GenHelperUtil {
         return null;
      }
 
-    static GeneratedTOBuilder findIdentityByQname(final QName qname, final Map<Module, ModuleContext> genCtx) {
+    static GeneratedTypeBuilder findIdentityByQname(final QName qname, final Map<Module, ModuleContext> genCtx) {
         for (final ModuleContext ctx : genCtx.values()) {
-            final GeneratedTOBuilder result = ctx.getIdentities().get(qname);
+            final GeneratedTypeBuilder result = ctx.getIdentities().get(qname);
             if (result != null) {
                 return result;
             }
@@ -259,26 +269,17 @@ final class GenHelperUtil {
         }
 
         final QName qname = schemaNode.getPath().getLastComponent();
-        final Module originalModule = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(),
-            qname.getRevision());
+        final Module originalModule = schemaContext.findModule(qname.getModule()).get();
         return module.equals(originalModule);
     }
 
-    static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String basePackageName, final SchemaNode
-            schemaNode, final Module module, final Map<Module, ModuleContext> genCtx, final SchemaContext schemaContext,
-            final boolean verboseClassComments, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
-            final TypeProvider typeProvider, final BindingNamespaceType namespaceType) {
-        return addDefaultInterfaceDefinition(basePackageName, schemaNode, null, module, genCtx, schemaContext,
-                verboseClassComments, genTypeBuilders, typeProvider , namespaceType);
-    }
-
     private static QName createQNameFromSuperNode(final Module module, final Object node, final SchemaNode superChildNode) {
         QName childNodeQName = null;
         if (node instanceof Module) {
             childNodeQName = QName.create(((Module) node).getQNameModule(), superChildNode.getQName().getLocalName());
         } else if (node instanceof SchemaNode) {
             childNodeQName = QName.create(((SchemaNode) node).getQName(), superChildNode.getQName().getLocalName());
-        } else if (node instanceof AugmentationSchema) {
+        } else if (node instanceof AugmentationSchemaNode) {
             childNodeQName = QName.create(module.getQNameModule(), superChildNode.getQName().getLocalName());
         } else {
             throw new IllegalArgumentException("Not support node type:" + node);
@@ -317,9 +318,9 @@ final class GenHelperUtil {
                 }
             }
         } else if (superNode instanceof ChoiceSchemaNode) {
-            for (ChoiceCaseNode superCaseNode : ((ChoiceSchemaNode) superNode).getCases()) {
+            for (CaseSchemaNode superCaseNode : ((ChoiceSchemaNode) superNode).getCases().values()) {
                 final QName childQName = createQNameFromSuperNode(module, node, superCaseNode);
-                ChoiceCaseNode caseNode = ((ChoiceSchemaNode) node).getCaseNodeByName(childQName);
+                CaseSchemaNode caseNode = ((ChoiceSchemaNode) node).getCaseNodeByName(childQName);
                 Preconditions.checkNotNull(caseNode, "%s->%s", node, childQName);
 
                 final GeneratedTypeBuilder type = genCtx.get(module).getCase(caseNode.getPath());
@@ -338,9 +339,8 @@ final class GenHelperUtil {
             final Object parentNode, final UsesNode usesNode) {
         SchemaNode groupingNode;
         if (parentNode instanceof Module) {
-            final Module superModule = schemaContext.findModuleByNamespaceAndRevision(
-                    usesNode.getGroupingPath().getLastComponent().getModule().getNamespace(),
-                    usesNode.getGroupingPath().getLastComponent().getModule().getRevision());
+            final Module superModule = schemaContext.findModule(
+                usesNode.getGroupingPath().getLastComponent().getModule()).get();
             groupingNode = superModule.getGroupings()
                     .stream().filter(grouping -> grouping.getPath().equals(usesNode.getGroupingPath()))
                     .findFirst().orElse(null);
@@ -348,10 +348,11 @@ final class GenHelperUtil {
             //FIXME: Schema path is not unique for Yang 1.1, findDataSchemaNode always does search from data node first.
             final Iterable<QName> prefixedPath = usesNode.getGroupingPath().getPathFromRoot();
             final QName current = prefixedPath.iterator().next();
-            final Module targetModule = schemaContext.findModuleByNamespaceAndRevision(current.getNamespace(), current.getRevision());
+            final Module targetModule = schemaContext.findModule(current.getModule()).orElse(null);
             Preconditions.checkArgument(targetModule != null, "Cannot find target module for %s and %s.",
                     current.getNamespace(), current.getRevision());
-            groupingNode = targetModule.getGroupings().stream().filter(grouping -> grouping.getPath().equals(usesNode.getGroupingPath()))
+            groupingNode = targetModule.getGroupings().stream()
+                    .filter(grouping -> grouping.getPath().equals(usesNode.getGroupingPath()))
                     .collect(Collectors.toList()).get(0);
             if (groupingNode == null) {
                 groupingNode = SchemaContextUtil.findDataSchemaNode(schemaContext, usesNode.getGroupingPath());
@@ -396,21 +397,25 @@ final class GenHelperUtil {
         return null;
     }
 
-    static Map<Module, ModuleContext> addRawAugmentGenTypeDefinition(final Module module, final String augmentPackageName,
-            final Type targetTypeRef, final SchemaNode targetNode, final List<AugmentationSchema> schemaPathAugmentListEntry,
-            final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final Map<Module, ModuleContext> genCtx,
-            final SchemaContext schemaContext, final boolean verboseClassComments, final TypeProvider typeProvider,
+    static Map<Module, ModuleContext> addRawAugmentGenTypeDefinition(final Module module,
+            final String augmentPackageName, final Type targetTypeRef, final SchemaNode targetNode,
+            final List<AugmentationSchemaNode> schemaPathAugmentListEntry,
+            final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
+            final Map<Module, ModuleContext> genCtx, final SchemaContext schemaContext,
+            final boolean verboseClassComments, final TypeProvider typeProvider,
             final BindingNamespaceType namespaceType) {
 
         //pick augmentation grouped by augmentation target, there is always at least one
-        final AugmentationSchema augSchema = schemaPathAugmentListEntry.get(0);
+        final AugmentationSchemaNode augSchema = schemaPathAugmentListEntry.get(0);
 
         Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.computeIfAbsent(
                 augmentPackageName, k -> new HashMap<>());
 
         //this requires valid semantics in YANG model
         String augIdentifier = null;
-        for (AugmentationSchema aug : schemaPathAugmentListEntry) {
+        for (AugmentationSchemaNode aug : schemaPathAugmentListEntry) {
+            // FIXME: when there're multiple augment identifiers for augmentations of same target,
+            // it would pick the first identifier.
             augIdentifier = getAugmentIdentifier(aug.getUnknownSchemaNodes());
             break;
         }
@@ -431,20 +436,21 @@ final class GenHelperUtil {
         annotateDeprecatedIfNecessary(augSchema.getStatus(), augTypeBuilder);
 
         //produces getters for augTypeBuilder eventually
-        for (AugmentationSchema aug : schemaPathAugmentListEntry) {
+        for (AugmentationSchemaNode aug : schemaPathAugmentListEntry) {
             //apply all uses
             addImplementedInterfaceFromUses(aug, augTypeBuilder, genCtx);
-            augSchemaNodeToMethods(module, BindingMapping.getRootPackageName(module), augTypeBuilder, augTypeBuilder, aug.getChildNodes(),
-               genCtx, schemaContext, verboseClassComments, typeProvider, genTypeBuilders, namespaceType);
+            augSchemaNodeToMethods(module, BindingMapping.getRootPackageName(module), augTypeBuilder, augTypeBuilder,
+                aug.getChildNodes(), genCtx, schemaContext, verboseClassComments, typeProvider, genTypeBuilders,
+                namespaceType);
         }
 
         augmentBuilders.put(augTypeBuilder.getName(), augTypeBuilder);
 
         if(!augSchema.getChildNodes().isEmpty()) {
-            genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
             genCtx.get(module).addTargetToAugmentation(augTypeBuilder, augSchema.getTargetPath());
         }
         genCtx.get(module).addAugmentType(augTypeBuilder);
+        genCtx.get(module).addTypeToAugmentations(augTypeBuilder, schemaPathAugmentListEntry);
         return genCtx;
     }
 
@@ -504,42 +510,36 @@ final class GenHelperUtil {
      *            string contains the module package name
      * @param schemaNode
      *            schema node for which is created generated type builder
-     * @param parent
-     *            parent type (can be null)
+     * @param childOf
+     *            parent generated type of data tree node, which should be
+     *            set null if current schema node is not a data tree node.
      * @param schemaContext schema context
      * @return generated type builder <code>schemaNode</code>
      */
-    private static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String basePackageName, final SchemaNode
-            schemaNode, final Type parent, final Module module, final Map<Module, ModuleContext> genCtx,
+    public static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String basePackageName, final SchemaNode
+            schemaNode, @Nullable final Type childOf, final Module module, final Map<Module, ModuleContext> genCtx,
             final SchemaContext schemaContext, final boolean verboseClassComments, final Map<String, Map<String,
             GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider, final BindingNamespaceType namespaceType) {
 
-        String suffix = "";
-        if (schemaNode instanceof GroupingDefinition) {
-            suffix = "grouping";
-        } else if (namespaceType.equals(BindingNamespaceType.Grouping)) {
-            suffix = "data";
-        }
-
-        GeneratedTypeBuilder it = addRawInterfaceDefinition(basePackageName, schemaNode, schemaContext, "", suffix,
+        GeneratedTypeBuilder it = addRawInterfaceDefinition(basePackageName, schemaNode, schemaContext, "", "",
                 verboseClassComments, genTypeBuilders, namespaceType, genCtx.get(module));
+
         if (namespaceType.equals(BindingNamespaceType.Data)) {
-            if (parent == null) {
+            if (childOf == null) {
                 it.addImplementsType(BindingTypes.TREE_NODE);
             } else {
-                if (parent instanceof ListSchemaNode) {
-                    it.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, parent, parameterizedTypeFor
-                            (BindingTypes.IDENTIFIABLE_ITEM, parent)));
-                } else {
-                    it.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, parent, parameterizedTypeFor
-                            (BindingTypes.ITEM, parent)));
-                    it.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, it));
+                if (!(schemaNode instanceof ListSchemaNode) ||
+                        ((ListSchemaNode) schemaNode).getKeyDefinition().isEmpty()) {
+                    it.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, childOf,
+                        parameterizedTypeFor(BindingTypes.ITEM, it)));
                 }
             }
 
-            if (!(schemaNode instanceof GroupingDefinition)) {
-                it.addImplementsType(BindingTypes.augmentable(it));
+            if (!(schemaNode instanceof CaseSchemaNode)) {
+                it.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, it));
             }
+
+            it.addImplementsType(BindingTypes.augmentable(it));
         } else {
             it.addImplementsType(BindingTypes.TREE_NODE);
         }
@@ -578,7 +578,7 @@ final class GenHelperUtil {
 
         listenerInterface.addMethod(JavaIdentifierNormalizer.normalizeSpecificIdentifier(sb.toString(), JavaIdentifier.METHOD))
                 .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification")
-                .setComment(encodeAngleBrackets(notification.getDescription())).setReturnType(Types.VOID);
+                .setComment(encodeAngleBrackets(notification.getDescription().orElse(null))).setReturnType(Types.VOID);
         return listenerInterface;
     }
 
@@ -631,10 +631,12 @@ final class GenHelperUtil {
         final GeneratedTypeBuilderImpl newType = new GeneratedTypeBuilderImpl(packageName, schemaNodeName, context);
         final Module module = SchemaContextUtil.findParentModule(schemaContext, schemaNode);
         qNameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, schemaNode.getQName());
-        newType.addComment(schemaNode.getDescription());
-        newType.setDescription(createDescription(schemaNode, newType.getFullyQualifiedName(), schemaContext,
-                verboseClassComments, namespaceType));
-        newType.setReference(schemaNode.getReference());
+        if (verboseClassComments) {
+            YangSourceDefinition.of(module, schemaNode).ifPresent(newType::setYangSourceDefinition);
+            TypeComments.description(schemaNode).ifPresent(newType::addComment);
+            schemaNode.getDescription().ifPresent(newType::setDescription);
+            schemaNode.getReference().ifPresent(newType::setReference);
+        }
         newType.setSchemaPath((List<QName>) schemaNode.getPath().getPathFromRoot());
         newType.setModuleName(module.getName());
         newType.setBasePackageName(BindingMapping.getRootPackageName(module));
@@ -666,15 +668,15 @@ final class GenHelperUtil {
                         schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
             } else if (node instanceof LeafListSchemaNode) {
                 resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) node, module,
-                            typeProvider, genCtx);
+                            typeProvider, genCtx, verboseClassComments);
             } else if (node instanceof LeafSchemaNode) {
                 resolveLeafSchemaNodeAsMethod("", schemaContext, typeBuilder, genCtx, (LeafSchemaNode) node, module,
-                        typeProvider);
+                        typeProvider, verboseClassComments);
             } else if (node instanceof ListSchemaNode) {
                 listToGenType(module, basePackageName, typeBuilder, childOf, (ListSchemaNode) node, schemaContext,
                         verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
             } else if (node instanceof ChoiceSchemaNode) {
-                choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder,
+                choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder, childOf,
                         (ChoiceSchemaNode) node, genTypeBuilders, genCtx, typeProvider, namespaceType);
             } else if (node instanceof AnyXmlSchemaNode || node instanceof AnyDataSchemaNode) {
                 resolveAnyNodeAsMethod(schemaContext, typeBuilder, genCtx, node, module, typeProvider);
@@ -706,16 +708,19 @@ final class GenHelperUtil {
      *             </ul>
      */
     private static void choiceToGenType(final Module module, final SchemaContext schemaContext, final boolean
-            verboseClasssComments, final String basePackageName, final GeneratedTypeBuilder parent, final
-            ChoiceSchemaNode choiceNode, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
-            final Map<Module, ModuleContext> genCtx, final TypeProvider typeProvider, final BindingNamespaceType namespaceType) {
+            verboseClasssComments, final String basePackageName, final GeneratedTypeBuilder parent,
+            final GeneratedTypeBuilder childOf, final ChoiceSchemaNode choiceNode,
+            final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
+            final Map<Module, ModuleContext> genCtx, final TypeProvider typeProvider,
+            final BindingNamespaceType namespaceType) {
         checkArgument(basePackageName != null, "Base Package Name cannot be NULL.");
         checkArgument(choiceNode != null, "Choice Schema Node cannot be NULL.");
 
         final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(basePackageName, choiceNode,
-                schemaContext, "", "", verboseClasssComments, genTypeBuilders, namespaceType, genCtx.get(module));
+            schemaContext, "", "", verboseClasssComments, genTypeBuilders, namespaceType, genCtx.get(module));
         constructGetter(parent, choiceNode.getQName().getLocalName(),
-                choiceNode.getDescription(), choiceTypeBuilder, choiceNode.getStatus());
+                choiceNode.getDescription().orElse(null), choiceTypeBuilder, choiceNode.getStatus());
+        choiceTypeBuilder.setParentTypeForBuilder(childOf);
         if (namespaceType.equals(BindingNamespaceType.Data)) {
             choiceTypeBuilder.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, choiceTypeBuilder));
         }
@@ -735,7 +740,7 @@ final class GenHelperUtil {
                 schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
         if (genType != null) {
             StringBuilder getterName = new StringBuilder(node.getQName().getLocalName());
-            constructGetter(parent, getterName.toString(), node.getDescription(), genType, node.getStatus());
+            constructGetter(parent, getterName.toString(), node.getDescription().orElse(null), genType, node.getStatus());
             resolveDataSchemaNodes(module, basePackageName, genType, genType, node.getChildNodes(), genCtx,
                     schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType);
             processUsesImplements(node, module, schemaContext, genCtx, namespaceType);
@@ -758,7 +763,7 @@ final class GenHelperUtil {
                 getterReturnType = Types.listTypeFor(wildcardTypeFor(genType.getPackageName(), genType.getName(),
                                 true, true, null));
             }
-            constructGetter(parent, nodeName, node.getDescription(), getterReturnType, node.getStatus());
+            constructGetter(parent, nodeName, node.getDescription().orElse(null), getterReturnType, node.getStatus());
 
             final List<QName> listKeys = node.getKeyDefinition();
             final String packageName = new StringBuilder(packageNameForGeneratedType(basePackageName, node.getPath(),
@@ -779,6 +784,15 @@ final class GenHelperUtil {
                 processUsesImplements(node, module, schemaContext, genCtx, namespaceType);
             } else {
                 final GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, node, genCtx.get(module));
+                if (genTOBuilder != null) {
+                    final Type identifiableMarker = Types.parameterizedTypeFor(IDENTIFIABLE, genTOBuilder);
+                    genTOBuilder.addImplementsType(IDENTIFIER);
+                    genType.addImplementsType(identifiableMarker);
+                    genType.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, childOf, parameterizedTypeFor
+                        (BindingTypes.IDENTIFIABLE_ITEM, genType, genTOBuilder)));
+
+                }
+
                 for (final DataSchemaNode schemaNode : node.getChildNodes()) {
                     if (resolveDataSchemaNodesCheck(module, schemaContext, schemaNode)) {
                         addSchemaNodeToListBuilders(nodeName, basePackageName, schemaNode, genType, genTOBuilder, listKeys,
@@ -792,7 +806,6 @@ final class GenHelperUtil {
                     final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID");
                     prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder)));
                     genTOBuilder.setSUID(prop);
-
                     typeBuildersToGenTypes(module, genType, genTOBuilder.toInstance(), genCtx, namespaceType);
                     genCtx.get(module).addGeneratedTOBuilder(node.getPath(), genTOBuilder);
                 }
@@ -810,7 +823,7 @@ final class GenHelperUtil {
                 returnKeyType = wildcardTypeFor(keyType.getPackageName(), keyType.getName(),
                         true, true, null);
             }
-            constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", returnKeyType, Status.CURRENT);
+            constructGetter(typeBuilder, "identifier", "Returns Primary Key of Yang List Type", returnKeyType, Status.CURRENT);
 
         }
     }
@@ -836,7 +849,7 @@ final class GenHelperUtil {
      */
     private static Type resolveLeafSchemaNodeAsMethod(final String nodeName, final SchemaContext schemaContext,
             final GeneratedTypeBuilder typeBuilder, final Map<Module, ModuleContext> genCtx, final LeafSchemaNode leaf,
-            final Module module, final TypeProvider typeProvider) {
+            final Module module, final TypeProvider typeProvider, final boolean verboseClassComments) {
         if (leaf == null || typeBuilder == null) {
             return null;
         }
@@ -860,7 +873,7 @@ final class GenHelperUtil {
             } else {
                 if (typeDef.getBaseType() == null && (typeDef instanceof EnumTypeDefinition
                         || typeDef instanceof UnionTypeDefinition || typeDef instanceof BitsTypeDefinition)) {
-                    LeafSchemaNode originalLeaf = (LeafSchemaNode) ((DerivableSchemaNode) leaf).getOriginal().orNull();
+                    LeafSchemaNode originalLeaf = (LeafSchemaNode) ((DerivableSchemaNode) leaf).getOriginal().orElse(null);
                     Preconditions.checkNotNull(originalLeaf);
                     returnType = genCtx.get(findParentModule(schemaContext, originalLeaf)).getInnerType(typeDef.getPath());
                 } else {
@@ -883,7 +896,8 @@ final class GenHelperUtil {
                         typeProvider, schemaContext, genCtx.get(module), genCtx);
                 if (genTOBuilder != null) {
                     //TODO: https://bugs.opendaylight.org/show_bug.cgi?id=2289
-                    returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider);
+                    returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule,
+                        typeProvider, verboseClassComments);
                 }
             } else if (typeDef instanceof BitsTypeDefinition) {
                 final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule,
@@ -913,11 +927,6 @@ final class GenHelperUtil {
             ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
         }
 
-        String leafDesc = leaf.getDescription();
-        if (leafDesc == null) {
-            leafDesc = "";
-        }
-
         final String leafGetterName;
         if ("key".equals(leafName.toLowerCase())) {
             StringBuilder sb = new StringBuilder(leafName)
@@ -926,7 +935,7 @@ final class GenHelperUtil {
         } else {
             leafGetterName = leafName;
         }
-        constructGetter(typeBuilder, leafGetterName, leafDesc, returnType, leaf.getStatus());
+        constructGetter(typeBuilder, leafGetterName, leaf.getDescription().orElse(""), returnType, leaf.getStatus());
         return returnType;
     }
 
@@ -952,7 +961,7 @@ final class GenHelperUtil {
      */
     private static boolean resolveLeafListSchemaNode(final SchemaContext schemaContext, final GeneratedTypeBuilder
             typeBuilder, final LeafListSchemaNode node, final Module module, final TypeProvider typeProvider,
-            final Map<Module, ModuleContext> genCtx) {
+            final Map<Module, ModuleContext> genCtx, final boolean verboseClassComments) {
         if (node == null || typeBuilder == null) {
             return false;
         }
@@ -976,7 +985,8 @@ final class GenHelperUtil {
                 final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule,
                         typeProvider, schemaContext, genCtx.get(module), genCtx);
                 if (genTOBuilder != null) {
-                    returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider);
+                    returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule,
+                        typeProvider, verboseClassComments);
                 }
             } else if (typeDef instanceof BitsTypeDefinition) {
                 final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule,
@@ -992,7 +1002,7 @@ final class GenHelperUtil {
         }
 
         final ParameterizedType listType = Types.listTypeFor(returnType);
-        constructGetter(typeBuilder, nodeName.getLocalName(), node.getDescription(), listType, node.getStatus());
+        constructGetter(typeBuilder, nodeName.getLocalName(), node.getDescription().orElse(null), listType, node.getStatus());
         return true;
     }
 
@@ -1029,68 +1039,31 @@ final class GenHelperUtil {
      *             </ul>
      */
     private static void generateTypesFromChoiceCases(final Module module, final SchemaContext schemaContext,
-            final Map<Module, ModuleContext> genCtx, final String basePackageName, final Type refChoiceType,
-            final ChoiceSchemaNode choiceNode, final boolean verboseClassComments, final TypeProvider typeProvider,
-            final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final BindingNamespaceType namespaceType) {
+            final Map<Module, ModuleContext> genCtx, final String basePackageName, final GeneratedType refChoiceType,
+            final ChoiceSchemaNode choiceNode, final boolean verboseClassComments,
+            final TypeProvider typeProvider, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
+            final BindingNamespaceType namespaceType) {
         checkArgument(basePackageName != null, "Base Package Name cannot be NULL.");
         checkArgument(refChoiceType != null, "Referenced Choice Type cannot be NULL.");
         checkArgument(choiceNode != null, "ChoiceNode cannot be NULL.");
 
-        final Set<ChoiceCaseNode> caseNodes = choiceNode.getCases();
-        if (caseNodes == null) {
-            return;
-        }
-
-        for (final ChoiceCaseNode caseNode : caseNodes) {
+        for (final CaseSchemaNode caseNode : choiceNode.getCases().values()) {
             if (caseNode != null && resolveDataSchemaNodesCheck(module, schemaContext, caseNode)) {
                 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(basePackageName, caseNode,
-                    module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType);
+                    null, module, genCtx, schemaContext, verboseClassComments,
+                    genTypeBuilders, typeProvider, namespaceType);
                 caseTypeBuilder.addImplementsType(refChoiceType);
-                caseTypeBuilder.setParentTypeForBuilder(refChoiceType);
+                caseTypeBuilder.setParentTypeForBuilder(refChoiceType.getParentTypeForBuilder());
                 annotateDeprecatedIfNecessary(caseNode.getStatus(), caseTypeBuilder);
                 genCtx.get(module).addCaseType(caseNode.getPath(), caseTypeBuilder);
-                genCtx.get(module).addChoiceToCaseMapping(refChoiceType, caseTypeBuilder, caseNode);
-                final Iterable<DataSchemaNode> caseChildNodes = caseNode.getChildNodes();
-                if (caseChildNodes != null) {
-                    final SchemaPath choiceNodeParentPath = choiceNode.getPath().getParent();
-
-                    if (!Iterables.isEmpty(choiceNodeParentPath.getPathFromRoot())) {
-                        SchemaNode parent = findDataSchemaNode(schemaContext, choiceNodeParentPath);
-
-                        if (parent instanceof AugmentationSchema) {
-                            final AugmentationSchema augSchema = (AugmentationSchema) parent;
-                            final SchemaPath targetPath = augSchema.getTargetPath();
-                            SchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
-                            if (targetSchemaNode instanceof DataSchemaNode
-                                    && ((DataSchemaNode) targetSchemaNode).isAddedByUses()) {
-                                if (targetSchemaNode instanceof DerivableSchemaNode) {
-                                    targetSchemaNode = ((DerivableSchemaNode) targetSchemaNode).getOriginal().orNull();
-                                }
-                                if (targetSchemaNode == null) {
-                                    throw new IllegalStateException(
-                                            "Failed to find target node from grouping for augmentation " + augSchema
-                                                    + " in module " + module.getName());
-                                }
-                            }
-                            parent = targetSchemaNode;
-                        }
-
-                        Preconditions.checkState(parent != null, "Could not find Choice node parent %s",
-                                choiceNodeParentPath);
-                        GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.getPath(), genCtx);
-                        if (childOfType == null) {
-                            childOfType = findGroupingByPath(parent.getPath(), genCtx);
-                        }
-                        resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes,
-                                genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType);
-                    } else {
-                        final GeneratedTypeBuilder moduleType = genCtx.get(module).getModuleNode();
-                        Preconditions.checkNotNull(moduleType, "Module type can not be null.");
-                        resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, moduleType, caseChildNodes,
-                            genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType);
-                    }
-                    processUsesImplements(caseNode, module, schemaContext, genCtx, namespaceType);
+                if (namespaceType.equals(BindingNamespaceType.Data)) {
+                    genCtx.get(module).addChoiceToCaseMapping(refChoiceType, caseTypeBuilder, caseNode);
                 }
+
+                resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder,
+                        (GeneratedTypeBuilder) refChoiceType.getParentTypeForBuilder(), caseNode.getChildNodes(),
+                    genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType);
+                processUsesImplements(caseNode, module, schemaContext, genCtx, namespaceType);
             }
         }
     }
@@ -1104,14 +1077,8 @@ final class GenHelperUtil {
             return null;
         }
 
-        String anyDesc = node.getDescription();
-        if (anyDesc == null) {
-            anyDesc = "";
-        }
-
         Type returnType = Types.DOCUMENT;
-
-        constructGetter(typeBuilder, anyName, anyDesc, returnType, node.getStatus());
+        constructGetter(typeBuilder, anyName, node.getDescription().orElse(""), returnType, node.getStatus());
         return returnType;
     }
 
@@ -1165,7 +1132,7 @@ final class GenHelperUtil {
             final QName leafQName = leaf.getQName();
 
             final Type type = resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, typeBuilder, genCtx, leaf, module,
-                    typeProvider);
+                    typeProvider, verboseClassComments);
             if (listKeys.contains(leafQName)) {
                 if (type == null) {
                     resolveLeafSchemaNodeAsProperty(nodeName, schemaContext, typeProvider, genCtx, genTOBuilder, leaf, true,
@@ -1177,7 +1144,7 @@ final class GenHelperUtil {
         } else {
             if (schemaNode instanceof LeafListSchemaNode) {
                 resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) schemaNode, module,
-                        typeProvider, genCtx);
+                        typeProvider, genCtx, verboseClassComments);
             } else if (schemaNode instanceof ContainerSchemaNode) {
                 containerToGenType(module, basePackageName, typeBuilder, typeBuilder, (ContainerSchemaNode) schemaNode,
                         schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
@@ -1185,18 +1152,18 @@ final class GenHelperUtil {
                 listToGenType(module, basePackageName, typeBuilder, typeBuilder, (ListSchemaNode) schemaNode,
                         schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
             } else if (schemaNode instanceof ChoiceSchemaNode) {
-                choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder,
+                choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder, typeBuilder,
                         (ChoiceSchemaNode) schemaNode, genTypeBuilders, genCtx, typeProvider, namespaceType);
             }
         }
     }
 
     private static void addSchemaNodeToListTypeBuilders(final String nodeName, final String basePackageName,
-                                                    final DataSchemaNode schemaNode, final GeneratedTypeBuilder typeBuilder,
-                                                    final GeneratedTypeBuilder genTypeBuilder, final List<QName> listKeys, final Module module,
-                                                    final TypeProvider typeProvider, final SchemaContext schemaContext, final Map<Module, ModuleContext> genCtx,
-                                                    final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final boolean verboseClassComments,
-                                                    final BindingNamespaceType namespaceType) {
+            final DataSchemaNode schemaNode, final GeneratedTypeBuilder typeBuilder,
+            final GeneratedTypeBuilder genTypeBuilder, final List<QName> listKeys, final Module module,
+            final TypeProvider typeProvider, final SchemaContext schemaContext, final Map<Module, ModuleContext> genCtx,
+            final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final boolean verboseClassComments,
+            final BindingNamespaceType namespaceType) {
         checkArgument(schemaNode != null, "Data Schema Node cannot be NULL.");
         checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL.");
 
@@ -1204,15 +1171,15 @@ final class GenHelperUtil {
             final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode;
             final QName leafQName = leaf.getQName();
             final Type type = resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, typeBuilder, genCtx, leaf, module,
-                    typeProvider);
+                    typeProvider, verboseClassComments);
             if (listKeys.contains(leafQName)) {
                 resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, genTypeBuilder, genCtx, leaf, module,
-                        typeProvider);
+                        typeProvider, verboseClassComments);
             }
         } else {
             if (schemaNode instanceof LeafListSchemaNode) {
                 resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) schemaNode, module,
-                        typeProvider, genCtx);
+                        typeProvider, genCtx, verboseClassComments);
             } else if (schemaNode instanceof ContainerSchemaNode) {
                 containerToGenType(module, basePackageName, typeBuilder, typeBuilder, (ContainerSchemaNode) schemaNode,
                         schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
@@ -1220,7 +1187,7 @@ final class GenHelperUtil {
                 listToGenType(module, basePackageName, typeBuilder, typeBuilder, (ListSchemaNode) schemaNode,
                         schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType);
             } else if (schemaNode instanceof ChoiceSchemaNode) {
-                choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder,
+                choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder, typeBuilder,
                         (ChoiceSchemaNode) schemaNode, genTypeBuilders, genCtx, typeProvider, namespaceType);
             }
         }
@@ -1237,16 +1204,14 @@ final class GenHelperUtil {
                 // GeneratedType for this type definition should be already
                 // created
                 final QName qname = typeDef.getQName();
-                final Module unionModule = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(),
-                        qname.getRevision());
+                final Module unionModule = schemaContext.findModule(qname.getModule()).get();
                 final ModuleContext mc = genCtx.get(unionModule);
                 returnType = mc.getTypedefs().get(typeDef.getPath());
             } else if (typeDef instanceof EnumTypeDefinition && typeDef.getBaseType() == null) {
                 // Annonymous enumeration (already generated, since it is inherited via uses).
                 LeafSchemaNode originalLeaf = (LeafSchemaNode) SchemaNodeUtils.getRootOriginalIfPossible(leaf);
                 QName qname = originalLeaf.getQName();
-                final Module enumModule =  schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(),
-                        qname.getRevision());
+                final Module enumModule =  schemaContext.findModule(qname.getModule()).orElse(null);
                 returnType = genCtx.get(enumModule).getInnerType(originalLeaf.getType().getPath());
             } else {
                 returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, genCtx.get(module));
@@ -1269,12 +1234,14 @@ final class GenHelperUtil {
 
         final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(basePackageName, node, childOf, module,
                 genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType);
-        genType.addComment(node.getDescription());
         annotateDeprecatedIfNecessary(node.getStatus(), genType);
-        genType.setDescription(createDescription(node, genType.getFullyQualifiedName(), schemaContext,
-                verboseClassComments, namespaceType));
         genType.setModuleName(module.getName());
-        genType.setReference(node.getReference());
+        if (verboseClassComments) {
+            YangSourceDefinition.of(module, node).ifPresent(genType::setYangSourceDefinition);
+            TypeComments.description(node).ifPresent(genType::addComment);
+            node.getDescription().ifPresent(genType::setDescription);
+            node.getReference().ifPresent(genType::setReference);
+        }
         genType.setSchemaPath((List) node.getPath().getPathFromRoot());
         genType.setParentTypeForBuilder(childOf);
         if (node instanceof DataNodeContainer) {
@@ -1347,7 +1314,7 @@ final class GenHelperUtil {
     private static Map<Module, ModuleContext> groupingToGenType(final String basePackageName, final GroupingDefinition grouping, final Module
             module, Map<Module, ModuleContext> genCtx, final SchemaContext schemaContext, final boolean
             verboseClassComments, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
-        final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(basePackageName, grouping, module, genCtx,
+        final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(basePackageName, grouping, null, module, genCtx,
                 schemaContext, verboseClassComments, genTypeBuilders, typeProvider, BindingNamespaceType.Grouping);
         annotateDeprecatedIfNecessary(grouping.getStatus(), genType);
         genCtx.get(module).addGroupingType(grouping, genType);
@@ -1386,13 +1353,13 @@ final class GenHelperUtil {
         return genCtx;
     }
 
-    private static GeneratedTOBuilder resolveIdentitySchemaNode(final String basePackageName, final SchemaContext schemaContext,
+    private static GeneratedTypeBuilder resolveIdentitySchemaNode(final String basePackageName, final SchemaContext schemaContext,
             final IdentitySchemaNode identity, final Module module, final boolean verboseClassComments,
             final Map<Module, ModuleContext> genCtx) {
         Preconditions.checkNotNull(identity,"Identity can not be null!");
 
         //check first if identity has been resolved as base identity of some other one
-        GeneratedTOBuilder newType = findIdentityByQname(identity.getQName(), genCtx);
+        GeneratedTypeBuilder newType = findIdentityByQname(identity.getQName(), genCtx);
         if (newType == null) {
             final Module parentModule = SchemaContextUtil.findParentModule(schemaContext, identity);
             Preconditions.checkState(module.equals(parentModule),
@@ -1401,29 +1368,30 @@ final class GenHelperUtil {
 
             final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, identity.getPath(),
                     BindingNamespaceType.Identity);
-            newType = new GeneratedTOBuilderImpl(packageName, identity.getQName().getLocalName(), true, false,
+            newType = new GeneratedTypeBuilderImpl(packageName, identity.getQName().getLocalName(), true, false,
                     genCtx.get(module));
 
             final Set<IdentitySchemaNode> baseIdentities = identity.getBaseIdentities();
             if (baseIdentities.size() == 0) {
                 //no base - abstract
-                final GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(BaseIdentity.class.getPackage().getName(),
+                final GeneratedTypeBuilderImpl genType = new GeneratedTypeBuilderImpl(BaseIdentity.class.getPackage().getName(),
                         BaseIdentity.class.getSimpleName(), genCtx.get(module));
-                newType.setExtendsType(gto.toInstance());
+                newType.addImplementsType(genType.toInstance());
             } else {
-                //one base - inheritance
-                final IdentitySchemaNode baseIdentity = baseIdentities.iterator().next();
-                GeneratedTOBuilder baseType = resolveIdentitySchemaNode(basePackageName, schemaContext,
-                    baseIdentity, module, verboseClassComments, genCtx);
-                newType.setExtendsType(baseType.toInstance());
+                //multiple bases - inheritance
+                for (IdentitySchemaNode baseIdentity : baseIdentities) {
+                    GeneratedTypeBuilder baseType = resolveIdentitySchemaNode(basePackageName, schemaContext,
+                        baseIdentity, module, verboseClassComments, genCtx);
+                    newType.addImplementsType(baseType.toInstance());
+                }
             }
 
-            newType.setAbstract(true);
-            newType.addComment(identity.getDescription());
-            newType.setDescription(createDescription(identity, newType.getFullyQualifiedName(), schemaContext,
-                    verboseClassComments, BindingNamespaceType.Identity));
-            newType.setReference(identity.getReference());
-            newType.setModuleName(module.getName());
+            if (verboseClassComments) {
+                YangSourceDefinition.of(module).ifPresent(newType::setYangSourceDefinition);
+                TypeComments.description(module).ifPresent(newType::addComment);
+                module.getDescription().ifPresent(newType::setDescription);
+                module.getReference().ifPresent(newType::setReference);
+            }
             newType.setSchemaPath((List) identity.getPath().getPathFromRoot());
 
             qNameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, identity.getQName());