package cz.habarta.typescript.generator.ext;
import com.fasterxml.jackson.annotation.*;
import cz.habarta.typescript.generator.Settings;
import cz.habarta.typescript.generator.emitter.*;
public class TypeGuardsForJackson2PolymorphismExtension extends EmitterExtension {
@Override
public EmitterExtensionFeatures getFeatures() {
final EmitterExtensionFeatures features = new EmitterExtensionFeatures();
features.generatesRuntimeCode = true;
return features;
}
@Override
public void emitElements(Writer writer, Settings settings, boolean exportKeyword, TsModel model) {
for (TsBeanModel tsBean : model.getBeans()) {
final Class<?> beanClass = tsBean.getOrigin();
if (beanClass != null) {
final JsonSubTypes jsonSubTypes = beanClass.getAnnotation(JsonSubTypes.class);
final JsonTypeInfo jsonTypeInfo = beanClass.getAnnotation(JsonTypeInfo.class);
if (jsonSubTypes != null && jsonTypeInfo != null && jsonTypeInfo.include() == JsonTypeInfo.As.PROPERTY) {
final String propertyName = jsonTypeInfo.property();
for (JsonSubTypes.Type subType : jsonSubTypes.value()) {
String propertyValue = null;
if (jsonTypeInfo.use() == JsonTypeInfo.Id.NAME) {
if (subType.name().equals("")) {
final JsonTypeName jsonTypeName = subType.value().getAnnotation(JsonTypeName.class);
if (jsonTypeName != null) {
propertyValue = jsonTypeName.value();
}
} else {
propertyValue = subType.name();
}
}
if (propertyValue != null) {
final String baseTypeName = tsBean.getName().getSimpleName();
final String subTypeName = findTypeName(subType.value(), model);
if (baseTypeName != null && subTypeName != null) {
writer.writeIndentedLine("");
emitTypeGuard(writer, settings, exportKeyword, baseTypeName, subTypeName, propertyName, propertyValue);
}
}
}
}
}
}
}
static String findTypeName(Class<?> beanClass, TsModel model) {
for (TsBeanModel bean : model.getBeans()) {
if (bean.getOrigin().equals(beanClass)) {
return bean.getName().getSimpleName();
}
}
return null;
}
// Example:
// function isCartesianPoint(point: Point): point is CartesianPoint {
// return point.type === "cartesian";
// }
static void emitTypeGuard(Writer writer, Settings settings, boolean exportKeyword, String baseType, String subType, String propertyName, String propertyValue) {
final String argument = Character.toLowerCase(baseType.charAt(0)) + baseType.substring(1);
final String exportPrefix = exportKeyword ? "export " : "";
writer.writeIndentedLine(String.format(exportPrefix + "function is%s(%s: %s): %s is %s {", subType, argument, baseType, argument, subType));
writer.writeIndentedLine(String.format("%sreturn %s.%s === %s;", settings.indentString, argument, propertyName, settings.quotes + propertyValue + settings.quotes));
writer.writeIndentedLine("}");
}
}