1use std::sync::Arc;
4
5use CommonLibrary::{
6 Environment::Requires::Requires,
7 Error::CommonError::CommonError,
8 IPC::IPCProvider::IPCProvider,
9 LanguageFeature::DTO::{
10 CompletionContextDTO::CompletionContextDTO,
11 CompletionListDTO::CompletionListDTO,
12 HoverResultDTO::HoverResultDTO,
13 LocationDTO::LocationDTO,
14 PositionDTO::PositionDTO,
15 ProviderType::ProviderType,
16 TextEditDTO::TextEditDTO,
17 },
18};
19use log::warn;
20use serde_json::{Value, json};
21use url::Url;
22
23use crate::ApplicationState::DTO::ProviderRegistrationDTO::ProviderRegistrationDTO;
24
25pub(super) async fn provide_code_actions(
28 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
29 document_uri:Url,
30 range_or_selection_dto:Value,
31 context_dto:Value,
32) -> Result<Option<Value>, CommonError> {
33 let provider =
34 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::CodeAction).await?;
35 match provider {
36 Some(registration) => {
37 let response = invoke_provider(
38 environment,
39 ®istration,
40 vec![
41 json!(registration.Handle),
42 json!({ "external": document_uri.to_string(), "$mid": 1 }),
43 range_or_selection_dto,
44 context_dto,
45 ],
46 )
47 .await?;
48 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
49 },
50 None => Ok(None),
51 }
52}
53
54pub(super) async fn provide_code_lenses(
55 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
56 document_uri:Url,
57) -> Result<Option<Value>, CommonError> {
58 let provider =
59 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::CodeLens).await?;
60 match provider {
61 Some(registration) => {
62 let response = invoke_provider(
63 environment,
64 ®istration,
65 vec![
66 json!(registration.Handle),
67 json!({ "external": document_uri.to_string(), "$mid": 1 }),
68 ],
69 )
70 .await?;
71 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
72 },
73 None => Ok(None),
74 }
75}
76
77pub(super) async fn provide_completions(
78 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
79 document_uri:Url,
80 position_dto:PositionDTO,
81 context_dto:CompletionContextDTO,
82 cancellation_token_value:Option<Value>,
83) -> Result<Option<CompletionListDTO>, CommonError> {
84 let provider =
85 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Completion).await?;
86 match provider {
87 Some(registration) => {
88 let response = invoke_provider(
89 environment,
90 ®istration,
91 vec![
92 json!(registration.Handle),
93 json!({ "external": document_uri.to_string(), "$mid": 1 }),
94 json!(position_dto),
95 json!(context_dto),
96 cancellation_token_value.unwrap_or_else(|| json!(null)),
97 ],
98 )
99 .await?;
100 if response.is_null() {
101 Ok(None)
102 } else {
103 serde_json::from_value(response).map_err(|error| {
104 CommonError::SerializationError {
105 Description:format!("Failed to deserialize CompletionListDTO: {}", error),
106 }
107 })
108 }
109 },
110 None => Ok(None),
111 }
112}
113
114pub(super) async fn provide_definition(
115 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
116 document_uri:Url,
117 position_dto:PositionDTO,
118) -> Result<Option<Vec<LocationDTO>>, CommonError> {
119 let provider =
120 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Definition).await?;
121 match provider {
122 Some(registration) => {
123 let response = invoke_provider(
124 environment,
125 ®istration,
126 vec![
127 json!(registration.Handle),
128 json!({ "external": document_uri.to_string(), "$mid": 1 }),
129 json!(position_dto),
130 ],
131 )
132 .await?;
133 if response.is_null() {
134 Ok(None)
135 } else {
136 serde_json::from_value(response).map_err(|error| {
137 CommonError::SerializationError {
138 Description:format!("Failed to deserialize Vec<LocationDTO>: {}", error),
139 }
140 })
141 }
142 },
143 None => Ok(None),
144 }
145}
146
147pub(super) async fn provide_document_formatting_edits(
148 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
149 document_uri:Url,
150 options_dto:Value,
151) -> Result<Option<Vec<TextEditDTO>>, CommonError> {
152 let provider =
153 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentFormatting)
154 .await?;
155 match provider {
156 Some(registration) => {
157 let response = invoke_provider(
158 environment,
159 ®istration,
160 vec![
161 json!(registration.Handle),
162 json!({ "external": document_uri.to_string(), "$mid": 1 }),
163 options_dto,
164 ],
165 )
166 .await?;
167 if response.is_null() {
168 Ok(None)
169 } else {
170 serde_json::from_value(response).map_err(|error| {
171 CommonError::SerializationError {
172 Description:format!("Failed to deserialize Vec<TextEditDTO>: {}", error),
173 }
174 })
175 }
176 },
177 None => Ok(None),
178 }
179}
180
181pub(super) async fn provide_document_highlights(
182 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
183 document_uri:Url,
184 position_dto:PositionDTO,
185) -> Result<Option<Value>, CommonError> {
186 let provider =
187 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentHighlight)
188 .await?;
189 match provider {
190 Some(registration) => {
191 let response = invoke_provider(
192 environment,
193 ®istration,
194 vec![
195 json!(registration.Handle),
196 json!({ "external": document_uri.to_string(), "$mid": 1 }),
197 json!(position_dto),
198 ],
199 )
200 .await?;
201 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
202 },
203 None => Ok(None),
204 }
205}
206
207pub(super) async fn provide_document_links(
208 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
209 document_uri:Url,
210) -> Result<Option<Value>, CommonError> {
211 let provider =
212 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentLink).await?;
213 match provider {
214 Some(registration) => {
215 let response = invoke_provider(
216 environment,
217 ®istration,
218 vec![
219 json!(registration.Handle),
220 json!({ "external": document_uri.to_string(), "$mid": 1 }),
221 ],
222 )
223 .await?;
224 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
225 },
226 None => Ok(None),
227 }
228}
229
230pub(super) async fn provide_document_range_formatting_edits(
231 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
232 document_uri:Url,
233 range_dto:Value,
234 options_dto:Value,
235) -> Result<Option<Vec<TextEditDTO>>, CommonError> {
236 let provider =
237 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentRangeFormatting)
238 .await?;
239 match provider {
240 Some(registration) => {
241 let response = invoke_provider(
242 environment,
243 ®istration,
244 vec![
245 json!(registration.Handle),
246 json!({ "external": document_uri.to_string(), "$mid": 1 }),
247 range_dto,
248 options_dto,
249 ],
250 )
251 .await?;
252 if response.is_null() {
253 Ok(None)
254 } else {
255 serde_json::from_value(response).map_err(|error| {
256 CommonError::SerializationError {
257 Description:format!("Failed to deserialize Vec<TextEditDTO>: {}", error),
258 }
259 })
260 }
261 },
262 None => Ok(None),
263 }
264}
265
266pub(super) async fn provide_hover(
267 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
268 document_uri:Url,
269 position_dto:PositionDTO,
270) -> Result<Option<HoverResultDTO>, CommonError> {
271 let provider =
272 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Hover).await?;
273 match provider {
274 Some(registration) => {
275 let response = invoke_provider(
276 environment,
277 ®istration,
278 vec![
279 json!(registration.Handle),
280 json!({ "external": document_uri.to_string(), "$mid": 1 }),
281 json!(position_dto),
282 ],
283 )
284 .await?;
285 if response.is_null() {
286 Ok(None)
287 } else {
288 serde_json::from_value(response).map_err(|error| {
289 CommonError::SerializationError {
290 Description:format!("Failed to deserialize HoverResultDTO: {}", error),
291 }
292 })
293 }
294 },
295 None => Ok(None),
296 }
297}
298
299pub(super) async fn provide_references(
300 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
301 document_uri:Url,
302 position_dto:PositionDTO,
303 context_dto:Value,
304) -> Result<Option<Vec<LocationDTO>>, CommonError> {
305 let provider =
306 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::References).await?;
307 match provider {
308 Some(registration) => {
309 let response = invoke_provider(
310 environment,
311 ®istration,
312 vec![
313 json!(registration.Handle),
314 json!({ "external": document_uri.to_string(), "$mid": 1 }),
315 json!(position_dto),
316 context_dto,
317 ],
318 )
319 .await?;
320 if response.is_null() {
321 Ok(None)
322 } else {
323 serde_json::from_value(response).map_err(|error| {
324 CommonError::SerializationError {
325 Description:format!("Failed to deserialize Vec<LocationDTO>: {}", error),
326 }
327 })
328 }
329 },
330 None => Ok(None),
331 }
332}
333
334pub(super) async fn prepare_rename(
335 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
336 document_uri:Url,
337 position_dto:PositionDTO,
338) -> Result<Option<Value>, CommonError> {
339 let provider =
340 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Rename).await?;
341 match provider {
342 Some(registration) => {
343 let response = invoke_provider(
344 environment,
345 ®istration,
346 vec![
347 json!(registration.Handle),
348 json!({ "external": document_uri.to_string(), "$mid": 1 }),
349 json!(position_dto),
350 ],
351 )
352 .await?;
353 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
354 },
355 None => Ok(None),
356 }
357}
358
359async fn invoke_provider(
360 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
361 registration:&ProviderRegistrationDTO,
362 arguments:Vec<Value>,
363) -> Result<Value, CommonError> {
364 let rpc_method = format!("$provide{}", registration.ProviderType.to_string());
365 let ipc_provider:Arc<dyn IPCProvider> = environment.Require();
366 ipc_provider
367 .SendRequestToSideCar(registration.SideCarIdentifier.clone(), rpc_method, json!(arguments), 5000)
368 .await
369}