BindingGenerator v1 "copy-paste" bug in RPCs
[mdsal.git] / binding / mdsal-binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / yang / types / TypeProviderImpl.java
index 7f9907c0e75311a77d2175b619b000b203d2be4f..397557611591c7132ce56f4ab5b342f750716b5a 100644 (file)
@@ -7,6 +7,7 @@
  */
 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;
@@ -64,6 +65,7 @@ import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
 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.Status;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
@@ -78,11 +80,8 @@ 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.Decimal64;
-import org.opendaylight.yangtools.yang.model.util.ExtendedType;
 import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
-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;
@@ -93,6 +92,11 @@ public final class TypeProviderImpl implements TypeProvider {
     private static final Logger LOG = LoggerFactory.getLogger(TypeProviderImpl.class);
     private static final Pattern NUMBERS_PATTERN = Pattern.compile("[0-9]+\\z");
 
+    // 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.
+    private static final SchemaPath UNION_PATH = SchemaPath.create(true,
+        org.opendaylight.yangtools.yang.model.util.BaseTypes.UNION_QNAME);
+
     /**
      * Contains the schema data red from YANG files.
      */
@@ -186,8 +190,7 @@ 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!)");
@@ -198,10 +201,9 @@ public final class TypeProviderImpl implements TypeProvider {
         if (typeDefinition.getBaseType() == 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);
+            // a base type which holds these constraints.
+            if (typeDefinition instanceof DecimalTypeDefinition) {
+                final Type ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, parentNode, r);
                 if (ret != null) {
                     return ret;
                 }
@@ -227,8 +229,7 @@ public final class TypeProviderImpl implements TypeProvider {
             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))) {
@@ -411,8 +412,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(
@@ -495,7 +495,8 @@ public final class TypeProviderImpl implements TypeProvider {
                 } else {
                     dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
                 }
-                Preconditions.checkArgument(dataNode != null, "Failed to find leafref target node: %s", 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());
@@ -508,7 +509,8 @@ public final class TypeProviderImpl implements TypeProvider {
                 returnType = Types.typeForClass(Object.class);
             }
         }
-        Preconditions.checkArgument(returnType != null, "Failed to find leafref target: %s", 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;
     }
 
@@ -561,7 +563,7 @@ public final class TypeProviderImpl implements TypeProvider {
 
     /**
      * Converts <code>enumTypeDef</code> to
-     * {@link org.opendaylight.yangtools.sal.binding.model.api.Enumeration
+     * {@link Enumeration
      * enumeration}.
      *
      * @param enumTypeDef
@@ -578,8 +580,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!");
@@ -593,7 +594,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());
@@ -624,8 +626,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!");
@@ -637,7 +638,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);
     }
@@ -729,8 +731,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)) {
@@ -740,8 +741,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);
@@ -780,8 +780,7 @@ public final class TypeProviderImpl implements TypeProvider {
                     makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
                     returnType = genTOBuilder.toInstance();
                 } else {
-                    final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(
-                            innerTypeDefinition, typedef);
+                    final Type javaType = javaTypeForSchemaDefinitionType(innerTypeDefinition, typedef);
                     returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType, module.getName());
                 }
                 if (returnType != null) {
@@ -812,8 +811,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";
 
@@ -824,6 +822,9 @@ public final class TypeProviderImpl implements TypeProvider {
         genTOBuilder.addEqualsIdentity(genPropBuilder);
         genTOBuilder.addHashIdentity(genPropBuilder);
         genTOBuilder.addToStringProperty(genPropBuilder);
+        if (typedef.getStatus() == Status.DEPRECATED) {
+            genTOBuilder.addAnnotation("", "Deprecated");
+        }
         if (javaType instanceof ConcreteType && "String".equals(javaType.getName()) && typedef.getBaseType() != null) {
             final List<String> regExps = resolveRegExpressionsFromTypedef(typedef);
             addStringRegExAsConstant(genTOBuilder, regExps);
@@ -850,24 +851,16 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName,
             final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) {
-        final List<GeneratedTOBuilder> genTOBuilders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
+        final List<GeneratedTOBuilder> builders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
                 typedef, typeDefName, parentNode);
-        GeneratedTOBuilder resultTOBuilder = null;
-        if (genTOBuilders.isEmpty()) {
-            throw new IllegalStateException("No GeneratedTOBuilder objects generated from union " + typedef);
-        }
+        Preconditions.checkState(!builders.isEmpty(), "No GeneratedTOBuilder objects generated from union %s", typedef);
 
-        resultTOBuilder = genTOBuilders.remove(0);
-        for (GeneratedTOBuilder genTOBuilder : genTOBuilders) {
+        final GeneratedTOBuilder resultTOBuilder = builders.remove(0);
+        for (GeneratedTOBuilder genTOBuilder : builders) {
             resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
         }
 
-        final GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");
-        genPropBuilder.setReturnType(Types.CHAR_ARRAY);
-        resultTOBuilder.addEqualsIdentity(genPropBuilder);
-        resultTOBuilder.addHashIdentity(genPropBuilder);
-        resultTOBuilder.addToStringProperty(genPropBuilder);
-
+        resultTOBuilder.addProperty("value").setReturnType(Types.CHAR_ARRAY);
         return resultTOBuilder;
     }
 
@@ -891,8 +884,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!");
@@ -905,7 +897,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());
@@ -923,14 +916,13 @@ public final class TypeProviderImpl implements TypeProvider {
                         parentNode);
             } else if (unionType instanceof UnionTypeDefinition) {
                 generatedTOBuilders.addAll(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionTypeDefinition) unionType,
-                    basePackageName, parentNode));
+                        basePackageName, parentNode));
             } else if (unionType instanceof EnumTypeDefinition) {
                 final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType,
                         unionTypeName, unionGenTOBuilder);
                 updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName);
             } else {
-                final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(unionType,
-                        parentNode);
+                final Type javaType = javaTypeForSchemaDefinitionType(unionType, parentNode);
                 updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName);
             }
         }
@@ -966,8 +958,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);
@@ -1000,8 +991,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *            parent Schema Node for Extended Subtype
      *
      */
-    private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
-            final TypeDefinition<?> 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) {
@@ -1053,8 +1043,7 @@ 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) {
+    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) {
@@ -1078,8 +1067,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));
@@ -1101,8 +1089,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();
@@ -1110,8 +1097,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);
@@ -1141,8 +1129,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!");
@@ -1152,8 +1139,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,14 +1180,7 @@ public final class TypeProviderImpl implements TypeProvider {
         Preconditions.checkArgument(typedef != null, "typedef can't be null");
 
         final List<PatternConstraint> patternConstraints;
-        if (typedef instanceof ExtendedType) {
-            final TypeDefinition<?> strTypeDef = baseTypeDefForExtendedType(typedef);
-            if (strTypeDef instanceof StringTypeDefinition) {
-                patternConstraints = ((ExtendedType)typedef).getPatternConstraints();
-            } else {
-                patternConstraints = ImmutableList.of();
-            }
-        } else if (typedef instanceof StringTypeDefinition) {
+        if (typedef instanceof StringTypeDefinition) {
             // FIXME: run diff against base
             patternConstraints = ((StringTypeDefinition) typedef).getPatternConstraints();
         } else {
@@ -1272,8 +1253,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!");
 
@@ -1281,14 +1261,18 @@ 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);
         genTOBuilder.setTypedef(true);
         Restrictions r = BindingGeneratorUtil.getRestrictions(typedef);
         genTOBuilder.setRestrictions(r);
+        if (typedef.getStatus() == Status.DEPRECATED) {
+            genTOBuilder.addAnnotation("", "Deprecated");
+        }
 
         if (baseTypeDefForExtendedType(innerExtendedType) instanceof UnionTypeDefinition) {
             genTOBuilder.setIsUnion(true);
@@ -1375,7 +1359,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *         definition to the base type
      */
     private static int getTypeDefinitionDepth(final TypeDefinition<?> typeDefinition) {
-        // FIXME: rewrite this in a non-recursive manner, without ExtendedType and UnionType
+        // FIXME: rewrite this in a non-recursive manner
         if (typeDefinition == null) {
             return 1;
         }
@@ -1551,15 +1535,9 @@ public final class TypeProviderImpl implements TypeProvider {
         return sb.toString();
     }
 
-    private static final Comparator<Bit> BIT_NAME_COMPARATOR = new Comparator<Bit>() {
-        @Override
-        public int compare(final Bit o1, final Bit o2) {
-            return o1.getName().compareTo(o2.getName());
-        }
-    };
+    private static final Comparator<Bit> BIT_NAME_COMPARATOR = (o1, o2) -> 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();
@@ -1638,12 +1616,7 @@ public final class TypeProviderImpl implements TypeProvider {
                 }
                 if (module == null) {
                     List<Module> modulesList = new ArrayList<>(modules);
-                    Collections.sort(modulesList, new Comparator<Module>() {
-                        @Override
-                        public int compare(final Module o1, final Module o2) {
-                            return o1.getRevision().compareTo(o2.getRevision());
-                        }
-                    });
+                    Collections.sort(modulesList, (o1, o2) -> o1.getRevision().compareTo(o2.getRevision()));
                     module = modulesList.get(0);
                 }
             } else {
@@ -1667,18 +1640,7 @@ public final class TypeProviderImpl implements TypeProvider {
                 Date revision = first.getRevision();
                 Module parentModule = schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
                 String basePackageName = BindingMapping.getRootPackageName(parentModule.getQNameModule());
-
-                // 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);
+                String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, UNION_PATH);
                 className = packageName + "." + BindingMapping.getClassName(node.getQName());
             }
         }