Bug 5882: Wrong placement of deprecated annotation
[mdsal.git] / binding / mdsal-binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / yang / types / TypeProviderImpl.java
index d568c947dd34a9893b7639c723f6607c3e47c21f..405a71d922a289b1fc3c174e85c9b0641ec4bd9d 100644 (file)
@@ -7,9 +7,11 @@
  */
 package org.opendaylight.yangtools.sal.binding.yang.types;
 
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.encodeAngleBrackets;
 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.base.Strings;
 import com.google.common.collect.ImmutableList;
@@ -78,20 +80,13 @@ import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.EnumerationType;
+import org.opendaylight.yangtools.yang.model.util.Decimal64;
 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
-import org.opendaylight.yangtools.yang.model.util.Int16;
-import org.opendaylight.yangtools.yang.model.util.Int32;
-import org.opendaylight.yangtools.yang.model.util.Int64;
-import org.opendaylight.yangtools.yang.model.util.Int8;
 import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
-import org.opendaylight.yangtools.yang.model.util.StringType;
-import org.opendaylight.yangtools.yang.model.util.Uint16;
-import org.opendaylight.yangtools.yang.model.util.Uint32;
-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 org.opendaylight.yangtools.yang.model.util.type.BaseTypes;
+import org.opendaylight.yangtools.yang.model.util.type.CompatUtils;
 import org.opendaylight.yangtools.yang.parser.util.YangValidationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -193,39 +188,46 @@ public final class TypeProviderImpl implements TypeProvider {
      *             </ul>
      */
     @Override
-    public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
-            final Restrictions r) {
+    public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode, final Restrictions r) {
         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!)");
         String typedefName = typeDefinition.getQName().getLocalName();
         Preconditions.checkArgument(typedefName != null, "Type Definitions Local Name cannot be NULL!");
 
-        // Deal with leafrefs/identityrefs first
-        Type returnType = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode);
-        if (returnType != null) {
-            return returnType;
-        }
-
+        // Deal with base types
         if (typeDefinition.getBaseType() == null) {
-            // Now deal with base types
-            returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(typeDefinition.getQName()
-                .getLocalName());
-            if (returnType == null) {
+            // We have to deal with differing handling of decimal64. The old parser used a fixed Decimal64 type
+            // and generated an enclosing ExtendedType to hold any range constraints. The new parser instantiates
+            // a base type which holds these constraints -- and the class is not a Decimal64.
+            if (typeDefinition instanceof DecimalTypeDefinition && !(typeDefinition instanceof Decimal64)) {
+                final Type ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, parentNode, r);
+                if (ret != null) {
+                    return ret;
+                }
+            }
+
+            // Deal with leafrefs/identityrefs
+            Type ret = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode);
+            if (ret != null) {
+                return ret;
+            }
+
+            // FIXME: it looks as though we could be using the same codepath as above...
+            ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(typeDefinition.getQName().getLocalName());
+            if (ret == null) {
                 LOG.debug("Failed to resolve Java type for {}", typeDefinition);
             }
 
-            // FIXME: what about base types with restrictions?
-            return returnType;
+            return ret;
         }
 
-        returnType = javaTypeForExtendedType(typeDefinition);
+        Type returnType = javaTypeForExtendedType(typeDefinition);
         if (r != null && returnType instanceof GeneratedTransferObject) {
             GeneratedTransferObject gto = (GeneratedTransferObject) returnType;
             Module module = findParentModule(schemaContext, parentNode);
             String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule());
-            String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName,
-                typeDefinition.getPath());
+            String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typeDefinition.getPath());
             String genTOName = BindingMapping.getClassName(typedefName);
             String name = packageName + "." + genTOName;
             if (!(returnType.getFullyQualifiedName().equals(name))) {
@@ -408,8 +410,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             <li>if name of <code>typeDefinition</code></li>
      *             </ul>
      */
-    public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition,
-            final SchemaNode parentNode) {
+    public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode) {
         Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
         if (typeDefinition.getQName() == null) {
             throw new IllegalArgumentException(
@@ -484,29 +485,30 @@ public final class TypeProviderImpl implements TypeProvider {
         if (strXPath != null) {
             if (strXPath.indexOf('[') == -1) {
                 final Module module = findParentModule(schemaContext, parentNode);
-                if (module != null) {
-                    final SchemaNode dataNode;
-                    if (xpath.isAbsolute()) {
-                        dataNode = findDataSchemaNode(schemaContext, module, xpath);
-                    } else {
-                        dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
-                    }
+                Preconditions.checkArgument(module != null, "Failed to find module for parent %s", parentNode);
 
-                    if (leafContainsEnumDefinition(dataNode)) {
-                        returnType = referencedTypes.get(dataNode.getPath());
-                    } else if (leafListContainsEnumDefinition(dataNode)) {
-                        returnType = Types.listTypeFor(referencedTypes.get(dataNode.getPath()));
-                    } else {
-                        returnType = resolveTypeFromDataSchemaNode(dataNode);
-                    }
+                final SchemaNode dataNode;
+                if (xpath.isAbsolute()) {
+                    dataNode = findDataSchemaNode(schemaContext, module, xpath);
+                } else {
+                    dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
+                }
+                Preconditions.checkArgument(dataNode != null, "Failed to find leafref target: %s in module %s (%s)",
+                        strXPath, this.getParentModule(parentNode).getName(), parentNode.getQName().getModule());
+
+                if (leafContainsEnumDefinition(dataNode)) {
+                    returnType = referencedTypes.get(dataNode.getPath());
+                } else if (leafListContainsEnumDefinition(dataNode)) {
+                    returnType = Types.listTypeFor(referencedTypes.get(dataNode.getPath()));
+                } else {
+                    returnType = resolveTypeFromDataSchemaNode(dataNode);
                 }
             } else {
                 returnType = Types.typeForClass(Object.class);
             }
         }
-        if (returnType == null) {
-            throw new IllegalArgumentException("Failed to find leafref target: " + strXPath);
-        }
+        Preconditions.checkArgument(returnType != null, "Failed to find leafref target: %s in module %s (%s)",
+                strXPath, this.getParentModule(parentNode).getName(), parentNode.getQName().getModule(), this);
         return returnType;
     }
 
@@ -526,7 +528,7 @@ public final class TypeProviderImpl implements TypeProvider {
     private static boolean leafContainsEnumDefinition(final SchemaNode dataNode) {
         if (dataNode instanceof LeafSchemaNode) {
             final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
-            if (leaf.getType() instanceof EnumTypeDefinition) {
+            if (CompatUtils.compatLeafType(leaf) instanceof EnumTypeDefinition) {
                 return true;
             }
         }
@@ -576,8 +578,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             <li>if name of <code>enumTypeDef</code> equal null</li>
      *             </ul>
      */
-    private Enumeration provideTypeForEnum(final EnumTypeDefinition enumTypeDef, final String enumName,
-            final SchemaNode parentNode) {
+    private Enumeration provideTypeForEnum(final EnumTypeDefinition enumTypeDef, final String enumName, final SchemaNode parentNode) {
         Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!");
         Preconditions.checkArgument(enumTypeDef.getValues() != null,
                 "EnumTypeDefinition MUST contain at least ONE value definition!");
@@ -591,7 +592,8 @@ public final class TypeProviderImpl implements TypeProvider {
         final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule());
 
         final EnumerationBuilderImpl enumBuilder = new EnumerationBuilderImpl(basePackageName, enumerationName);
-        enumBuilder.setDescription(enumTypeDef.getDescription());
+        final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription());
+        enumBuilder.setDescription(enumTypedefDescription);
         enumBuilder.setReference(enumTypeDef.getReference());
         enumBuilder.setModuleName(module.getName());
         enumBuilder.setSchemaPath(enumTypeDef.getPath().getPathFromRoot());
@@ -622,8 +624,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             </ul>
      *
      */
-    private static Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef, final String enumName,
-            final GeneratedTypeBuilderBase<?> typeBuilder) {
+    private static Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef, final String enumName, final GeneratedTypeBuilderBase<?> typeBuilder) {
         Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!");
         Preconditions.checkArgument(enumTypeDef.getValues() != null,
                 "EnumTypeDefinition MUST contain at least ONE value definition!");
@@ -635,7 +636,8 @@ public final class TypeProviderImpl implements TypeProvider {
         final String enumerationName = BindingMapping.getClassName(enumName);
 
         final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
-        enumBuilder.setDescription(enumTypeDef.getDescription());
+        final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription());
+        enumBuilder.setDescription(enumTypedefDescription);
         enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
         return enumBuilder.toInstance(enumBuilder);
     }
@@ -652,7 +654,8 @@ public final class TypeProviderImpl implements TypeProvider {
         if (dataNode != null) {
             if (dataNode instanceof LeafSchemaNode) {
                 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
-                returnType = javaTypeForSchemaDefinitionType(leaf.getType(), leaf);
+                final TypeDefinition<?> type = CompatUtils.compatLeafType(leaf);
+                returnType = javaTypeForSchemaDefinitionType(type, leaf);
             } else if (dataNode instanceof LeafListSchemaNode) {
                 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
                 returnType = javaTypeForSchemaDefinitionType(leafList.getType(), leafList);
@@ -726,8 +729,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *         <code>modulName</code> or <code>typedef</code> or Q name of
      *         <code>typedef</code> equals <code>null</code>
      */
-    private Type typedefToGeneratedType(final String basePackageName, final Module module,
-            final TypeDefinition<?> typedef) {
+    private Type typedefToGeneratedType(final String basePackageName, final Module module, final TypeDefinition<?> typedef) {
         final String moduleName = module.getName();
         final Date moduleRevision = module.getRevision();
         if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) {
@@ -737,8 +739,7 @@ public final class TypeProviderImpl implements TypeProvider {
                     && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) {
                 Type returnType = null;
                 if (innerTypeDefinition.getBaseType() != null) {
-                    returnType = provideGeneratedTOFromExtendedType(typedef, innerTypeDefinition, basePackageName,
-                            module.getName());
+                    returnType = provideGeneratedTOFromExtendedType(typedef, innerTypeDefinition, basePackageName, module.getName());
                 } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
                     final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName,
                             (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef);
@@ -809,8 +810,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *            JAVA <code>Type</code> to which is <code>typedef</code> mapped
      * @return generated transfer object which represent<code>javaType</code>
      */
-    private static GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition<?> typedef,
-            final Type javaType, final String moduleName) {
+    private static GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition<?> typedef, final Type javaType, final String moduleName) {
         Preconditions.checkNotNull(javaType, "javaType cannot be null");
         final String propertyName = "value";
 
@@ -845,8 +845,7 @@ public final class TypeProviderImpl implements TypeProvider {
      * @return generated TO builder with the list of enclosed generated TO
      *         builders
      */
-    public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName,
-            final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) {
+    public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName, final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) {
         final List<GeneratedTOBuilder> genTOBuilders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
                 typedef, typeDefName, parentNode);
         GeneratedTOBuilder resultTOBuilder = null;
@@ -888,8 +887,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             <li>if Qname of <code>typedef</code> is null</li>
      *             </ul>
      */
-    public List<GeneratedTOBuilder> provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName,
-            final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) {
+    public List<GeneratedTOBuilder> provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName, final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) {
         Preconditions.checkNotNull(basePackageName, "Base Package Name cannot be NULL!");
         Preconditions.checkNotNull(typedef, "Type Definition cannot be NULL!");
         Preconditions.checkNotNull(typedef.getQName(), "Type definition QName cannot be NULL!");
@@ -902,7 +900,8 @@ public final class TypeProviderImpl implements TypeProvider {
         if (typeDefName != null && !typeDefName.isEmpty()) {
             final String typeName = BindingMapping.getClassName(typeDefName);
             unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
-            unionGenTOBuilder.setDescription(typedef.getDescription());
+            final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
+            unionGenTOBuilder.setDescription(typedefDescription);
             unionGenTOBuilder.setReference(typedef.getReference());
             unionGenTOBuilder.setSchemaPath(typedef.getPath().getPathFromRoot());
             unionGenTOBuilder.setModuleName(module.getName());
@@ -915,12 +914,12 @@ public final class TypeProviderImpl implements TypeProvider {
         final List<String> regularExpressions = new ArrayList<String>();
         for (final TypeDefinition<?> unionType : unionTypes) {
             final String unionTypeName = unionType.getQName().getLocalName();
-            if (unionType instanceof UnionType) {
-                generatedTOBuilders.addAll(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionType) unionType,
-                        basePackageName, parentNode));
-            } else if (unionType instanceof ExtendedType) {
-                resolveExtendedSubtypeAsUnion(unionGenTOBuilder, (ExtendedType) unionType, regularExpressions,
+            if (unionType.getBaseType() != null) {
+                resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, regularExpressions,
                         parentNode);
+            } else if (unionType instanceof UnionTypeDefinition) {
+                generatedTOBuilders.addAll(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionTypeDefinition) unionType,
+                        basePackageName, parentNode));
             } else if (unionType instanceof EnumTypeDefinition) {
                 final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType,
                         unionTypeName, unionGenTOBuilder);
@@ -963,8 +962,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *         bigger one due to recursive call of
      *         <code>provideGeneratedTOBuildersForUnionTypeDef</code> method.
      */
-    private List<GeneratedTOBuilder> resolveUnionSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
-            final UnionTypeDefinition unionSubtype, final String basePackageName, final SchemaNode parentNode) {
+    private List<GeneratedTOBuilder> resolveUnionSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder, final UnionTypeDefinition unionSubtype, final String basePackageName, final SchemaNode parentNode) {
         final String newTOBuilderName = provideAvailableNameForGenTOBuilder(parentUnionGenTOBuilder.getName());
         final List<GeneratedTOBuilder> subUnionGenTOBUilders = provideGeneratedTOBuildersForUnionTypeDef(
                 basePackageName, unionSubtype, newTOBuilderName, parentNode);
@@ -997,8 +995,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *            parent Schema Node for Extended Subtype
      *
      */
-    private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
-            final ExtendedType unionSubtype, final List<String> regularExpressions, final SchemaNode parentNode) {
+    private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder, final TypeDefinition<?> unionSubtype, final List<String> regularExpressions, final SchemaNode parentNode) {
         final String unionTypeName = unionSubtype.getQName().getLocalName();
         final Type genTO = findGenTO(unionTypeName, unionSubtype);
         if (genTO != null) {
@@ -1012,7 +1009,7 @@ public final class TypeProviderImpl implements TypeProvider {
                     updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName);
                 }
             }
-            if (baseType instanceof StringType) {
+            if (baseType instanceof StringTypeDefinition) {
                 regularExpressions.addAll(resolveRegExpressionsFromTypedef(unionSubtype));
             }
         }
@@ -1050,10 +1047,8 @@ public final class TypeProviderImpl implements TypeProvider {
      *            generated TO builder which is converted to generated TO and
      *            stored
      */
-    private void storeGenTO(final TypeDefinition<?> newTypeDef, final GeneratedTOBuilder genTOBuilder,
-            final SchemaNode parentNode) {
-        if (!(newTypeDef instanceof UnionType)) {
-
+    private void storeGenTO(final TypeDefinition<?> newTypeDef, final GeneratedTOBuilder genTOBuilder, final SchemaNode parentNode) {
+        if (!(newTypeDef instanceof UnionTypeDefinition)) {
             final Module parentModule = findParentModule(schemaContext, parentNode);
             if (parentModule != null && parentModule.getName() != null) {
                 Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(parentModule.getName());
@@ -1076,8 +1071,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *            string with name of property which should be added to
      *            <code>unionGentransObject</code>
      */
-    private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type,
-            final String propertyName) {
+    private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type, final String propertyName) {
         if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) {
             final GeneratedPropertyBuilder propBuilder = unionGenTransObject
                     .addProperty(BindingMapping.getPropertyName(propertyName));
@@ -1099,8 +1093,7 @@ public final class TypeProviderImpl implements TypeProvider {
      * @return generated TO builder which contains data from
      *         <code>typedef</code> and <code>basePackageName</code>
      */
-    private static GeneratedTOBuilderImpl typedefToTransferObject(final String basePackageName,
-            final TypeDefinition<?> typedef, final String moduleName) {
+    private static GeneratedTOBuilderImpl typedefToTransferObject(final String basePackageName, final TypeDefinition<?> typedef, final String moduleName) {
 
         final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typedef.getPath());
         final String typeDefTOName = typedef.getQName().getLocalName();
@@ -1108,8 +1101,9 @@ public final class TypeProviderImpl implements TypeProvider {
         if ((packageName != null) && (typeDefTOName != null)) {
             final String genTOName = BindingMapping.getClassName(typeDefTOName);
             final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTOName);
+            final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
 
-            newType.setDescription(typedef.getDescription());
+            newType.setDescription(typedefDescription);
             newType.setReference(typedef.getReference());
             newType.setSchemaPath(typedef.getPath().getPathFromRoot());
             newType.setModuleName(moduleName);
@@ -1139,8 +1133,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             <li>if <code>basePackageName</code> equals null</li>
      *             </ul>
      */
-    public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName,
-            final TypeDefinition<?> typeDef, final String typeDefName, final String moduleName) {
+    public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName, final TypeDefinition<?> typeDef, final String typeDefName, final String moduleName) {
 
         Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!");
         Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!");
@@ -1150,8 +1143,9 @@ public final class TypeProviderImpl implements TypeProvider {
 
             final String typeName = BindingMapping.getClassName(typeDefName);
             final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
+            final String typedefDescription = encodeAngleBrackets(typeDef.getDescription());
 
-            genTOBuilder.setDescription(typeDef.getDescription());
+            genTOBuilder.setDescription(typedefDescription);
             genTOBuilder.setReference(typeDef.getReference());
             genTOBuilder.setSchemaPath(typeDef.getPath().getPathFromRoot());
             genTOBuilder.setModuleName(moduleName);
@@ -1192,7 +1186,7 @@ public final class TypeProviderImpl implements TypeProvider {
         final List<PatternConstraint> patternConstraints;
         if (typedef instanceof ExtendedType) {
             final TypeDefinition<?> strTypeDef = baseTypeDefForExtendedType(typedef);
-            if (strTypeDef instanceof StringType) {
+            if (strTypeDef instanceof StringTypeDefinition) {
                 patternConstraints = ((ExtendedType)typedef).getPatternConstraints();
             } else {
                 patternConstraints = ImmutableList.of();
@@ -1270,8 +1264,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             <li>if <code>typedefName</code> equals null</li>
      *             </ul>
      */
-    private GeneratedTransferObject provideGeneratedTOFromExtendedType(final TypeDefinition<?> typedef,
-            final TypeDefinition<?> innerExtendedType, final String basePackageName, final String moduleName) {
+    private GeneratedTransferObject provideGeneratedTOFromExtendedType(final TypeDefinition<?> typedef, final TypeDefinition<?> innerExtendedType, final String basePackageName, final String moduleName) {
         Preconditions.checkArgument(innerExtendedType != null, "Extended type cannot be NULL!");
         Preconditions.checkArgument(basePackageName != null, "String with base package name cannot be NULL!");
 
@@ -1279,8 +1272,9 @@ public final class TypeProviderImpl implements TypeProvider {
         final String classTypedefName = BindingMapping.getClassName(typedefName);
         final String innerTypeDef = innerExtendedType.getQName().getLocalName();
         final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, classTypedefName);
+        final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
 
-        genTOBuilder.setDescription(typedef.getDescription());
+        genTOBuilder.setDescription(typedefDescription);
         genTOBuilder.setReference(typedef.getReference());
         genTOBuilder.setSchemaPath(typedef.getPath().getPathFromRoot());
         genTOBuilder.setModuleName(moduleName);
@@ -1377,13 +1371,16 @@ public final class TypeProviderImpl implements TypeProvider {
         if (typeDefinition == null) {
             return 1;
         }
-        int depth = 1;
         TypeDefinition<?> baseType = typeDefinition.getBaseType();
+        if (baseType == null) {
+            return 1;
+        }
 
-        if (baseType instanceof ExtendedType) {
-            depth = depth + getTypeDefinitionDepth(typeDefinition.getBaseType());
-        } else if (baseType instanceof UnionType) {
-            List<TypeDefinition<?>> childTypeDefinitions = ((UnionType) baseType).getTypes();
+        int depth = 1;
+        if (baseType.getBaseType() != null) {
+            depth = depth + getTypeDefinitionDepth(baseType);
+        } else if (baseType instanceof UnionTypeDefinition) {
+            List<TypeDefinition<?>> childTypeDefinitions = ((UnionTypeDefinition) baseType).getTypes();
             int maxChildDepth = 0;
             int childDepth = 1;
             for (TypeDefinition<?> childTypeDefinition : childTypeDefinitions) {
@@ -1431,7 +1428,7 @@ public final class TypeProviderImpl implements TypeProvider {
     }
 
     public String getTypeDefaultConstruction(final LeafSchemaNode node, final String defaultValue) {
-        TypeDefinition<?> type = node.getType();
+        TypeDefinition<?> type = CompatUtils.compatLeafType(node);
         QName typeQName = type.getQName();
         TypeDefinition<?> base = baseTypeDefForExtendedType(type);
         Preconditions.checkNotNull(type, "Cannot provide default construction for null type of %s", node);
@@ -1458,7 +1455,7 @@ public final class TypeProviderImpl implements TypeProvider {
                 parentName = BindingMapping.getClassName(parent.getName());
                 className = packageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName());
             }
-            result = bitsToDef((BitsTypeDefinition) base, className, defaultValue, type instanceof ExtendedType);
+            result = bitsToDef((BitsTypeDefinition) base, className, defaultValue, type.getBaseType() != null);
         } else if (base instanceof BooleanTypeDefinition) {
             result = typeToDef(Boolean.class, defaultValue);
         } else if (base instanceof DecimalTypeDefinition) {
@@ -1471,7 +1468,7 @@ public final class TypeProviderImpl implements TypeProvider {
             defValArray[0] = first;
             String newDefVal = new String(defValArray);
             String className;
-            if (type instanceof ExtendedType) {
+            if (type.getBaseType() != null) {
                 Module m = getParentModule(type);
                 String basePackageName = BindingMapping.getRootPackageName(m.getQNameModule());
                 String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, type.getPath());
@@ -1487,25 +1484,25 @@ public final class TypeProviderImpl implements TypeProvider {
             throw new UnsupportedOperationException("Cannot get default construction for identityref type");
         } else if (base instanceof InstanceIdentifierTypeDefinition) {
             throw new UnsupportedOperationException("Cannot get default construction for instance-identifier type");
-        } else if (base instanceof Int8) {
+        } else if (BaseTypes.isInt8(base)) {
             result = typeToDef(Byte.class, defaultValue);
-        } else if (base instanceof Int16) {
+        } else if (BaseTypes.isInt16(base)) {
             result = typeToDef(Short.class, defaultValue);
-        } else if (base instanceof Int32) {
+        } else if (BaseTypes.isInt32(base)) {
             result = typeToDef(Integer.class, defaultValue);
-        } else if (base instanceof Int64) {
+        } else if (BaseTypes.isInt64(base)) {
             result = typeToDef(Long.class, defaultValue);
         } else if (base instanceof LeafrefTypeDefinition) {
             result = leafrefToDef(node, (LeafrefTypeDefinition) base, defaultValue);
         } else if (base instanceof StringTypeDefinition) {
             result = "\"" + defaultValue + "\"";
-        } else if (base instanceof Uint8) {
+        } else if (BaseTypes.isUint8(base)) {
             result = typeToDef(Short.class, defaultValue);
-        } else if (base instanceof Uint16) {
+        } else if (BaseTypes.isUint16(base)) {
             result = typeToDef(Integer.class, defaultValue);
-        } else if (base instanceof Uint32) {
+        } else if (BaseTypes.isUint32(base)) {
             result = typeToDef(Long.class, defaultValue);
-        } else if (base instanceof Uint64) {
+        } else if (BaseTypes.isUint64(base)) {
             result = typeToDef(BigInteger.class, defaultValue);
         } else if (base instanceof UnionTypeDefinition) {
             result = unionToDef(node);
@@ -1514,8 +1511,8 @@ public final class TypeProviderImpl implements TypeProvider {
         }
         sb.append(result);
 
-        if (type instanceof ExtendedType && !(base instanceof LeafrefTypeDefinition)
-                && !(base instanceof EnumerationType) && !(base instanceof UnionTypeDefinition)) {
+        if (type.getBaseType() != null && !(base instanceof LeafrefTypeDefinition)
+                && !(base instanceof EnumTypeDefinition) && !(base instanceof UnionTypeDefinition)) {
             Module m = getParentModule(type);
             String basePackageName = BindingMapping.getRootPackageName(m.getQNameModule());
             String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, type.getPath());
@@ -1548,13 +1545,12 @@ public final class TypeProviderImpl implements TypeProvider {
 
     private static final Comparator<Bit> BIT_NAME_COMPARATOR = new Comparator<Bit>() {
         @Override
-        public int compare(final Bit o1, final Bit o2) {
+        public int compare(Bit o1, Bit o2) {
             return o1.getName().compareTo(o2.getName());
         }
     };
 
-    private static String bitsToDef(final BitsTypeDefinition type, final String className, final String defaultValue,
-            final boolean isExt) {
+    private static String bitsToDef(final BitsTypeDefinition type, final String className, final String defaultValue, final boolean isExt) {
         List<Bit> bits = new ArrayList<>(type.getBits());
         Collections.sort(bits, BIT_NAME_COMPARATOR);
         StringBuilder sb = new StringBuilder();
@@ -1616,11 +1612,11 @@ public final class TypeProviderImpl implements TypeProvider {
     }
 
     private String unionToDef(final LeafSchemaNode node) {
+        final TypeDefinition<?> type = CompatUtils.compatLeafType(node);
         String parentName;
         String className;
 
-        if (node.getType() instanceof ExtendedType) {
-            ExtendedType type = (ExtendedType) node.getType();
+        if (type.getBaseType() != null) {
             QName typeQName = type.getQName();
             Module module = null;
             Set<Module> modules = schemaContext.findModuleByNamespace(typeQName.getNamespace());
@@ -1635,7 +1631,7 @@ public final class TypeProviderImpl implements TypeProvider {
                     List<Module> modulesList = new ArrayList<>(modules);
                     Collections.sort(modulesList, new Comparator<Module>() {
                         @Override
-                        public int compare(final Module o1, final Module o2) {
+                        public int compare(Module o1, Module o2) {
                             return o1.getRevision().compareTo(o2.getRevision());
                         }
                     });
@@ -1662,8 +1658,18 @@ public final class TypeProviderImpl implements TypeProvider {
                 Date revision = first.getRevision();
                 Module parentModule = schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
                 String basePackageName = BindingMapping.getRootPackageName(parentModule.getQNameModule());
-                String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName,
-                    node.getType().getPath());
+
+                // Backwards compatibility: Union types used to be instantiated in YANG namespace, which is no longer
+                // the case, as unions are emitted to their correct schema path. Create a proxy instance to meet the
+                // codepath's expectations
+                final SchemaPath typePath;
+                if (type instanceof UnionType) {
+                    typePath = type.getPath();
+                } else {
+                    typePath = UnionType.create(((UnionTypeDefinition)type).getTypes()).getPath();
+                }
+
+                String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typePath);
                 className = packageName + "." + BindingMapping.getClassName(node.getQName());
             }
         }
@@ -1694,4 +1700,4 @@ public final class TypeProviderImpl implements TypeProvider {
         return BindingMapping.getPropertyName(type.getQName().getLocalName());
     }
 
-}
+}
\ No newline at end of file