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