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 serde_json::{Value, json};
20use url::Url;
21
22use crate::ApplicationState::DTO::ProviderRegistrationDTO::ProviderRegistrationDTO;
23
24pub(super) async fn provide_code_actions(
27 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
28 document_uri:Url,
29 range_or_selection_dto:Value,
30 context_dto:Value,
31) -> Result<Option<Value>, CommonError> {
32 let provider =
33 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::CodeAction).await?;
34 match provider {
35 Some(registration) => {
36 let response = invoke_provider(
37 environment,
38 ®istration,
39 vec![
40 json!(registration.Handle),
41 json!({ "external": document_uri.to_string(), "$mid": 1 }),
42 range_or_selection_dto,
43 context_dto,
44 ],
45 )
46 .await?;
47 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
48 },
49 None => Ok(None),
50 }
51}
52
53pub(super) async fn provide_code_lenses(
54 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
55 document_uri:Url,
56) -> Result<Option<Value>, CommonError> {
57 let provider =
58 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::CodeLens).await?;
59 match provider {
60 Some(registration) => {
61 let response = invoke_provider(
62 environment,
63 ®istration,
64 vec![
65 json!(registration.Handle),
66 json!({ "external": document_uri.to_string(), "$mid": 1 }),
67 ],
68 )
69 .await?;
70 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
71 },
72 None => Ok(None),
73 }
74}
75
76pub(super) async fn provide_completions(
77 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
78 document_uri:Url,
79 position_dto:PositionDTO,
80 context_dto:CompletionContextDTO,
81 cancellation_token_value:Option<Value>,
82) -> Result<Option<CompletionListDTO>, CommonError> {
83 let provider =
84 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Completion).await?;
85 match provider {
86 Some(registration) => {
87 let response = invoke_provider(
88 environment,
89 ®istration,
90 vec![
91 json!(registration.Handle),
92 json!({ "external": document_uri.to_string(), "$mid": 1 }),
93 json!(position_dto),
94 json!(context_dto),
95 cancellation_token_value.unwrap_or_else(|| json!(null)),
96 ],
97 )
98 .await?;
99 if response.is_null() {
100 Ok(None)
101 } else {
102 serde_json::from_value(response).map_err(|error| {
103 CommonError::SerializationError {
104 Description:format!("Failed to deserialize CompletionListDTO: {}", error),
105 }
106 })
107 }
108 },
109 None => Ok(None),
110 }
111}
112
113pub(super) async fn provide_definition(
114 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
115 document_uri:Url,
116 position_dto:PositionDTO,
117) -> Result<Option<Vec<LocationDTO>>, CommonError> {
118 let provider =
119 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Definition).await?;
120 match provider {
121 Some(registration) => {
122 let response = invoke_provider(
123 environment,
124 ®istration,
125 vec![
126 json!(registration.Handle),
127 json!({ "external": document_uri.to_string(), "$mid": 1 }),
128 json!(position_dto),
129 ],
130 )
131 .await?;
132 if response.is_null() {
133 Ok(None)
134 } else {
135 serde_json::from_value(response).map_err(|error| {
136 CommonError::SerializationError {
137 Description:format!("Failed to deserialize Vec<LocationDTO>: {}", error),
138 }
139 })
140 }
141 },
142 None => Ok(None),
143 }
144}
145
146pub(super) async fn provide_document_formatting_edits(
147 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
148 document_uri:Url,
149 options_dto:Value,
150) -> Result<Option<Vec<TextEditDTO>>, CommonError> {
151 let provider =
152 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentFormatting)
153 .await?;
154 match provider {
155 Some(registration) => {
156 let response = invoke_provider(
157 environment,
158 ®istration,
159 vec![
160 json!(registration.Handle),
161 json!({ "external": document_uri.to_string(), "$mid": 1 }),
162 options_dto,
163 ],
164 )
165 .await?;
166 if response.is_null() {
167 Ok(None)
168 } else {
169 serde_json::from_value(response).map_err(|error| {
170 CommonError::SerializationError {
171 Description:format!("Failed to deserialize Vec<TextEditDTO>: {}", error),
172 }
173 })
174 }
175 },
176 None => Ok(None),
177 }
178}
179
180pub(super) async fn provide_document_highlights(
181 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
182 document_uri:Url,
183 position_dto:PositionDTO,
184) -> Result<Option<Value>, CommonError> {
185 let provider =
186 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentHighlight)
187 .await?;
188 match provider {
189 Some(registration) => {
190 let response = invoke_provider(
191 environment,
192 ®istration,
193 vec![
194 json!(registration.Handle),
195 json!({ "external": document_uri.to_string(), "$mid": 1 }),
196 json!(position_dto),
197 ],
198 )
199 .await?;
200 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
201 },
202 None => Ok(None),
203 }
204}
205
206pub(super) async fn provide_document_links(
207 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
208 document_uri:Url,
209) -> Result<Option<Value>, CommonError> {
210 let provider =
211 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentLink).await?;
212 match provider {
213 Some(registration) => {
214 let response = invoke_provider(
215 environment,
216 ®istration,
217 vec![
218 json!(registration.Handle),
219 json!({ "external": document_uri.to_string(), "$mid": 1 }),
220 ],
221 )
222 .await?;
223 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
224 },
225 None => Ok(None),
226 }
227}
228
229pub(super) async fn provide_document_range_formatting_edits(
230 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
231 document_uri:Url,
232 range_dto:Value,
233 options_dto:Value,
234) -> Result<Option<Vec<TextEditDTO>>, CommonError> {
235 let provider =
236 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentRangeFormatting)
237 .await?;
238 match provider {
239 Some(registration) => {
240 let response = invoke_provider(
241 environment,
242 ®istration,
243 vec![
244 json!(registration.Handle),
245 json!({ "external": document_uri.to_string(), "$mid": 1 }),
246 range_dto,
247 options_dto,
248 ],
249 )
250 .await?;
251 if response.is_null() {
252 Ok(None)
253 } else {
254 serde_json::from_value(response).map_err(|error| {
255 CommonError::SerializationError {
256 Description:format!("Failed to deserialize Vec<TextEditDTO>: {}", error),
257 }
258 })
259 }
260 },
261 None => Ok(None),
262 }
263}
264
265pub(super) async fn provide_hover(
266 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
267 document_uri:Url,
268 position_dto:PositionDTO,
269) -> Result<Option<HoverResultDTO>, CommonError> {
270 let provider =
271 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Hover).await?;
272 match provider {
273 Some(registration) => {
274 let response = invoke_provider(
275 environment,
276 ®istration,
277 vec![
278 json!(registration.Handle),
279 json!({ "external": document_uri.to_string(), "$mid": 1 }),
280 json!(position_dto),
281 ],
282 )
283 .await?;
284 if response.is_null() {
285 Ok(None)
286 } else {
287 serde_json::from_value(response).map_err(|error| {
288 CommonError::SerializationError {
289 Description:format!("Failed to deserialize HoverResultDTO: {}", error),
290 }
291 })
292 }
293 },
294 None => Ok(None),
295 }
296}
297
298pub(super) async fn provide_references(
299 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
300 document_uri:Url,
301 position_dto:PositionDTO,
302 context_dto:Value,
303) -> Result<Option<Vec<LocationDTO>>, CommonError> {
304 let provider =
305 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::References).await?;
306 match provider {
307 Some(registration) => {
308 let response = invoke_provider(
309 environment,
310 ®istration,
311 vec![
312 json!(registration.Handle),
313 json!({ "external": document_uri.to_string(), "$mid": 1 }),
314 json!(position_dto),
315 context_dto,
316 ],
317 )
318 .await?;
319 if response.is_null() {
320 Ok(None)
321 } else {
322 serde_json::from_value(response).map_err(|error| {
323 CommonError::SerializationError {
324 Description:format!("Failed to deserialize Vec<LocationDTO>: {}", error),
325 }
326 })
327 }
328 },
329 None => Ok(None),
330 }
331}
332
333pub(super) async fn prepare_rename(
334 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
335 document_uri:Url,
336 position_dto:PositionDTO,
337) -> Result<Option<Value>, CommonError> {
338 let provider =
339 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Rename).await?;
340 match provider {
341 Some(registration) => {
342 let response = invoke_provider(
343 environment,
344 ®istration,
345 vec![
346 json!(registration.Handle),
347 json!({ "external": document_uri.to_string(), "$mid": 1 }),
348 json!(position_dto),
349 ],
350 )
351 .await?;
352 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
353 },
354 None => Ok(None),
355 }
356}
357
358pub(super) async fn provide_rename_edits(
359 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
360 document_uri:Url,
361 position_dto:PositionDTO,
362 new_name:String,
363) -> Result<Option<Value>, CommonError> {
364 let provider =
365 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::Rename).await?;
366 match provider {
367 Some(registration) => {
368 let response = invoke_provider(
369 environment,
370 ®istration,
371 vec![
372 json!(registration.Handle),
373 json!({ "external": document_uri.to_string(), "$mid": 1 }),
374 json!(position_dto),
375 json!(new_name),
376 ],
377 )
378 .await?;
379 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
380 },
381 None => Ok(None),
382 }
383}
384
385pub(super) async fn provide_document_symbols(
386 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
387 document_uri:Url,
388) -> Result<Option<Value>, CommonError> {
389 let provider =
390 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::DocumentSymbol).await?;
391 match provider {
392 Some(registration) => {
393 let response = invoke_provider(
394 environment,
395 ®istration,
396 vec![
397 json!(registration.Handle),
398 json!({ "external": document_uri.to_string(), "$mid": 1 }),
399 ],
400 )
401 .await?;
402 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
403 },
404 None => Ok(None),
405 }
406}
407
408pub(super) async fn provide_workspace_symbols(
409 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
410 query:String,
411) -> Result<Option<Value>, CommonError> {
412 let MatchingRegistration = {
416 let providers = environment
417 .ApplicationState
418 .Extension
419 .ProviderRegistration
420 .LanguageProviders
421 .lock()
422 .map_err(crate::Environment::Utility::MapApplicationStateLockErrorToCommonError)?;
423 providers
424 .values()
425 .find(|p| p.ProviderType == ProviderType::WorkspaceSymbol)
426 .cloned()
427 };
428 match MatchingRegistration {
429 Some(registration) => {
430 let response =
431 invoke_provider(environment, ®istration, vec![json!(registration.Handle), json!(query)]).await?;
432 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
433 },
434 None => Ok(None),
435 }
436}
437
438pub(super) async fn provide_signature_help(
439 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
440 document_uri:Url,
441 position_dto:PositionDTO,
442 context_dto:Value,
443) -> Result<Option<Value>, CommonError> {
444 let provider =
445 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::SignatureHelp).await?;
446 match provider {
447 Some(registration) => {
448 let response = invoke_provider(
449 environment,
450 ®istration,
451 vec![
452 json!(registration.Handle),
453 json!({ "external": document_uri.to_string(), "$mid": 1 }),
454 json!(position_dto),
455 context_dto,
456 ],
457 )
458 .await?;
459 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
460 },
461 None => Ok(None),
462 }
463}
464
465pub(super) async fn provide_folding_ranges(
466 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
467 document_uri:Url,
468) -> Result<Option<Value>, CommonError> {
469 let provider =
470 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::FoldingRange).await?;
471 match provider {
472 Some(registration) => {
473 let response = invoke_provider(
474 environment,
475 ®istration,
476 vec![
477 json!(registration.Handle),
478 json!({ "external": document_uri.to_string(), "$mid": 1 }),
479 ],
480 )
481 .await?;
482 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
483 },
484 None => Ok(None),
485 }
486}
487
488pub(super) async fn provide_selection_ranges(
489 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
490 document_uri:Url,
491 positions:Vec<PositionDTO>,
492) -> Result<Option<Value>, CommonError> {
493 let provider =
494 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::SelectionRange).await?;
495 match provider {
496 Some(registration) => {
497 let response = invoke_provider(
498 environment,
499 ®istration,
500 vec![
501 json!(registration.Handle),
502 json!({ "external": document_uri.to_string(), "$mid": 1 }),
503 json!(positions),
504 ],
505 )
506 .await?;
507 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
508 },
509 None => Ok(None),
510 }
511}
512
513pub(super) async fn provide_semantic_tokens_full(
514 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
515 document_uri:Url,
516) -> Result<Option<Value>, CommonError> {
517 let provider =
518 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::SemanticTokens).await?;
519 match provider {
520 Some(registration) => {
521 let response = invoke_provider(
522 environment,
523 ®istration,
524 vec![
525 json!(registration.Handle),
526 json!({ "external": document_uri.to_string(), "$mid": 1 }),
527 ],
528 )
529 .await?;
530 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
531 },
532 None => Ok(None),
533 }
534}
535
536pub(super) async fn provide_inlay_hints(
537 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
538 document_uri:Url,
539 range_dto:Value,
540) -> Result<Option<Value>, CommonError> {
541 let provider =
542 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::InlayHint).await?;
543 match provider {
544 Some(registration) => {
545 let response = invoke_provider(
546 environment,
547 ®istration,
548 vec![
549 json!(registration.Handle),
550 json!({ "external": document_uri.to_string(), "$mid": 1 }),
551 range_dto,
552 ],
553 )
554 .await?;
555 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
556 },
557 None => Ok(None),
558 }
559}
560
561pub(super) async fn provide_type_hierarchy_supertypes(
562 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
563 item_dto:Value,
564) -> Result<Option<Value>, CommonError> {
565 let uri_str = item_dto.get("uri").and_then(|u| u.as_str()).unwrap_or("");
567 let document_uri = Url::parse(uri_str).unwrap_or_else(|_| Url::parse("file:///unknown").unwrap());
568 let provider =
569 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::TypeHierarchy).await?;
570 match provider {
571 Some(registration) => {
572 let response =
573 invoke_provider(environment, ®istration, vec![json!(registration.Handle), item_dto]).await?;
574 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
575 },
576 None => Ok(None),
577 }
578}
579
580pub(super) async fn provide_type_hierarchy_subtypes(
581 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
582 item_dto:Value,
583) -> Result<Option<Value>, CommonError> {
584 let uri_str = item_dto.get("uri").and_then(|u| u.as_str()).unwrap_or("");
585 let document_uri = Url::parse(uri_str).unwrap_or_else(|_| Url::parse("file:///unknown").unwrap());
586 let provider =
587 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::TypeHierarchy).await?;
588 match provider {
589 Some(registration) => {
590 let response =
591 invoke_provider(environment, ®istration, vec![json!(registration.Handle), item_dto]).await?;
592 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
593 },
594 None => Ok(None),
595 }
596}
597
598pub(super) async fn provide_call_hierarchy_incoming_calls(
599 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
600 item_dto:Value,
601) -> Result<Option<Value>, CommonError> {
602 let uri_str = item_dto.get("uri").and_then(|u| u.as_str()).unwrap_or("");
603 let document_uri = Url::parse(uri_str).unwrap_or_else(|_| Url::parse("file:///unknown").unwrap());
604 let provider =
605 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::CallHierarchy).await?;
606 match provider {
607 Some(registration) => {
608 let response =
609 invoke_provider(environment, ®istration, vec![json!(registration.Handle), item_dto]).await?;
610 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
611 },
612 None => Ok(None),
613 }
614}
615
616pub(super) async fn provide_call_hierarchy_outgoing_calls(
617 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
618 item_dto:Value,
619) -> Result<Option<Value>, CommonError> {
620 let uri_str = item_dto.get("uri").and_then(|u| u.as_str()).unwrap_or("");
621 let document_uri = Url::parse(uri_str).unwrap_or_else(|_| Url::parse("file:///unknown").unwrap());
622 let provider =
623 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::CallHierarchy).await?;
624 match provider {
625 Some(registration) => {
626 let response =
627 invoke_provider(environment, ®istration, vec![json!(registration.Handle), item_dto]).await?;
628 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
629 },
630 None => Ok(None),
631 }
632}
633
634pub(super) async fn provide_linked_editing_ranges(
635 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
636 document_uri:Url,
637 position_dto:PositionDTO,
638) -> Result<Option<Value>, CommonError> {
639 let provider =
640 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::LinkedEditingRange)
641 .await?;
642 match provider {
643 Some(registration) => {
644 let response = invoke_provider(
645 environment,
646 ®istration,
647 vec![
648 json!(registration.Handle),
649 json!({ "external": document_uri.to_string(), "$mid": 1 }),
650 json!(position_dto),
651 ],
652 )
653 .await?;
654 if response.is_null() { Ok(None) } else { Ok(Some(response)) }
655 },
656 None => Ok(None),
657 }
658}
659
660pub(super) async fn provide_on_type_formatting_edits(
661 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
662 document_uri:Url,
663 position_dto:PositionDTO,
664 character:String,
665 options_dto:Value,
666) -> Result<Option<Vec<TextEditDTO>>, CommonError> {
667 let provider =
668 super::ProviderLookup::get_matching_provider(environment, &document_uri, ProviderType::OnTypeFormatting)
669 .await?;
670 match provider {
671 Some(registration) => {
672 let response = invoke_provider(
673 environment,
674 ®istration,
675 vec![
676 json!(registration.Handle),
677 json!({ "external": document_uri.to_string(), "$mid": 1 }),
678 json!(position_dto),
679 json!(character),
680 options_dto,
681 ],
682 )
683 .await?;
684 if response.is_null() {
685 Ok(None)
686 } else {
687 serde_json::from_value(response).map_err(|error| {
688 CommonError::SerializationError {
689 Description:format!("Failed to deserialize Vec<TextEditDTO>: {}", error),
690 }
691 })
692 }
693 },
694 None => Ok(None),
695 }
696}
697
698async fn invoke_provider(
699 environment:&crate::Environment::MountainEnvironment::MountainEnvironment,
700 registration:&ProviderRegistrationDTO,
701 arguments:Vec<Value>,
702) -> Result<Value, CommonError> {
703 let rpc_method = format!("$provide{}", registration.ProviderType.to_string());
704 let ipc_provider:Arc<dyn IPCProvider> = environment.Require();
705 ipc_provider
706 .SendRequestToSideCar(registration.SideCarIdentifier.clone(), rpc_method, json!(arguments), 5000)
707 .await
708}