diff --git a/android/src/main/java/com/xfl/msgbot/plugin/ipc/PluginService.kt b/android/src/main/java/com/xfl/msgbot/plugin/ipc/PluginService.kt index 0c09f95..e7430df 100644 --- a/android/src/main/java/com/xfl/msgbot/plugin/ipc/PluginService.kt +++ b/android/src/main/java/com/xfl/msgbot/plugin/ipc/PluginService.kt @@ -19,6 +19,8 @@ import com.xfl.msgbot.plugin.api.engine.ScriptEngineFactory import com.xfl.msgbot.plugin.api.provider.Provider import com.xfl.msgbot.plugin.api.remote.EngineEndpoint import com.xfl.msgbot.plugin.api.remote.ProviderEndpoint +import com.xfl.msgbot.plugin.api.remote.ToolingEndpoint +import com.xfl.msgbot.plugin.api.tooling.ToolingFactory import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.RejectedExecutionException @@ -34,6 +36,7 @@ import java.util.concurrent.atomic.AtomicLong * class MyPluginService : PluginService() { * override val engines = mapOf("luaj" to ScriptEngineFactory(::LuaEngine)) * override val providers = mapOf("weather" to ::WeatherProvider) + * override val tooling = mapOf("ts-tools" to ToolingFactory(::TypeScriptTools)) * } * ``` * @@ -43,6 +46,7 @@ import java.util.concurrent.atomic.AtomicLong open class PluginService : Service() { protected open val engines: Map = emptyMap() protected open val providers: Map Provider> = emptyMap() + protected open val tooling: Map = emptyMap() private class Session( val callback: IPluginCallback, @@ -87,6 +91,12 @@ open class PluginService : Service() { onProtocolError = lost, factory = providers[component] ?: throw IllegalArgumentException("This plugin has no provider '$component'"), ) + PluginRole.TOOLING -> + ToolingEndpoint( + transport, + tooling[component] ?: throw IllegalArgumentException("This plugin has no tooling '$component'"), + onProtocolError = lost, + ) else -> throw IllegalArgumentException("Unknown role '$role'") } } catch (e: Throwable) { @@ -184,6 +194,7 @@ open class PluginService : Service() { when (endpoint) { is EngineEndpoint -> endpoint.isStopped is ProviderEndpoint -> endpoint.isStopped + is ToolingEndpoint -> endpoint.isStopped else -> true } diff --git a/contract/src/main/kotlin/com/xfl/msgbot/plugin/api/discovery/PluginManifestSchema.kt b/contract/src/main/kotlin/com/xfl/msgbot/plugin/api/discovery/PluginManifestSchema.kt index f66ae95..00a7a12 100644 --- a/contract/src/main/kotlin/com/xfl/msgbot/plugin/api/discovery/PluginManifestSchema.kt +++ b/contract/src/main/kotlin/com/xfl/msgbot/plugin/api/discovery/PluginManifestSchema.kt @@ -22,6 +22,7 @@ object PluginManifestSchema { const val TAG_LANGUAGE = "language" const val TAG_PROFILE = "profile" const val TAG_PROVIDER = "provider" + const val TAG_TOOLING = "tooling" const val TAG_OPTION = "option" /** Root attribute: the plugin's [com.xfl.msgbot.plugin.api.protocol.ProtocolVersion.CURRENT]. */ @@ -58,6 +59,10 @@ object PluginManifestSchema { /** Space-separated namespaces. Publishing an unlisted namespace is refused. */ const val ATTR_PROVIDES = "provides" + // + /** Space-separated language names (``) the tooling serves, such as `javascript typescript`. */ + const val ATTR_LANGUAGES = "languages" + //