wit.rs

  1mod v0_0_1;
  2mod v0_0_4;
  3
  4use super::{wasm_engine, WasmState};
  5use anyhow::{Context, Result};
  6use language::LspAdapterDelegate;
  7use std::sync::Arc;
  8use util::SemanticVersion;
  9use wasmtime::{
 10    component::{Component, Instance, Linker, Resource},
 11    Store,
 12};
 13
 14use v0_0_4 as latest;
 15
 16pub use latest::{Command, LanguageServerConfig};
 17
 18pub fn new_linker(
 19    f: impl Fn(&mut Linker<WasmState>, fn(&mut WasmState) -> &mut WasmState) -> Result<()>,
 20) -> Linker<WasmState> {
 21    let mut linker = Linker::new(&wasm_engine());
 22    wasmtime_wasi::command::add_to_linker(&mut linker).unwrap();
 23    f(&mut linker, wasi_view).unwrap();
 24    linker
 25}
 26
 27fn wasi_view(state: &mut WasmState) -> &mut WasmState {
 28    state
 29}
 30
 31pub enum Extension {
 32    V004(v0_0_4::Extension),
 33    V001(v0_0_1::Extension),
 34}
 35
 36impl Extension {
 37    pub async fn instantiate_async(
 38        store: &mut Store<WasmState>,
 39        version: SemanticVersion,
 40        component: &Component,
 41    ) -> Result<(Self, Instance)> {
 42        if version < latest::VERSION {
 43            let (extension, instance) =
 44                v0_0_1::Extension::instantiate_async(store, &component, v0_0_1::linker())
 45                    .await
 46                    .context("failed to instantiate wasm extension")?;
 47            Ok((Self::V001(extension), instance))
 48        } else {
 49            let (extension, instance) =
 50                v0_0_4::Extension::instantiate_async(store, &component, v0_0_4::linker())
 51                    .await
 52                    .context("failed to instantiate wasm extension")?;
 53            Ok((Self::V004(extension), instance))
 54        }
 55    }
 56
 57    pub async fn call_init_extension(&self, store: &mut Store<WasmState>) -> Result<()> {
 58        match self {
 59            Extension::V004(ext) => ext.call_init_extension(store).await,
 60            Extension::V001(ext) => ext.call_init_extension(store).await,
 61        }
 62    }
 63
 64    pub async fn call_language_server_command(
 65        &self,
 66        store: &mut Store<WasmState>,
 67        config: &LanguageServerConfig,
 68        resource: Resource<Arc<dyn LspAdapterDelegate>>,
 69    ) -> Result<Result<Command, String>> {
 70        match self {
 71            Extension::V004(ext) => {
 72                ext.call_language_server_command(store, config, resource)
 73                    .await
 74            }
 75            Extension::V001(ext) => Ok(ext
 76                .call_language_server_command(store, &config.clone().into(), resource)
 77                .await?
 78                .map(|command| command.into())),
 79        }
 80    }
 81
 82    pub async fn call_language_server_initialization_options(
 83        &self,
 84        store: &mut Store<WasmState>,
 85        config: &LanguageServerConfig,
 86        resource: Resource<Arc<dyn LspAdapterDelegate>>,
 87    ) -> Result<Result<Option<String>, String>> {
 88        match self {
 89            Extension::V004(ext) => {
 90                ext.call_language_server_initialization_options(store, config, resource)
 91                    .await
 92            }
 93            Extension::V001(ext) => {
 94                ext.call_language_server_initialization_options(
 95                    store,
 96                    &config.clone().into(),
 97                    resource,
 98                )
 99                .await
100            }
101        }
102    }
103}