Increased version of binding-generator to 0.5.5-SNAPSHOT.
[controller.git] / opendaylight / sal / yang-prototype / code-generator / binding-generator-impl / src / main / java / org / opendaylight / controller / sal / binding / generator / impl / BindingGeneratorImpl.java
index 8b680509ddbc587ead6a16d59a320d738c40041c..0f59f1aaa3ca9f9402c8c336988cc09e6e177422 100644 (file)
@@ -8,12 +8,19 @@
 package org.opendaylight.controller.sal.binding.generator.impl;
 
 import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
-import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findDataSchemaNode;
-import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findParentModule;
-
-import java.util.*;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Future;
 
+import javax.management.Notification;
+
 import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl;
 import org.opendaylight.controller.binding.generator.util.Types;
 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
@@ -23,23 +30,48 @@ import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
 import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
 import org.opendaylight.controller.sal.binding.model.api.Type;
-import org.opendaylight.controller.sal.binding.model.api.type.builder.*;
+import org.opendaylight.controller.sal.binding.model.api.type.builder.EnumBuilder;
+import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
+import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;
+import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
+import org.opendaylight.controller.sal.binding.model.api.type.builder.MethodSignatureBuilder;
+import org.opendaylight.controller.sal.binding.yang.types.GroupingDefinitionDependencySort;
 import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl;
-import org.opendaylight.controller.yang.binding.Notification;
-import org.opendaylight.controller.yang.common.QName;
-import org.opendaylight.controller.yang.common.RpcResult;
-import org.opendaylight.controller.yang.model.api.*;
-import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
-import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
-import org.opendaylight.controller.yang.model.util.DataNodeIterator;
-import org.opendaylight.controller.yang.model.util.ExtendedType;
-import org.opendaylight.controller.yang.model.util.SchemaContextUtil;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+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.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+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.Module;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
+import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.opendaylight.yangtools.yang.model.util.UnionType;
 
 public final class BindingGeneratorImpl implements BindingGenerator {
 
     private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
     private TypeProvider typeProvider;
     private SchemaContext schemaContext;
+    private final Map<SchemaPath, GeneratedType> allGroupings = new HashMap<SchemaPath, GeneratedType>();
 
     public BindingGeneratorImpl() {
         super();
@@ -60,6 +92,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         final Set<Module> modules = context.getModules();
         genTypeBuilders = new HashMap<>();
         for (final Module module : modules) {
+            generatedTypes.addAll(allGroupingsToGenTypes(module));
             generatedTypes.add(moduleToDataType(module));
             generatedTypes.addAll(allTypeDefinitionsToGenTypes(module));
             generatedTypes.addAll(allContainersToGenTypes(module));
@@ -69,7 +102,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
             generatedTypes.addAll(allRPCMethodsToGenType(module));
             generatedTypes.addAll(allNotificationsToGenType(module));
             generatedTypes.addAll(allIdentitiesToGenTypes(module, context));
-            generatedTypes.addAll(allGroupingsToGenTypes(module));
+
         }
         return generatedTypes;
     }
@@ -94,6 +127,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         for (final Module contextModule : contextModules) {
             final List<Type> generatedTypes = new ArrayList<>();
 
+            generatedTypes.addAll(allGroupingsToGenTypes(contextModule));
             generatedTypes.add(moduleToDataType(contextModule));
             generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule));
             generatedTypes.addAll(allContainersToGenTypes(contextModule));
@@ -103,7 +137,6 @@ public final class BindingGeneratorImpl implements BindingGenerator {
             generatedTypes.addAll(allRPCMethodsToGenType(contextModule));
             generatedTypes.addAll(allNotificationsToGenType(contextModule));
             generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context));
-            generatedTypes.addAll(allGroupingsToGenTypes(contextModule));
 
             if (modules.contains(contextModule)) {
                 filteredGenTypes.addAll(generatedTypes);
@@ -155,7 +188,9 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         final List<ContainerSchemaNode> schemaContainers = it.allContainers();
         final String basePackageName = moduleNamespaceToPackageName(module);
         for (final ContainerSchemaNode container : schemaContainers) {
-            generatedTypes.add(containerToGenType(basePackageName, container));
+            if (!container.isAddedByUses()) {
+                generatedTypes.add(containerToGenType(basePackageName, container));
+            }
         }
         return generatedTypes;
     }
@@ -180,7 +215,9 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         final String basePackageName = moduleNamespaceToPackageName(module);
         if (schemaLists != null) {
             for (final ListSchemaNode list : schemaLists) {
-                generatedTypes.addAll(listToGenType(basePackageName, list));
+                if (!list.isAddedByUses()) {
+                    generatedTypes.addAll(listToGenType(basePackageName, list));
+                }
             }
         }
         return generatedTypes;
@@ -200,7 +237,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
         final List<GeneratedType> generatedTypes = new ArrayList<>();
         for (final ChoiceNode choice : choiceNodes) {
-            if (choice != null) {
+            if ((choice != null) && !choice.isAddedByUses()) {
                 generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice));
             }
         }
@@ -262,6 +299,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         }
 
         final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data");
+        addInterfaceDefinition(module, moduleDataTypeBuilder);
 
         final String basePackageName = moduleNamespaceToPackageName(module);
         if (moduleDataTypeBuilder != null) {
@@ -294,7 +332,8 @@ public final class BindingGeneratorImpl implements BindingGenerator {
             if (rpc != null) {
 
                 String rpcName = parseToClassName(rpc.getQName().getLocalName());
-                MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcName);
+                String rpcMethodName = parseToValidParamName(rpcName);
+                MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcMethodName);
 
                 final List<DataNodeIterator> rpcInOut = new ArrayList<>();
 
@@ -304,6 +343,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 if (input != null) {
                     rpcInOut.add(new DataNodeIterator(input));
                     GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName);
+                    addInterfaceDefinition(input, inType);
                     resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes());
                     Type inTypeInstance = inType.toInstance();
                     genRPCTypes.add(inTypeInstance);
@@ -313,8 +353,8 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 Type outTypeInstance = Types.typeForClass(Void.class);
                 if (output != null) {
                     rpcInOut.add(new DataNodeIterator(output));
-
                     GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName);
+                    addInterfaceDefinition(output, outType);
                     resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes());
                     outTypeInstance = outType.toInstance();
                     genRPCTypes.add(outTypeInstance);
@@ -327,13 +367,17 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                     List<ContainerSchemaNode> nContainers = it.allContainers();
                     if ((nContainers != null) && !nContainers.isEmpty()) {
                         for (final ContainerSchemaNode container : nContainers) {
-                            genRPCTypes.add(containerToGenType(basePackageName, container));
+                            if (!container.isAddedByUses()) {
+                                genRPCTypes.add(containerToGenType(basePackageName, container));
+                            }
                         }
                     }
                     List<ListSchemaNode> nLists = it.allLists();
                     if ((nLists != null) && !nLists.isEmpty()) {
                         for (final ListSchemaNode list : nLists) {
-                            genRPCTypes.addAll(listToGenType(basePackageName, list));
+                            if (!list.isAddedByUses()) {
+                                genRPCTypes.addAll(listToGenType(basePackageName, list));
+                            }
                         }
                     }
                 }
@@ -367,11 +411,15 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
                 // Containers
                 for (ContainerSchemaNode node : it.allContainers()) {
-                    genNotifyTypes.add(containerToGenType(basePackageName, node));
+                    if (!node.isAddedByUses()) {
+                        genNotifyTypes.add(containerToGenType(basePackageName, node));
+                    }
                 }
                 // Lists
                 for (ListSchemaNode node : it.allLists()) {
-                    genNotifyTypes.addAll(listToGenType(basePackageName, node));
+                    if (!node.isAddedByUses()) {
+                        genNotifyTypes.addAll(listToGenType(basePackageName, node));
+                    }
                 }
                 final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName,
                         notification);
@@ -429,10 +477,16 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         final List<Type> genTypes = new ArrayList<>();
         final String basePackageName = moduleNamespaceToPackageName(module);
         final Set<GroupingDefinition> groupings = module.getGroupings();
-        if (groupings != null && !groupings.isEmpty()) {
-            for (final GroupingDefinition grouping : groupings) {
-                genTypes.add(groupingToGenType(basePackageName, grouping));
-            }
+        List<GroupingDefinition> groupingsSortedByDependencies;
+        // groupingsSortedByDependencies =
+        // sortGroupingDefinitionsByUses(groupings);
+        groupingsSortedByDependencies = GroupingDefinitionDependencySort.sort(groupings);
+
+        for (final GroupingDefinition grouping : groupingsSortedByDependencies) {
+            GeneratedType genType = groupingToGenType(basePackageName, grouping);
+            genTypes.add(genType);
+            SchemaPath schemaPath = grouping.getPath();
+            allGroupings.put(schemaPath, genType);
         }
         return genTypes;
     }
@@ -523,20 +577,40 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null)
                 && (targetSchemaNode.getQName().getLocalName() != null)) {
             final Module targetModule = findParentModule(schemaContext, targetSchemaNode);
-
             final String targetBasePackage = moduleNamespaceToPackageName(targetModule);
             final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath());
-
             final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName();
             final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
-            final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName,
-                    targetPackageName, targetSchemaNodeName, augSchema);
-            if (augTypeBuilder != null) {
-                genTypes.add(augTypeBuilder.toInstance());
+
+            if (!(targetSchemaNode instanceof ChoiceNode)) {
+                final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName,
+                        targetPackageName, targetSchemaNodeName, augSchema);
+                addInterfaceDefinition(augSchema, augTypeBuilder);
+
+                final GeneratedType augType = augTypeBuilder.toInstance();
+                genTypes.add(augType);
+            } else {
+                final Type refChoiceType = new ReferencedTypeImpl(targetPackageName,
+                        parseToClassName(targetSchemaNodeName));
+                final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode;
+                final Set<ChoiceCaseNode> choiceCaseNodes = choiceTarget.getCases();
+                genTypes.addAll(augmentCasesToGenTypes(augmentPackageName, refChoiceType, choiceCaseNodes));
             }
             genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes));
+        }
+        return genTypes;
+    }
 
+    private List<GeneratedType> augmentCasesToGenTypes(final String augmentPackageName, final Type refChoiceType,
+            final Set<ChoiceCaseNode> choiceCaseNodes) {
+        if (augmentPackageName == null) {
+            throw new IllegalArgumentException("Augment Package Name string cannot be NULL!");
+        }
+        if (choiceCaseNodes == null) {
+            throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
         }
+        final List<GeneratedType> genTypes = generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType,
+                choiceCaseNodes);
         return genTypes;
     }
 
@@ -576,23 +650,35 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 } else if (childNode instanceof ListSchemaNode) {
                     genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode));
                 }
+            } else if (childNode instanceof ChoiceNode) {
+                final ChoiceNode choice = (ChoiceNode) childNode;
+                for (final ChoiceCaseNode caseNode : choice.getCases()) {
+                    augSchemaIts.add(new DataNodeIterator(caseNode));
+                }
+                genTypes.addAll(choiceToGeneratedType(augBasePackageName, (ChoiceNode) childNode));
             }
         }
 
         for (final DataNodeIterator it : augSchemaIts) {
             final List<ContainerSchemaNode> augContainers = it.allContainers();
             final List<ListSchemaNode> augLists = it.allLists();
+            final List<ChoiceNode> augChoices = it.allChoices();
 
-            if ((augContainers != null) && !augContainers.isEmpty()) {
+            if (augContainers != null) {
                 for (final ContainerSchemaNode container : augContainers) {
                     genTypes.add(containerToGenType(augBasePackageName, container));
                 }
             }
-            if ((augLists != null) && !augLists.isEmpty()) {
+            if (augLists != null) {
                 for (final ListSchemaNode list : augLists) {
                     genTypes.addAll(listToGenType(augBasePackageName, list));
                 }
             }
+            if (augChoices != null) {
+                for (final ChoiceNode choice : augChoices) {
+                    genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice));
+                }
+            }
         }
         return genTypes;
     }
@@ -625,7 +711,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
             final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
         if ((schemaNodes != null) && (typeBuilder != null)) {
             for (final DataSchemaNode schemaNode : schemaNodes) {
-                if (schemaNode.isAugmenting()) {
+                if (schemaNode.isAugmenting() || schemaNode.isAddedByUses()) {
                     continue;
                 }
                 addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);
@@ -676,7 +762,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         }
 
         final String choiceName = choiceNode.getQName().getLocalName();
-        if (choiceName != null) {
+        if (choiceName != null && !choiceNode.isAddedByUses()) {
             final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
             final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode);
             constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType);
@@ -719,7 +805,37 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
         final List<GeneratedType> generatedTypes = new ArrayList<>();
         for (final ChoiceCaseNode caseNode : caseNodes) {
-            if (caseNode != null) {
+            if (caseNode != null && !caseNode.isAddedByUses()) {
+                final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
+                final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
+                caseTypeBuilder.addImplementsType(refChoiceType);
+
+                final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();
+                if (childNodes != null) {
+                    resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);
+                }
+                generatedTypes.add(caseTypeBuilder.toInstance());
+            }
+        }
+
+        return generatedTypes;
+    }
+
+    private List<GeneratedType> generateTypesFromAugmentedChoiceCases(final String basePackageName,
+            final Type refChoiceType, final Set<ChoiceCaseNode> caseNodes) {
+        if (basePackageName == null) {
+            throw new IllegalArgumentException("Base Package Name cannot be NULL!");
+        }
+        if (refChoiceType == null) {
+            throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");
+        }
+        if (caseNodes == null) {
+            throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
+        }
+
+        final List<GeneratedType> generatedTypes = new ArrayList<>();
+        for (final ChoiceCaseNode caseNode : caseNodes) {
+            if (caseNode != null && caseNode.isAugmenting()) {
                 final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
                 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
                 caseTypeBuilder.addImplementsType(refChoiceType);
@@ -743,13 +859,12 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 leafDesc = "";
             }
 
-            if (leafName != null) {
+            if (leafName != null && !leaf.isAddedByUses()) {
                 final TypeDefinition<?> typeDef = leaf.getType();
 
                 Type returnType = null;
-                if (!(typeDef instanceof EnumTypeDefinition)) {
+                if (typeDef instanceof EnumTypeDefinition) {
                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
-                } else {
                     final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef);
                     final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName,
                             typeBuilder);
@@ -758,12 +873,21 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                         returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
                     }
                     ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
+                } else if (typeDef instanceof UnionType) {
+                    GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName);
+                    if (genTOBuilder != null) {
+                        returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
+                    }
+                } else if (typeDef instanceof BitsTypeDefinition) {
+                    GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName);
+                    if (genTOBuilder != null) {
+                        returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
+                    }
+                } else {
+                    returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
                 }
                 if (returnType != null) {
                     constructGetter(typeBuilder, leafName, leafDesc, returnType);
-                    if (!leaf.isConfiguration()) {
-                        constructSetter(typeBuilder, leafName, leafDesc, returnType);
-                    }
                     return true;
                 }
             }
@@ -780,7 +904,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 leafDesc = "";
             }
 
-            if (leafName != null) {
+            if (leafName != null && !leaf.isAddedByUses()) {
                 final TypeDefinition<?> typeDef = leaf.getType();
 
                 // TODO: properly resolve enum types
@@ -812,14 +936,11 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 nodeDesc = "";
             }
 
-            if (nodeName != null) {
+            if (nodeName != null && !node.isAddedByUses()) {
                 final TypeDefinition<?> type = node.getType();
                 final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type));
 
                 constructGetter(typeBuilder, nodeName, nodeDesc, listType);
-                if (!node.isConfiguration()) {
-                    constructSetter(typeBuilder, nodeName, nodeDesc, listType);
-                }
                 return true;
             }
         }
@@ -831,7 +952,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         if ((containerNode != null) && (typeBuilder != null)) {
             final String nodeName = containerNode.getQName().getLocalName();
 
-            if (nodeName != null) {
+            if (nodeName != null && !containerNode.isAddedByUses()) {
                 final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());
 
                 final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode);
@@ -848,13 +969,10 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         if ((schemaNode != null) && (typeBuilder != null)) {
             final String listName = schemaNode.getQName().getLocalName();
 
-            if (listName != null) {
+            if (listName != null && !schemaNode.isAddedByUses()) {
                 final String packageName = packageNameForGeneratedType(basePackageName, schemaNode.getPath());
                 final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, schemaNode);
                 constructGetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));
-                if (!schemaNode.isConfiguration()) {
-                    constructSetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));
-                }
                 return true;
             }
         }
@@ -862,17 +980,26 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     }
 
     /**
-     * Method instantiates new Generated Type Builder and sets the implements definitions of Data Object and
-     * Augmentable.
+     * Method instantiates new Generated Type Builder and sets the implements
+     * definitions of Data Object and Augmentable.
      *
-     * @param packageName Generated Type Package Name
-     * @param schemaNode Schema Node definition
+     * @param packageName
+     *            Generated Type Package Name
+     * @param schemaNode
+     *            Schema Node definition
      * @return Generated Type Builder instance for Schema Node definition
      */
     private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
         final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, "");
         builder.addImplementsType(Types.DATA_OBJECT);
-        builder.addImplementsType(Types.augmentableTypeFor(builder));
+        if (!(schemaNode instanceof GroupingDefinition)) {
+            builder.addImplementsType(Types.augmentableTypeFor(builder));
+        }
+
+        if (schemaNode instanceof DataNodeContainer) {
+            addInterfaceDefinition((DataNodeContainer) schemaNode, builder);
+        }
+
         return builder;
     }
 
@@ -1085,4 +1212,47 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         }
         return genTOBuilder;
     }
+
+    private GeneratedTOBuilder addEnclosedTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
+            String leafName) {
+        String className = parseToClassName(leafName);
+        GeneratedTOBuilder genTOBuilder = null;
+        if (typeDef instanceof UnionType) {
+            genTOBuilder = ((TypeProviderImpl) typeProvider).addUnionGeneratedTypeDefinition(
+                    typeBuilder.getFullyQualifiedName(), typeDef, className);
+        } else if (typeDef instanceof BitsTypeDefinition) {
+            genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject(
+                    typeBuilder.getFullyQualifiedName(), typeDef, className);
+        }
+        if (genTOBuilder != null) {
+            typeBuilder.addEnclosingTransferObject(genTOBuilder);
+            return genTOBuilder;
+        }
+        return null;
+
+    }
+
+    /**
+     * Adds the implemented types to type builder. The method passes through the
+     * list of elements which contains {@code dataNodeContainer} and adds them
+     * as <i>implements type</i> to <code>builder</code>
+     *
+     * @param dataNodeContainer
+     *            element which contains the list of used YANG groupings
+     * @param builder
+     *            builder to which are added implemented types according to
+     *            <code>dataNodeContainer</code>
+     * @return generated type builder which contains implemented types
+     */
+    private GeneratedTypeBuilder addInterfaceDefinition(final DataNodeContainer dataNodeContainer,
+            final GeneratedTypeBuilder builder) {
+        for (UsesNode usesNode : dataNodeContainer.getUses()) {
+            if (usesNode.getGroupingPath() != null) {
+                GeneratedType genType = allGroupings.get(usesNode.getGroupingPath());
+                builder.addImplementsType(new ReferencedTypeImpl(genType.getPackageName(), genType.getName()));
+            }
+        }
+        return builder;
+    }
+
 }