Minestom/code-generators/src/main/java/net/minestom/codegen/potion/PotionTypeGenerator.java

156 lines
6.4 KiB
Java

package net.minestom.codegen.potion;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
import com.squareup.javapoet.*;
import net.minestom.codegen.MinestomCodeGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Collections;
public final class PotionTypeGenerator extends MinestomCodeGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(PotionTypeGenerator.class);
private final File potionsFile;
private final File outputFolder;
public PotionTypeGenerator(@NotNull File potionsFile, @NotNull File outputFolder) {
this.potionsFile = potionsFile;
this.outputFolder = outputFolder;
}
@Override
public void generate() {
if (!potionsFile.exists()) {
LOGGER.error("Failed to find potions.json.");
LOGGER.error("Stopped code generation for potions.");
return;
}
if (!outputFolder.exists() && !outputFolder.mkdirs()) {
LOGGER.error("Output folder for code generation does not exist and could not be created.");
return;
}
// Important classes we use alot
ClassName namespaceIDClassName = ClassName.get("net.minestom.server.utils", "NamespaceID");
ClassName registriesClassName = ClassName.get("net.minestom.server.registry", "Registries");
JsonArray potions;
try {
potions = GSON.fromJson(new JsonReader(new FileReader(potionsFile)), JsonArray.class);
} catch (FileNotFoundException e) {
LOGGER.error("Failed to find potions.json.");
LOGGER.error("Stopped code generation for potions.");
return;
}
ClassName potionTypeClassName = ClassName.get("net.minestom.server.potion", "PotionType");
// Particle
TypeSpec.Builder potionTypeClass = TypeSpec.enumBuilder(potionTypeClassName)
.addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed"))
.addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName());
potionTypeClass.addField(
FieldSpec.builder(namespaceIDClassName, "id")
.addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build()
);
// static field
potionTypeClass.addField(
FieldSpec.builder(ArrayTypeName.of(potionTypeClassName), "VALUES")
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("values()")
.build()
);
potionTypeClass.addMethod(
MethodSpec.constructorBuilder()
.addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build())
.addStatement("this.id = id")
.addStatement("$T.potionTypes.put(id, this)", registriesClassName)
.build()
);
// Override key method (adventure)
potionTypeClass.addMethod(
MethodSpec.methodBuilder("key")
.returns(ClassName.get("net.kyori.adventure.key", "Key"))
.addAnnotation(Override.class)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getId method
potionTypeClass.addMethod(
MethodSpec.methodBuilder("getId")
.returns(TypeName.SHORT)
.addStatement("return (short) ordinal()")
.addModifiers(Modifier.PUBLIC)
.build()
);
// getNamespaceID method
potionTypeClass.addMethod(
MethodSpec.methodBuilder("getNamespaceID")
.returns(namespaceIDClassName)
.addAnnotation(NotNull.class)
.addStatement("return this.id")
.addModifiers(Modifier.PUBLIC)
.build()
);
// fromId Method
potionTypeClass.addMethod(
MethodSpec.methodBuilder("fromId")
.returns(potionTypeClassName)
.addAnnotation(Nullable.class)
.addParameter(TypeName.SHORT, "id")
.beginControlFlow("if(id >= 0 && id < VALUES.length)")
.addStatement("return VALUES[id]")
.endControlFlow()
.addStatement("return null")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.build()
);
// toString method
potionTypeClass.addMethod(
MethodSpec.methodBuilder("toString")
.addAnnotation(NotNull.class)
.addAnnotation(Override.class)
.returns(String.class)
// this resolves to [Namespace]
.addStatement("return \"[\" + this.id + \"]\"")
.addModifiers(Modifier.PUBLIC)
.build()
);
// Use data
for (JsonElement p : potions) {
JsonObject potion = p.getAsJsonObject();
String potionName = potion.get("name").getAsString();
potionTypeClass.addEnumConstant(potionName, TypeSpec.anonymousClassBuilder(
"$T.from($S)",
namespaceIDClassName,
potion.get("id").getAsString()
).build()
);
}
// Write files to outputFolder
writeFiles(
Collections.singletonList(
JavaFile.builder("net.minestom.server.potion", potionTypeClass.build())
.indent(" ")
.skipJavaLangImports(true)
.build()
),
outputFolder
);
}
}