import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.Serializable import kotlinx.serialization.json.* import java.io.File import java.io.PrintWriter @Serializable data class LModule( val Namespace: String? = null, val Functions: List = listOf(), val Tables: List = listOf(), ) @Serializable data class LTypeUse( val Type: String, val InnerType: String? = null, val Name: String, val Nilable: Boolean, ) @Serializable data class LEnumValue( val Type: String, val Name: String, val EnumValue: Long, ) @Serializable data class LFunction( val Returns: List = listOf(), val Name: String, val Arguments: List = listOf(), ) @Serializable(with = LTable.Serializer::class) sealed class LTable { object Serializer : JsonContentPolymorphicSerializer(LTable::class) { override fun selectDeserializer(element: JsonElement): DeserializationStrategy { element as JsonObject return when ((element["Type"] as JsonPrimitive).content) { "Structure" -> LStructure.serializer() "Enumeration" -> LEnumeration.serializer() else -> { println("Unknown type " + element["Type"]) LUnknownObject.serializer() } } } } } @Serializable data class LStructure( val Name: String, val Fields: List, ) : LTable() @Serializable data object LUnknownObject : LTable() @Serializable data class LEnumeration( val Name: String, val MinValue: Long, val NumValues: Long, val MaxValue: Long, val Fields: List, ) : LTable() fun String?.postFixedWithOrEmpty(text: String): String { return if (this.isNullOrBlank()) "" else this + text } fun compositeTypeStr(module: LModule, field: LTypeUse): String { return if (field.InnerType == null) field.Type else module.Namespace.postFixedWithOrEmpty( "." ) + field.InnerType + "[]" } fun main() { val json1 = Json { ignoreUnknownKeys = true } val luaMeta = PrintWriter(File("definitions.lua")) luaMeta.println("---@meta") luaMeta.println() luaMeta.println("---@alias bool boolean") luaMeta.println("---@alias BigInteger number") luaMeta.println("---@alias BigUInteger number") luaMeta.println("---@alias cstring string") luaMeta.println("---@alias CalendarEventID string") luaMeta.println("---@alias ClubId string") luaMeta.println("---@alias ClubInvitationId string") luaMeta.println("---@alias ClubStreamId string") luaMeta.println("---@alias FileAsset string") luaMeta.println("---@alias fileID number") luaMeta.println("---@alias GarrisonFollower string") luaMeta.println("---@alias IDOrLink string|number") luaMeta.println("---@alias kstringClubMessage string") luaMeta.println("---@alias kstringLfgListApplicant string") luaMeta.println("---@alias kstringLfgListSearch string") luaMeta.println("---@alias luaIndex number") luaMeta.println("---@alias ModelAsset string") luaMeta.println("---@alias normalizedValue string") luaMeta.println("---@alias RecruitAcceptanceID string") luaMeta.println("---@alias ScriptRegion SimpleScriptRegion") luaMeta.println("---@alias SimpleButtonStateToken string") luaMeta.println("---@alias SingleColorValue number") luaMeta.println("---@alias size number") luaMeta.println("---@alias TBFFlags string") luaMeta.println("---@alias TBFStyleFlags string") luaMeta.println("---@alias textureAtlas string") luaMeta.println("---@alias textureKit string") luaMeta.println("---@alias time_t number") luaMeta.println("---@alias uiAddon string") luaMeta.println("---@alias uiFontHeight number") luaMeta.println("---@alias uiMapID number") luaMeta.println("---@alias uiUnit number") luaMeta.println("---@alias UnitToken string") luaMeta.println("---@alias WeeklyRewardItemDBID string") luaMeta.println("---@alias WOWGUID string") luaMeta.println("---@alias WOWMONEY string") for (module in json1.decodeFromString>(File("generated.json").readText())) { luaMeta.println() if (module.Namespace != null) { luaMeta.println("${module.Namespace} = {}") luaMeta.println() } for (table in module.Tables) { when (table) { is LEnumeration -> { luaMeta.println("---@enum ${table.Name}") luaMeta.println("${table.Name} = {") for (field in table.Fields) { luaMeta.println(" ${field.Name} = ${field.EnumValue};") } luaMeta.println("}") luaMeta.println() } is LStructure -> { luaMeta.println("---@class ${module.Namespace.postFixedWithOrEmpty(".")}${table.Name}") for (field in table.Fields) { luaMeta.println( "---@field ${field.Name} ${ compositeTypeStr( module, field ) }${if (field.Nilable) "|nil" else ""}" ) } luaMeta.println() } LUnknownObject -> { } } } for (func in module.Functions) { for (ret in func.Returns) { luaMeta.println( "---@return ${ compositeTypeStr( module, ret ) }${if (ret.Nilable) "|nil" else ""} ${ret.Name}" ) } for (par in func.Arguments) { luaMeta.println("---@param ${par.Name}${if (par.Nilable) "?" else ""} ${compositeTypeStr(module, par)}") } luaMeta.println("function ${module.Namespace.postFixedWithOrEmpty(".")}${func.Name}(${func.Arguments.joinToString { it.Name }}) end") luaMeta.println() } } luaMeta.close() }