Bug 2859: Key generation when anonymous Enum was used. 39/16639/3
authorTony Tkacik <ttkacik@cisco.com>
Mon, 16 Mar 2015 13:31:50 +0000 (14:31 +0100)
committerTony Tkacik <ttkacik@cisco.com>
Tue, 17 Mar 2015 18:12:49 +0000 (18:12 +0000)
Binding list key was generated with incorrect type,
when anonymous enumeration was defined in leaf in grouping
and that leaf was used for list.

Change-Id: Idcb114be49280f77af8054d8d83c5d8e6f453665
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/ModuleContext.java

index 8403a44a82689460f58d7bee6fb9f8cd973c2830..66f3bc042408f6a475a772aa41ef78541aabbbab 100644 (file)
@@ -25,6 +25,7 @@ import static org.opendaylight.yangtools.binding.generator.util.Types.typeForCla
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findNodeInSchemaContext;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
+
 import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
 import com.google.common.collect.Iterables;
@@ -94,8 +95,10 @@ 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.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.BaseTypes;
 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
 import org.opendaylight.yangtools.yang.model.util.UnionType;
 import org.opendaylight.yangtools.yang.parser.builder.util.Comparators;
 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
@@ -727,17 +730,21 @@ public class BindingGeneratorImpl implements BindingGenerator {
      *            builder
      * @param typeBuilder
      *            GeneratedTypeBuilder to which will be enum builder assigned
+     * @param module
+     *            Module in which type should be generated
      * @return enumeration builder which contains data from
      *         <code>enumTypeDef</code>
      */
     private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final QName enumName,
-            final GeneratedTypeBuilder typeBuilder) {
+            final GeneratedTypeBuilder typeBuilder, Module module) {
         if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null)
                 && (enumTypeDef.getQName().getLocalName() != null)) {
             final String enumerationName = BindingMapping.getClassName(enumName);
             final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
             enumBuilder.setDescription(enumTypeDef.getDescription());
             enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
+            ModuleContext ctx = genCtx.get(module);
+            ctx.addInnerTypedefType(enumTypeDef.getPath(), enumBuilder);
             return enumBuilder;
         }
         return null;
@@ -1109,9 +1116,9 @@ public class BindingGeneratorImpl implements BindingGenerator {
             final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf, final Module module) {
         if (node != null && typeBuilder != null) {
             if (node instanceof LeafSchemaNode) {
-                resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) node);
+                resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) node, module);
             } else if (node instanceof LeafListSchemaNode) {
-                resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) node);
+                resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) node,module);
             } else if (node instanceof ContainerSchemaNode) {
                 containerToGenType(module, basePackageName, typeBuilder, childOf, (ContainerSchemaNode) node);
             } else if (node instanceof ListSchemaNode) {
@@ -1332,6 +1339,8 @@ public class BindingGeneratorImpl implements BindingGenerator {
      * @param leaf
      *            leaf schema node which is mapped as getter method which is
      *            added to <code>typeBuilder</code>
+     * @param module
+     *            Module in which type was defined
      * @return boolean value
      *         <ul>
      *         <li>false - if <code>leaf</code> or <code>typeBuilder</code> are
@@ -1339,7 +1348,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
      *         <li>true - in other cases</li>
      *         </ul>
      */
-    private Type resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
+    private Type resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf, Module module) {
         Type returnType = null;
         if ((leaf != null) && (typeBuilder != null)) {
             final String leafName = leaf.getQName().getLocalName();
@@ -1357,7 +1366,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
                     final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef;
                     final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.getQName(),
-                            typeBuilder);
+                            typeBuilder,module);
 
                     if (enumBuilder != null) {
                         returnType = enumBuilder.toInstance(typeBuilder);
@@ -1454,23 +1463,27 @@ public class BindingGeneratorImpl implements BindingGenerator {
             if (leafDesc == null) {
                 leafDesc = "";
             }
-
-            if (leafName != null) {
-                Type returnType = null;
-                final TypeDefinition<?> typeDef = leaf.getType();
-                if (typeDef instanceof UnionTypeDefinition) {
-                    // GeneratedType for this type definition should be already
-                    // created
-                    final QName qname = typeDef.getQName();
-                    final Module unionModule = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(),
-                            qname.getRevision());
-                    final ModuleContext mc = genCtx.get(unionModule);
-                    returnType = mc.getTypedefs().get(typeDef.getPath());
-                } else {
-                    returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
-                }
-                return resolveLeafSchemaNodeAsProperty(toBuilder, leaf, returnType, isReadOnly);
+            Type returnType = null;
+            final TypeDefinition<?> typeDef = leaf.getType();
+            if (typeDef instanceof UnionTypeDefinition) {
+                // GeneratedType for this type definition should be already
+                // created
+                final QName qname = typeDef.getQName();
+                final Module unionModule = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(),
+                        qname.getRevision());
+                final ModuleContext mc = genCtx.get(unionModule);
+                returnType = mc.getTypedefs().get(typeDef.getPath());
+            } else if (typeDef instanceof EnumTypeDefinition && BaseTypes.ENUMERATION_QNAME.equals(typeDef.getQName())) {
+                // 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());
+                returnType = genCtx.get(enumModule).getInnerType(originalLeaf.getType().getPath());
+            } else {
+                returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
             }
+            return resolveLeafSchemaNodeAsProperty(toBuilder, leaf, returnType, isReadOnly);
         }
         return false;
     }
@@ -1523,6 +1536,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
      * @param node
      *            leaf list schema node which is added to
      *            <code>typeBuilder</code> as getter method
+     * @param module
      * @return boolean value
      *         <ul>
      *         <li>true - if <code>node</code>, <code>typeBuilder</code>,
@@ -1530,7 +1544,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
      *         <li>false - other cases</li>
      *         </ul>
      */
-    private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) {
+    private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node, Module module) {
         if ((node != null) && (typeBuilder != null)) {
             final QName nodeName = node.getQName();
 
@@ -1543,7 +1557,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node);
                     final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef;
                     final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName,
-                            typeBuilder);
+                            typeBuilder,module);
                     returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
                     ((TypeProviderImpl) typeProvider).putReferencedType(node.getPath(), returnType);
                 } else if (typeDef instanceof UnionType) {
@@ -1828,7 +1842,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
         if (schemaNode instanceof LeafSchemaNode) {
             final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode;
             final String leafName = leaf.getQName().getLocalName();
-            final Type type = resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
+            final Type type = resolveLeafSchemaNodeAsMethod(typeBuilder, leaf,module);
             if (listKeys.contains(leafName)) {
                 if (type == null) {
                     resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true, module);
@@ -1838,7 +1852,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
             }
         } else if (!schemaNode.isAddedByUses()) {
             if (schemaNode instanceof LeafListSchemaNode) {
-                resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);
+                resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode, module);
             } else if (schemaNode instanceof ContainerSchemaNode) {
                 containerToGenType(module, basePackageName, typeBuilder, typeBuilder, (ContainerSchemaNode) schemaNode);
             } else if (schemaNode instanceof ChoiceSchemaNode) {
index 8fd13c3cf999807ae8288205505f76a50a139de4..aac2135c7d8d7023e32c1543c151027222e23c58 100644 (file)
@@ -21,6 +21,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder;
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -50,6 +51,7 @@ public final class ModuleContext {
     private final BiMap<Type,ChoiceCaseNode> caseTypeToSchema = HashBiMap.create();
 
     private final Multimap<Type, Type> augmentableToAugmentations = HashMultimap.create();
+    private final Map<SchemaPath, Type> innerTypes = new HashMap<>();
 
     List<Type> getGeneratedTypes() {
         List<Type> result = new ArrayList<>();
@@ -215,4 +217,18 @@ public final class ModuleContext {
         typeToSchema.put(type, typedef);
     }
 
+    /**
+     * Adds mapping between schema path and inner enum.
+     *
+     * @param path
+     * @param enumBuilder
+     */
+    void addInnerTypedefType(SchemaPath path, EnumBuilder enumBuilder) {
+        innerTypes.put(path, enumBuilder);
+    }
+
+    public Type getInnerType(SchemaPath path) {
+        return innerTypes.get(path);
+    }
+
 }