package org.zwobble.hobgoblin.compiler.config; import org.zwobble.hobgoblin.compiler.output.generators.Generator; import org.zwobble.hobgoblin.compiler.output.generators.errors.UnknownGeneratorError; import org.zwobble.hobgoblin.compiler.output.generators.javapreciselymatchers.JavaPreciselyMatchersGenerator; import org.zwobble.hobgoblin.compiler.output.generators.javatransient0.JavaTransient0Generator; import org.zwobble.hobgoblin.compiler.output.generators.javatypes.JavaTypesGenerator; import org.zwobble.hobgoblin.compiler.output.generators.rusttransient0.RustTransient0Generator; import org.zwobble.hobgoblin.compiler.output.generators.rusttypes.RustTypesGenerator; import org.zwobble.hobgoblin.compiler.sources.FileFragmentSource; import org.zwobble.json5.reader.Json5ObjectReader; import org.zwobble.sourcetext.SourceText; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; public record ProjectConfig( List output ) { public static ProjectConfig read(Path projectRoot) throws IOException { var configPath = projectRoot.resolve("hobgoblin.json5"); var contents = Files.readString(configPath); var sourceText = SourceText.fromString(configPath.toString(), contents); return fromSourceText(projectRoot, sourceText); } private static ProjectConfig fromSourceText(Path projectRoot, SourceText sourceText) { return fromJson5(projectRoot, Json5ObjectReader.parse(sourceText)); } private static ProjectConfig fromJson5(Path projectRoot, Json5ObjectReader document) { var outputsJson = document.getObject("outputs"); var generatorsJson = outputsJson.getArrayOfObjects("generators"); var langsJson = outputsJson.getObjectOrNone("langs"); var outputs = new ArrayList(); for (var generatorJson : generatorsJson) { var generatorName = generatorJson.getString("generator"); var output = switch (generatorName.value()) { case JavaTypesGenerator.NAME -> JavaTypesGenerator.parseGeneratorConfig(projectRoot, generatorJson, langsJson); case JavaPreciselyMatchersGenerator.NAME -> JavaPreciselyMatchersGenerator.parseGeneratorConfig(projectRoot, generatorJson, langsJson); case JavaTransient0Generator.NAME -> JavaTransient0Generator.parseGeneratorConfig(projectRoot, generatorJson, langsJson); case RustTypesGenerator.NAME -> RustTypesGenerator.parseGeneratorConfig(projectRoot, generatorJson, langsJson); case RustTransient0Generator.NAME -> RustTransient0Generator.parseGeneratorConfig(projectRoot, generatorJson, langsJson); default -> throw new UnknownGeneratorError( generatorName.value(), new FileFragmentSource(generatorName.sourceRange()) ); }; outputs.add(output); } return new ProjectConfig(outputs); } public List createGenerators() { return this.output.stream() .map(output -> output.createGenerator()) .toList(); } }