Bug 2287 - TypeProviderImpl retains empty HashMaps
[yangtools.git] / code-generator / binding-type-provider / src / main / java / org / opendaylight / yangtools / sal / binding / yang / types / TypeProviderImpl.java
index cf23c844de29cfe5e5ea5d2ab36905f8a7dfb3ce..11edd05925046b52f6bd309ca86d1b897c74f035 100644 (file)
@@ -9,11 +9,13 @@ package org.opendaylight.yangtools.sal.binding.yang.types;
 
 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.moduleNamespaceToPackageName;
 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToValidParamName;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+import com.google.common.io.BaseEncoding;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -31,7 +33,6 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
 import org.apache.commons.lang3.StringEscapeUtils;
 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
 import org.opendaylight.yangtools.binding.generator.util.TypeConstants;
@@ -90,10 +91,6 @@ import org.opendaylight.yangtools.yang.model.util.Uint64;
 import org.opendaylight.yangtools.yang.model.util.Uint8;
 import org.opendaylight.yangtools.yang.model.util.UnionType;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-import com.google.common.io.BaseEncoding;
-
 public final class TypeProviderImpl implements TypeProvider {
     private static final Pattern NUMBERS_PATTERN = Pattern.compile("[0-9]+\\z");
 
@@ -192,7 +189,7 @@ public final class TypeProviderImpl implements TypeProvider {
     @Override
     public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
             final Restrictions r) {
-        Type returnType = null;
+        Type returnType;
         Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
         Preconditions.checkArgument(typeDefinition.getQName() != null,
                 "Type Definition cannot have non specified QName (QName cannot be NULL!)");
@@ -219,16 +216,10 @@ public final class TypeProviderImpl implements TypeProvider {
                         .getLocalName());
             }
         }
-        // TODO: add throw exception when we will be able to resolve ALL yang
-        // types!
-        // if (returnType == null) {
-        // throw new IllegalArgumentException("Type Provider can't resolve " +
-        // "type for specified Type Definition " + typedefName);
-        // }
         return returnType;
     }
 
-    private GeneratedTransferObject shadedTOWithRestrictions(GeneratedTransferObject gto, Restrictions r) {
+    private GeneratedTransferObject shadedTOWithRestrictions(final GeneratedTransferObject gto, final Restrictions r) {
         GeneratedTOBuilder gtob = new GeneratedTOBuilderImpl(gto.getPackageName(), gto.getName());
         GeneratedTransferObject parent = gto.getSuperType();
         if (parent != null) {
@@ -279,8 +270,7 @@ public final class TypeProviderImpl implements TypeProvider {
     private Type javaTypeForExtendedType(final TypeDefinition<?> typeDefinition) {
         final String typedefName = typeDefinition.getQName().getLocalName();
         final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
-        Type returnType = null;
-        returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition);
+        Type returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition);
         if (returnType == null) {
             if (baseTypeDef instanceof EnumTypeDefinition) {
                 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef;
@@ -302,12 +292,6 @@ public final class TypeProviderImpl implements TypeProvider {
             }
         }
         return returnType;
-        // TODO: add throw exception when we will be able to resolve ALL yang
-        // types!
-        // if (returnType == null) {
-        // throw new IllegalArgumentException("Type Provider can't resolve " +
-        // "type for specified Type Definition " + typedefName);
-        // }
     }
 
     /**
@@ -637,7 +621,7 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     private void resolveTypeDefsFromContext() {
         final Set<Module> modules = schemaContext.getModules();
-        Preconditions.checkArgument(modules != null, "Sef of Modules cannot be NULL!");
+        Preconditions.checkArgument(modules != null, "Set of Modules cannot be NULL!");
         final Module[] modulesArray = new Module[modules.size()];
         int i = 0;
         for (Module modul : modules) {
@@ -651,8 +635,7 @@ public final class TypeProviderImpl implements TypeProvider {
             if (dateTypeMap == null) {
                 dateTypeMap = new HashMap<>();
             }
-            final Map<String, Type> typeMap = new HashMap<>();
-            dateTypeMap.put(module.getRevision(), typeMap);
+            dateTypeMap.put(module.getRevision(), Collections.<String, Type>emptyMap());
             genTypeDefsContextMap.put(module.getName(), dateTypeMap);
         }
 
@@ -678,7 +661,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *
      * @param basePackageName
      *            string with name of package to which the module belongs
-     * @param moduleName
+     * @param module
      *            string with the name of the module for to which the
      *            <code>typedef</code> belongs
      * @param typedef
@@ -747,8 +730,12 @@ public final class TypeProviderImpl implements TypeProvider {
                 }
                 if (returnType != null) {
                     final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(moduleName);
-                    final Map<String, Type> typeMap = modulesByDate.get(moduleRevision);
+                    Map<String, Type> typeMap = modulesByDate.get(moduleRevision);
                     if (typeMap != null) {
+                        if (typeMap.isEmpty()) {
+                            typeMap = new HashMap<>(4);
+                            modulesByDate.put(moduleRevision, typeMap);
+                        }
                         typeMap.put(typedefName, returnType);
                     }
                     return returnType;
@@ -810,15 +797,17 @@ public final class TypeProviderImpl implements TypeProvider {
         final List<GeneratedTOBuilder> genTOBuilders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
                 typedef, typeDefName, parentNode);
         GeneratedTOBuilder resultTOBuilder = null;
-        if (!genTOBuilders.isEmpty()) {
-            resultTOBuilder = genTOBuilders.remove(0);
-            for (GeneratedTOBuilder genTOBuilder : genTOBuilders) {
-                resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
-            }
+        if (genTOBuilders.isEmpty()) {
+            throw new IllegalStateException("No GeneratedTOBuilder objects generated from union " + typedef);
+        }
+
+        resultTOBuilder = genTOBuilders.remove(0);
+        for (GeneratedTOBuilder genTOBuilder : genTOBuilders) {
+            resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
         }
 
         final GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");
-        genPropBuilder.setReturnType(Types.primitiveType("char[]", null));
+        genPropBuilder.setReturnType(Types.CHAR_ARRAY);
         resultTOBuilder.addEqualsIdentity(genPropBuilder);
         resultTOBuilder.addHashIdentity(genPropBuilder);
         resultTOBuilder.addToStringProperty(genPropBuilder);
@@ -904,7 +893,8 @@ public final class TypeProviderImpl implements TypeProvider {
      *
      * In this case the new generated TO is created for union subtype (recursive
      * call of method
-     * {@link #provideGeneratedTOBuildersForUnionTypeDef(String, TypeDefinition, String)
+     * {@link #provideGeneratedTOBuildersForUnionTypeDef(String, UnionTypeDefinition,
+     * String, SchemaNode)}
      * provideGeneratedTOBuilderForUnionTypeDef} and in parent TO builder
      * <code>parentUnionGenTOBuilder</code> is created property which type is
      * equal to new generated TO.
@@ -927,8 +917,7 @@ public final class TypeProviderImpl implements TypeProvider {
                 basePackageName, unionSubtype, newTOBuilderName, parentNode);
 
         final GeneratedPropertyBuilder propertyBuilder;
-        propertyBuilder = parentUnionGenTOBuilder.addProperty(BindingGeneratorUtil
-                .parseToValidParamName(newTOBuilderName));
+        propertyBuilder = parentUnionGenTOBuilder.addProperty(BindingMapping.getPropertyName(newTOBuilderName));
         propertyBuilder.setReturnType(subUnionGenTOBUilders.get(0));
         parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder);
         parentUnionGenTOBuilder.addToStringProperty(propertyBuilder);
@@ -949,10 +938,11 @@ public final class TypeProviderImpl implements TypeProvider {
      * @param unionSubtype
      *            type definition of the <code>ExtendedType</code> type which
      *            represents union subtype
-     * @param unionTypeName
-     *            string with the name for <code>unionSubtype</code>
      * @param regularExpressions
      *            list of strings with the regular expressions
+     * @param parentNode
+     *            parent Schema Node for Extended Subtype
+     *
      */
     private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
             final ExtendedType unionSubtype, final List<String> regularExpressions, final SchemaNode parentNode) {
@@ -1037,7 +1027,7 @@ public final class TypeProviderImpl implements TypeProvider {
             final String propertyName) {
         if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) {
             final GeneratedPropertyBuilder propBuilder = unionGenTransObject
-                    .addProperty(parseToValidParamName(propertyName));
+                    .addProperty(BindingMapping.getPropertyName(propertyName));
             propBuilder.setReturnType(type);
 
             unionGenTransObject.addEqualsIdentity(propBuilder);
@@ -1062,7 +1052,7 @@ public final class TypeProviderImpl implements TypeProvider {
         final String packageName = packageNameForGeneratedType(basePackageName, typedef.getPath());
         final String typeDefTOName = typedef.getQName().getLocalName();
 
-        if ((packageName != null) && (typedef != null) && (typeDefTOName != null)) {
+        if ((packageName != null) && (typeDefTOName != null)) {
             final String genTOName = BindingMapping.getClassName(typeDefTOName);
             final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTOName);
 
@@ -1112,12 +1102,13 @@ public final class TypeProviderImpl implements TypeProvider {
             genTOBuilder.setReference(typeDef.getReference());
             genTOBuilder.setSchemaPath(typeDef.getPath().getPathFromRoot());
             genTOBuilder.setModuleName(moduleName);
+            genTOBuilder.setBaseType(typeDef);
 
             final List<Bit> bitList = bitsTypeDefinition.getBits();
             GeneratedPropertyBuilder genPropertyBuilder;
             for (final Bit bit : bitList) {
                 String name = bit.getName();
-                genPropertyBuilder = genTOBuilder.addProperty(parseToValidParamName(name));
+                genPropertyBuilder = genTOBuilder.addProperty(BindingMapping.getPropertyName(name));
                 genPropertyBuilder.setReadOnly(true);
                 genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
 
@@ -1200,12 +1191,14 @@ public final class TypeProviderImpl implements TypeProvider {
      * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap} to
      * be possible set it as extended type for the returning generated TO.
      *
+     * @param typedef
+     *            Type Definition
      * @param innerExtendedType
      *            extended type which is part of some other extended type
      * @param basePackageName
      *            string with the package name of the module
-     * @param typedefName
-     *            string with the name for the generated TO
+     * @param moduleName
+     *            Module Name
      * @return generated TO which extends generated TO for
      *         <code>innerExtendedType</code>
      * @throws IllegalArgumentException
@@ -1299,10 +1292,10 @@ public final class TypeProviderImpl implements TypeProvider {
             }
             typeDefinitionsConcreteDepth.add(unsortedTypeDefinition);
         }
-        // keys are in ascending order
-        Set<Integer> depths = typeDefinitionsDepths.keySet();
-        for (Integer depth : depths) {
-            sortedTypeDefinition.addAll(typeDefinitionsDepths.get(depth));
+
+        // SortedMap guarantees order corresponding to keys in ascending order
+        for (List<TypeDefinition<?>> v : typeDefinitionsDepths.values()) {
+            sortedTypeDefinition.addAll(v);
         }
 
         return sortedTypeDefinition;
@@ -1393,13 +1386,13 @@ public final class TypeProviderImpl implements TypeProvider {
             Iterator<QName> path = node.getPath().getPathFromRoot().iterator();
             path.next();
             if (!(path.hasNext())) {
-                parentName = BindingMapping.getClassName((parent).getName()) + "Data";
+                parentName = BindingMapping.getClassName(parent.getName()) + "Data";
                 String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parent);
                 className = basePackageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName());
             } else {
                 String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parent);
                 String packageName = packageNameForGeneratedType(basePackageName, type.getPath());
-                parentName = BindingMapping.getClassName(((SchemaNode) parent).getQName());
+                parentName = BindingMapping.getClassName(parent.getName());
                 className = packageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName());
             }
             result = bitsToDef((BitsTypeDefinition) base, className, defaultValue, type instanceof ExtendedType);
@@ -1440,7 +1433,7 @@ public final class TypeProviderImpl implements TypeProvider {
         } else if (base instanceof Int64) {
             result = typeToDef(Long.class, defaultValue);
         } else if (base instanceof LeafrefTypeDefinition) {
-            result = leafrefToDef(node, (LeafrefTypeDefinition) base);
+            result = leafrefToDef(node, (LeafrefTypeDefinition) base, defaultValue);
         } else if (base instanceof StringTypeDefinition) {
             result = "\"" + defaultValue + "\"";
         } else if (base instanceof Uint8) {
@@ -1528,7 +1521,7 @@ public final class TypeProviderImpl implements TypeProvider {
         return schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
     }
 
-    private String leafrefToDef(final LeafSchemaNode parentNode, final LeafrefTypeDefinition leafrefType) {
+    private String leafrefToDef(final LeafSchemaNode parentNode, final LeafrefTypeDefinition leafrefType, final String defaultValue) {
         Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!");
         Preconditions.checkArgument(leafrefType.getPathStatement() != null,
                 "The Path Statement for Leafref Type Definition cannot be NULL!");
@@ -1546,7 +1539,7 @@ public final class TypeProviderImpl implements TypeProvider {
                     } else {
                         dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
                     }
-                    String result = getTypeDefaultConstruction((LeafSchemaNode) dataNode, parentNode.getDefault());
+                    String result = getTypeDefaultConstruction((LeafSchemaNode) dataNode, defaultValue);
                     return result;
                 }
             } else {
@@ -1632,7 +1625,7 @@ public final class TypeProviderImpl implements TypeProvider {
 
     @Override
     public String getParamNameFromType(final TypeDefinition<?> type) {
-        return BindingGeneratorUtil.parseToValidParamName(type.getQName().getLocalName());
+        return BindingMapping.getPropertyName(type.getQName().getLocalName());
     }
 
 }