Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/Vine/Server/Notification/
RegisterLanguageProvider.rs

1//! Handles all `register_*` / `register_*_provider` gRPC notifications from
2//! the Cocoon extension host. Each such notification wires a language-feature
3//! provider into Mountain's `ProviderRegistration` keyed on `Handle`; the
4//! language-feature RPC path (e.g. `GetHoverAtPosition`) then proxies back to
5//! Cocoon with the original `$providerXxx` method.
6//!
7//! Wire-method naming uses snake_case with two trailing shapes:
8//! - plain verbs:     `register_rename`, `register_debug_adapter`
9//! - `_provider` suffix: `register_hover_provider`,
10//!   `register_code_lens_provider`
11//!
12//! Both forms are normalised by stripping `register_` prefix and optional
13//! `_provider` suffix before the enum lookup.
14
15use CommonLibrary::LanguageFeature::DTO::ProviderType::ProviderType as PT;
16use serde_json::{Value, json};
17
18use crate::{
19	ApplicationState::DTO::ProviderRegistrationDTO::ProviderRegistrationDTO,
20	Vine::Server::MountainVinegRPCService::MountainVinegRPCService,
21	dev_log,
22};
23
24/// Dispatch a `register_*` notification. Returns `true` if the method was
25/// recognised and a `ProviderRegistrationDTO` was inserted.
26pub async fn RegisterLanguageProvider(Service:&MountainVinegRPCService, MethodName:&str, Parameter:&Value) -> bool {
27	let Handle = Parameter.get("handle").and_then(|h| h.as_u64()).unwrap_or(0) as u32;
28
29	// Accept camelCase (current Cocoon shape) with snake_case fallback for
30	// partial rebuild compatibility.
31	let Selector = Parameter
32		.get("languageSelector")
33		.or_else(|| Parameter.get("language_selector"))
34		.and_then(|s| s.as_str())
35		.unwrap_or("*");
36
37	let ExtId = Parameter
38		.get("extensionId")
39		.or_else(|| Parameter.get("extension_id"))
40		.and_then(|e| e.as_str())
41		.unwrap_or("");
42
43	let Scheme = Parameter.get("scheme").and_then(|s| s.as_str()).unwrap_or("");
44
45	let ProviderTypeName = MethodName
46		.strip_prefix("register_")
47		.map(|Stripped| Stripped.strip_suffix("_provider").unwrap_or(Stripped))
48		.unwrap_or("");
49
50	dev_log!(
51		"grpc-verbose",
52		"[MountainVinegRPCService] Cocoon registered {} provider: handle={}, lang={}",
53		ProviderTypeName,
54		Handle,
55		Selector
56	);
57
58	dev_log!(
59		"provider-register",
60		"[ProviderRegister] accepted method={} type={} handle={} lang={} scheme={} ext={}",
61		MethodName,
62		ProviderTypeName,
63		Handle,
64		Selector,
65		Scheme,
66		ExtId
67	);
68
69	let ProvType:Option<PT> = match ProviderTypeName {
70		"authentication" => Some(PT::Authentication),
71
72		"call_hierarchy" => Some(PT::CallHierarchy),
73
74		"code_actions" => Some(PT::CodeAction),
75
76		"code_lens" => Some(PT::CodeLens),
77
78		"color" => Some(PT::Color),
79
80		"completion_item" => Some(PT::Completion),
81
82		"debug_adapter" => Some(PT::DebugAdapter),
83
84		"debug_configuration" => Some(PT::DebugConfiguration),
85
86		"declaration" => Some(PT::Declaration),
87
88		"definition" => Some(PT::Definition),
89
90		"document_drop_edit" => Some(PT::DocumentDropEdit),
91
92		"document_formatting" => Some(PT::DocumentFormatting),
93
94		"document_highlight" => Some(PT::DocumentHighlight),
95
96		"document_link" => Some(PT::DocumentLink),
97
98		"document_paste_edit" => Some(PT::DocumentPasteEdit),
99
100		"document_range_formatting" => Some(PT::DocumentRangeFormatting),
101
102		"document_symbol" => Some(PT::DocumentSymbol),
103
104		"evaluatable_expression" => Some(PT::EvaluatableExpression),
105
106		"external_uri_opener" => Some(PT::ExternalUriOpener),
107
108		"file_decoration" => Some(PT::FileDecoration),
109
110		"file_system" => Some(PT::FileSystem),
111
112		"folding_range" => Some(PT::FoldingRange),
113
114		"hover" => Some(PT::Hover),
115
116		"implementation" => Some(PT::Implementation),
117
118		"inlay_hints" => Some(PT::InlayHint),
119
120		"inline_completion_item" => Some(PT::InlineCompletion),
121
122		"inline_edit" => Some(PT::InlineEdit),
123
124		"inline_values" => Some(PT::InlineValues),
125
126		"linked_editing_range" => Some(PT::LinkedEditingRange),
127
128		"mapped_edits" => Some(PT::MappedEdits),
129
130		"multi_document_highlight" => Some(PT::MultiDocumentHighlight),
131
132		"notebook_content" => Some(PT::NotebookContent),
133
134		"notebook_serializer" => Some(PT::NotebookSerializer),
135
136		"on_type_formatting" => Some(PT::OnTypeFormatting),
137
138		"reference" => Some(PT::References),
139
140		"remote_authority_resolver" => Some(PT::RemoteAuthorityResolver),
141
142		"rename" => Some(PT::Rename),
143
144		"resource_label_formatter" => Some(PT::ResourceLabelFormatter),
145
146		"scm" => Some(PT::SourceControl),
147
148		"scm_resource_group" => Some(PT::ScmResourceGroup),
149
150		"selection_range" => Some(PT::SelectionRange),
151
152		"semantic_tokens" => Some(PT::SemanticTokens),
153
154		"signature_help" => Some(PT::SignatureHelp),
155
156		"task" => Some(PT::Task),
157
158		"terminal_link" => Some(PT::TerminalLink),
159
160		"terminal_profile" => Some(PT::TerminalProfile),
161
162		"text_document_content" => Some(PT::TextDocumentContent),
163
164		"type_definition" => Some(PT::TypeDefinition),
165
166		"type_hierarchy" => Some(PT::TypeHierarchy),
167
168		"uri_handler" => Some(PT::UriHandler),
169
170		"workspace_symbol" => Some(PT::WorkspaceSymbol),
171
172		_ => None,
173	};
174
175	let Some(ProviderType) = ProvType else { return false };
176
177	// Scheme-bound providers carry their scheme in the selector so Mountain's
178	// resolver (FileSystem router, URI handler dispatch, …) can match on it.
179	let SelectorValue = if !Scheme.is_empty() {
180		json!([{ "scheme": Scheme, "language": Selector }])
181	} else {
182		json!([{ "language": Selector }])
183	};
184
185	let Dto = ProviderRegistrationDTO {
186		Handle,
187
188		ProviderType,
189
190		Selector:SelectorValue,
191
192		SideCarIdentifier:"cocoon-main".to_string(),
193
194		ExtensionIdentifier:json!(ExtId),
195
196		Options:Parameter.get("options").cloned(),
197	};
198
199	Service
200		.RunTime()
201		.Environment
202		.ApplicationState
203		.Extension
204		.ProviderRegistration
205		.RegisterProvider(Handle, Dto);
206
207	true
208}