Skip to content

Commit

Permalink
Validate enums field and type
Browse files Browse the repository at this point in the history
  • Loading branch information
tomdaffurn committed Oct 1, 2024
1 parent ef7668f commit 9fc1872
Showing 1 changed file with 27 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package xyz.block.ftl.deployment;

import static org.jboss.jandex.PrimitiveType.Primitive.BYTE;
import static org.jboss.jandex.PrimitiveType.Primitive.INT;
import static org.jboss.jandex.PrimitiveType.Primitive.LONG;
import static org.jboss.jandex.PrimitiveType.Primitive.SHORT;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.PrimitiveType;
import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -33,6 +37,7 @@ SchemaContributorBuildItem handleEnums(CombinedIndexBuildItem index) {
log.info("Processing {} enum annotations into build items", enumAnnotations.size());
List<Decl> decls = new ArrayList<>();
try {
// TODO how do we exclude @Enum annotations from generated verb clients?
for (var enumAnnotation : enumAnnotations) {
boolean exported = enumAnnotation.target().hasAnnotation(FTLDotNames.EXPORT);
ClassInfo enumClassInfo = enumAnnotation.target().asClass();
Expand All @@ -41,12 +46,19 @@ SchemaContributorBuildItem handleEnums(CombinedIndexBuildItem index) {
.setExport(exported);
if (enumClassInfo.isEnum()) {
// Value enums must have a type
Type type = enumClassInfo.field("value").type();
FieldInfo valueField = enumClassInfo.field("value");
if (valueField == null) {
throw new RuntimeException("Enum must have a 'value' field: " + enumClassInfo.name());
}
Type type = valueField.type();
xyz.block.ftl.v1.schema.Type.Builder typeBuilder = xyz.block.ftl.v1.schema.Type.newBuilder();
if (type == PrimitiveType.LONG) {
if (isInt(type)) {
typeBuilder.setInt(Int.newBuilder().build()).build();
} else {
} else if (type.name().equals(DotName.STRING_NAME)) {
typeBuilder.setString(xyz.block.ftl.v1.schema.String.newBuilder().build());
} else {
throw new RuntimeException(
"Enum value type must be String, int, long, short, or byte: " + enumClassInfo.name());
}
enumBuilder.setType(typeBuilder.build());

Expand All @@ -56,14 +68,12 @@ SchemaContributorBuildItem handleEnums(CombinedIndexBuildItem index) {
Field value = constant.getClass().getDeclaredField("value");
value.setAccessible(true);
Value.Builder valueBuilder = Value.newBuilder();
if (type == PrimitiveType.LONG) {
if (isInt(type)) {
long aLong = value.getLong(constant);
valueBuilder.setIntValue(IntValue.newBuilder().setValue(aLong).build());
} else if (type.name().equals(DotName.STRING_NAME)) {
} else {
String aString = (String) value.get(constant);
valueBuilder.setStringValue(StringValue.newBuilder().setValue(aString).build());
} else {
throw new RuntimeException("Unsupported enum value type: " + value.getType());
}
EnumVariant variant = EnumVariant.newBuilder()
.setName(constant.toString())
Expand All @@ -85,4 +95,11 @@ SchemaContributorBuildItem handleEnums(CombinedIndexBuildItem index) {
}
}

private boolean isInt(Type type) {
if (type.kind() != Type.Kind.PRIMITIVE) {
return false;
}
return Set.of(INT, LONG, BYTE, SHORT).contains(type.asPrimitiveType().primitive());
}

}

0 comments on commit 9fc1872

Please sign in to comment.