Revert "BUG-1196: fixed bug in choice case codec."
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / BindingGeneratorImpl.xtend
index bfbbf2f65b6823ab64a4e42200a191f95ffaa43d..8a41bef08f88a24889e712412508735e47227f87 100644 (file)
@@ -79,6 +79,7 @@ import org.opendaylight.yangtools.yang.binding.BindingMapping
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilderBase
 
 import com.google.common.collect.Sets
+import java.util.TreeSet
 
 public class BindingGeneratorImpl implements BindingGenerator {
 
@@ -252,6 +253,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
         val packageName = packageNameForGeneratedType(basePackageName, node.path)
         val genType = addDefaultInterfaceDefinition(packageName, node, childOf)
+        genType.addComment(node.getDescription());
         if (node instanceof DataNodeContainer) {
             genCtx.get(module).addChildNodeType(node.path, genType)
             groupingsToGenTypes(module, (node as DataNodeContainer).groupings)
@@ -363,19 +365,45 @@ public class BindingGeneratorImpl implements BindingGenerator {
         checkState(module.augmentations !== null, "Augmentations Set cannot be NULL.");
 
         val Set<AugmentationSchema> augmentations = module.augmentations;
-        val List<AugmentationSchema> sortedAugmentations = new ArrayList(augmentations);
+        var List<AugmentationSchema> sortedAugmentations = getSortedOrNull(augmentations)
+        if (sortedAugmentations != null) {
+            return sortedAugmentations
+        }
+        sortedAugmentations = new ArrayList(augmentations);
         Collections.sort(sortedAugmentations,
             [ augSchema1, augSchema2 |
-                if (augSchema1.targetPath.path.size() > augSchema2.targetPath.path.size()) {
-                    return 1;
-                } else if (augSchema1.targetPath.path.size() < augSchema2.targetPath.path.size()) {
-                    return -1;
+                val Iterator<QName> thisIt = augSchema1.targetPath.getPath().iterator();
+                val Iterator<QName> otherIt = augSchema2.getTargetPath().getPath().iterator();
+                while (thisIt.hasNext()) {
+                    if (otherIt.hasNext()) {
+                        val int comp = thisIt.next().compareTo(otherIt.next());
+                        if (comp != 0) {
+                            return comp
+                        }
+                    } else {
+                        return 1
+                    }
                 }
-                return 0;
+                if (otherIt.hasNext()) {
+                    return -1
+                }
+                return 0
             ]);
         return sortedAugmentations;
     }
 
+    private def List<AugmentationSchema> getSortedOrNull(Collection<AugmentationSchema> collection) {
+        val TreeSet<AugmentationSchema> set = new TreeSet()
+        for (e : collection) {
+            if (e instanceof Comparable<?>) {
+                set.add(e)
+            } else {
+                return null
+            }
+        }
+        return new ArrayList(set.toArray)
+    }
+
     /**
      * Converts whole <b>module</b> to <code>GeneratedType</code> object.
      * Firstly is created the module builder object from which is vally
@@ -396,6 +424,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
         val moduleDataTypeBuilder = moduleTypeBuilder(module, "Data");
         addImplementedInterfaceFromUses(module, moduleDataTypeBuilder);
         moduleDataTypeBuilder.addImplementsType(DATA_ROOT);
+        moduleDataTypeBuilder.addComment(module.getDescription());
         return moduleDataTypeBuilder;
     }
 
@@ -433,7 +462,9 @@ public class BindingGeneratorImpl implements BindingGenerator {
             if (rpc !== null) {
                 val rpcName = BindingMapping.getClassName(rpc.QName);
                 val rpcMethodName = parseToValidParamName(rpcName);
+                val rpcComment = rpc.getDescription();
                 val method = interfaceBuilder.addMethod(rpcMethodName);
+
                 val input = rpc.input;
                 val output = rpc.output;
 
@@ -460,7 +491,9 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 }
 
                 val rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult), outTypeInstance);
+                method.setComment(rpcComment);
                 method.setReturnType(Types.parameterizedTypeFor(FUTURE, rpcRes));
+
             }
         }
 
@@ -513,7 +546,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
                 listenerInterface.addMethod("on" + notificationInterface.name) //
                 .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification").
-                    setReturnType(Types.VOID);
+                    setComment(notification.getDescription()).setReturnType(Types.VOID);
             }
         }
 
@@ -580,6 +613,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
             newType.setExtendsType(gto);
         }
         newType.setAbstract(true);
+        newType.addComment(identity.getDescription());
         val qname = identity.QName;
         
         newType.qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,qname);
@@ -763,10 +797,9 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         if (!(targetSchemaNode instanceof ChoiceNode)) {
             var packageName = augmentPackageName;
-            val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
-                targetTypeBuilder.toInstance, augSchema);
-            genCtx.get(module).addAugmentType(augTypeBuilder)
-            genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
+            val targetType = new ReferencedTypeImpl(targetTypeBuilder.packageName,targetTypeBuilder.name);
+            addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,targetType, augSchema);
+            
         } else {
             generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance,
                 targetSchemaNode as ChoiceNode, augSchema.childNodes);
@@ -801,10 +834,8 @@ public class BindingGeneratorImpl implements BindingGenerator {
             if (usesNodeParent instanceof SchemaNode) {
                 packageName = packageNameForGeneratedType(augmentPackageName, (usesNodeParent as SchemaNode).path, true)
             }
-            val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
+            addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
                 targetTypeBuilder.toInstance, augSchema);
-            genCtx.get(module).addAugmentType(augTypeBuilder)
-            genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
         } else {
             generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance,
                 targetSchemaNode as ChoiceNode, augSchema.childNodes);
@@ -835,18 +866,17 @@ public class BindingGeneratorImpl implements BindingGenerator {
             return null;
         }
 
-        val String targetSchemaNodeName = result.QName.localName;
         var boolean fromUses = (result as DataSchemaNode).addedByUses
         var Iterator<UsesNode> groupingUses = grouping.uses.iterator;
-        while (fromUses) {
-            if (groupingUses.hasNext()) {
-                grouping = findNodeInSchemaContext(schemaContext, groupingUses.next().groupingPath.path) as GroupingDefinition;
-                result = grouping.getDataChildByName(targetSchemaNodeName);
-                fromUses = (result as DataSchemaNode).addedByUses;
-            } else {
-                throw new NullPointerException("Failed to generate code for augment in " + parentUsesNode);
+        while (groupingUses.hasNext && fromUses) {
+            result = findOriginalTargetFromGrouping(targetPath, groupingUses.next);
+            if (result != null) {
+                fromUses = (result as DataSchemaNode).addedByUses
             }
         }
+        if (fromUses) {
+            throw new NullPointerException("Failed to generate code for augment in " + parentUsesNode);
+        }
 
         return result as DataSchemaNode
     }
@@ -894,6 +924,10 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         augSchemaNodeToMethods(module, basePackageName, augTypeBuilder, augTypeBuilder, augSchema.childNodes);
         augmentBuilders.put(augTypeName, augTypeBuilder);
+        
+        genCtx.get(module).addTargetToAugmentation(targetTypeRef,augTypeBuilder);
+        genCtx.get(module).addAugmentType(augTypeBuilder);
+        genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
         return augTypeBuilder;
     }
 
@@ -1121,7 +1155,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                     val List<QName> nodeNames = nodeSp.path
                     val List<QName> nodeNewNames = new ArrayList(nodeNames)
                     nodeNewNames.remove(nodeNewNames.size - 1)
-                    val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute)
+                    val SchemaPath nodeNewSp = SchemaPath.create(nodeNewNames, nodeSp.absolute)
                     parentNode = findDataSchemaNode(schemaContext, nodeNewSp)
 
                     var SchemaNode parent
@@ -1144,7 +1178,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                         val List<QName> names = sp.path
                         val List<QName> newNames = new ArrayList(names)
                         newNames.remove(newNames.size - 1)
-                        val SchemaPath newSp = new SchemaPath(newNames, sp.absolute)
+                        val SchemaPath newSp = SchemaPath.create(newNames, sp.absolute)
                         parent = findDataSchemaNode(schemaContext, newSp)
                     }
                     var GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.path)
@@ -1198,7 +1232,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 val List<QName> nodeNames = nodeSp.path
                 val List<QName> nodeNewNames = new ArrayList(nodeNames)
                 nodeNewNames.remove(nodeNewNames.size - 1)
-                val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute)
+                val SchemaPath nodeNewSp = SchemaPath.create(nodeNewNames, nodeSp.absolute)
                 parent = findDataSchemaNode(schemaContext, nodeNewSp)
 
                 var GeneratedTypeBuilder childOfType = null;
@@ -1253,7 +1287,8 @@ public class BindingGeneratorImpl implements BindingGenerator {
      *         <li>true - in other cases</li>
      *         </ul>
      */
-    private def boolean resolveLeafSchemaNodeAsMethod(GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) {
+    private def Type resolveLeafSchemaNodeAsMethod(GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) {
+        var Type returnType = null;
         if ((leaf !== null) && (typeBuilder !== null)) {
             val leafName = leaf.QName.localName;
             var String leafDesc = leaf.description;
@@ -1265,7 +1300,6 @@ public class BindingGeneratorImpl implements BindingGenerator {
             if (leafName !== null && !leaf.isAddedByUses()) {
                 val TypeDefinition<?> typeDef = leaf.type;
 
-                var Type returnType = null;
                 var GeneratedTOBuilder genTOBuilder;
                 if (typeDef instanceof EnumTypeDefinition) {
                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
@@ -1273,7 +1307,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                     val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.QName, typeBuilder);
 
                     if (enumBuilder !== null) {
-                        returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name);
+                        returnType = enumBuilder.toInstance(typeBuilder)
                     }
                     (typeProvider as TypeProviderImpl).putReferencedType(leaf.path, returnType);
                 } else if (typeDef instanceof UnionType) {
@@ -1293,11 +1327,10 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 if (returnType !== null) {
                     val MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType);
                     processContextRefExtension(leaf, getter, parentModule);
-                    return true;
                 }
             }
         }
-        return false;
+        return returnType;
     }
 
     private def void processContextRefExtension(LeafSchemaNode leaf, MethodSignatureBuilder getter, Module module) {
@@ -1356,25 +1389,6 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return null;
     }
 
-    /**
-     * Converts <code>leaf</code> schema node to property of generated TO
-     * builder.
-     *
-     * @param toBuilder
-     *            generated TO builder to which is <code>leaf</code> added as
-     *            property
-     * @param leaf
-     *            leaf schema node which is added to <code>toBuilder</code> as
-     *            property
-     * @param isReadOnly
-     *            boolean value which says if leaf property is|isn't read only
-     * @return boolean value
-     *         <ul>
-     *         <li>false - if <code>leaf</code>, <code>toBuilder</code> or leaf
-     *         name equals null or if leaf is added by <i>uses</i>.</li>
-     *         <li>true - other cases</li>
-     *         </ul>
-     */
     private def boolean resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf,
         boolean isReadOnly, Module module) {
         if ((leaf !== null) && (toBuilder !== null)) {
@@ -1401,22 +1415,49 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 } else {
                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
                 }
-
-                if (returnType !== null) {
-                    val propBuilder = toBuilder.addProperty(parseToValidParamName(leafName));
-                    propBuilder.setReadOnly(isReadOnly);
-                    propBuilder.setReturnType(returnType);
-                    propBuilder.setComment(leafDesc);
-                    toBuilder.addEqualsIdentity(propBuilder);
-                    toBuilder.addHashIdentity(propBuilder);
-                    toBuilder.addToStringProperty(propBuilder);
-                    return true;
-                }
+                return resolveLeafSchemaNodeAsProperty(toBuilder, leaf, returnType, isReadOnly)
             }
         }
         return false;
     }
 
+    /**
+     * Converts <code>leaf</code> schema node to property of generated TO
+     * builder.
+     *
+     * @param toBuilder
+     *            generated TO builder to which is <code>leaf</code> added as
+     *            property
+     * @param leaf
+     *            leaf schema node which is added to <code>toBuilder</code> as
+     *            property
+     * @param returnType property type
+     * @param isReadOnly
+     *            boolean value which says if leaf property is|isn't read only
+     * @return boolean value
+     *         <ul>
+     *         <li>false - if <code>leaf</code>, <code>toBuilder</code> or leaf
+     *         name equals null or if leaf is added by <i>uses</i>.</li>
+     *         <li>true - other cases</li>
+     *         </ul>
+     */
+    private def resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf, Type returnType,
+        boolean isReadOnly) {
+        if (returnType == null) {
+            return false;
+        }
+        val leafName = leaf.QName.localName
+        val leafDesc = leaf.description
+        val propBuilder = toBuilder.addProperty(parseToValidParamName(leafName));
+        propBuilder.setReadOnly(isReadOnly);
+        propBuilder.setReturnType(returnType);
+        propBuilder.setComment(leafDesc);
+        toBuilder.addEqualsIdentity(propBuilder);
+        toBuilder.addHashIdentity(propBuilder);
+        toBuilder.addToStringProperty(propBuilder);
+        return true;
+    }
+
     /**
      * Converts <code>node</code> leaf list schema node to getter method of
      * <code>typeBuilder</code>.
@@ -1475,7 +1516,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
     private def Type createReturnTypeForUnion(GeneratedTOBuilder genTOBuilder, TypeDefinition<?> typeDef,
         GeneratedTypeBuilder typeBuilder, Module parentModule) {
-        val Type returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
+        val GeneratedTOBuilderImpl returnType = new GeneratedTOBuilderImpl(genTOBuilder.packageName, genTOBuilder.name)
         genTOBuilder.setTypedef(true);
         genTOBuilder.setIsUnion(true);
         (typeProvider as TypeProviderImpl).addUnitsToGenTO(genTOBuilder, typeDef.getUnits());
@@ -1497,7 +1538,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
         } else {
             types.add(unionBuilder.toInstance)
         }
-        return returnType
+        return returnType.toInstance
     }
 
     private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) {
@@ -1529,7 +1570,6 @@ public class BindingGeneratorImpl implements BindingGenerator {
     private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode,
         Type parent) {
         val it = addRawInterfaceDefinition(packageName, schemaNode, "");
-        qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,schemaNode.QName);
         if (parent === null) {
             addImplementsType(DATA_OBJECT);
         } else {
@@ -1601,6 +1641,8 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         //FIXME: Validation of name conflict
         val newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);
+        qnameConstant(newType,BindingMapping.QNAME_STATIC_FIELD_NAME,schemaNode.QName);
+        newType.addComment(schemaNode.getDescription());
         if (!genTypeBuilders.containsKey(packageName)) {
             val Map<String, GeneratedTypeBuilder> builders = new HashMap();
             builders.put(genTypeName, newType);
@@ -1615,9 +1657,9 @@ public class BindingGeneratorImpl implements BindingGenerator {
     }
 
     /**
-     * Creates the name of the getter method from <code>methodName</code>.
+     * Creates the name of the getter method name from <code>localName</code>.
      *
-     * @param methodName
+     * @param localName
      *            string with the name of the getter method
      * @param returnType return type
      * @return string with the name of the getter method for
@@ -1694,9 +1736,13 @@ public class BindingGeneratorImpl implements BindingGenerator {
         if (schemaNode instanceof LeafSchemaNode) {
             val leaf = schemaNode as LeafSchemaNode;
             val leafName = leaf.QName.localName;
-            resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
+            val Type type = resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
             if (listKeys.contains(leafName)) {
-                resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true, module)
+                if (type == null) {
+                    resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true, module)
+                } else {
+                    resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, type, true)
+                }
             }
         } else if (!schemaNode.addedByUses) {
             if (schemaNode instanceof LeafListSchemaNode) {
@@ -1854,6 +1900,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                         "Grouping " + usesNode.groupingPath + "is not resolved for " + builder.name);
                 }
                 builder.addImplementsType(genType);
+                builder.addComment(genType.getComment());
             }
         }
         return builder;