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}