package moe.nea.firmament.annotations.process import com.google.auto.service.AutoService import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.Dependencies import com.google.devtools.ksp.processing.KSPLogger import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.processing.SymbolProcessor import com.google.devtools.ksp.processing.SymbolProcessorEnvironment import com.google.devtools.ksp.processing.SymbolProcessorProvider import com.google.devtools.ksp.symbol.KSAnnotated import com.google.devtools.ksp.symbol.KSClassDeclaration import com.google.devtools.ksp.symbol.KSFile import com.google.devtools.ksp.symbol.KSName class ConfigAnnotationProcessor( val logger: KSPLogger, val codeGenerator: CodeGenerator, val sourceSetName: String ) : SymbolProcessor { val configs = mutableSetOf>() override fun process(resolver: Resolver): List { resolver.getSymbolsWithAnnotation("moe.nea.firmament.util.data.Config") .map { it as KSClassDeclaration } .mapTo(configs) { it.qualifiedName!! to it.containingFile!! } return listOf() } override fun finish() { val dependencies = Dependencies( aggregating = true, *configs.map { it.second }.toTypedArray() ) val generatedFileName = "ConfigProvider" val compatFile = codeGenerator.createNewFile( dependencies, "moe.nea.firmament.annotations.generated.$sourceSetName", generatedFileName ) .bufferedWriter() compatFile.appendLine("// This file is @generated by ConfigAnnotationProcessor") compatFile.appendLine("// Do not edit") compatFile.appendLine("package moe.nea.firmament.annotations.generated.$sourceSetName") compatFile.appendLine("class $generatedFileName : moe.nea.firmament.util.data.IConfigProvider {") compatFile.appendLine( """ override val configs: List> = listOf(${configs.joinToString { it.first.asString() }}) """ ) compatFile.appendLine("}") compatFile.close() val metaInf = codeGenerator.createNewFileByPath( dependencies, "META-INF/services/moe.nea.firmament.util.data.IConfigProvider", extensionName = "" ) .bufferedWriter() metaInf.append("moe.nea.firmament.annotations.generated.$sourceSetName.") metaInf.appendLine(generatedFileName) metaInf.close() } @AutoService(SymbolProcessorProvider::class) class Provider : SymbolProcessorProvider { override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { return ConfigAnnotationProcessor( environment.logger, environment.codeGenerator, environment.options["firmament.sourceset"] ?: "main" ) } } }