Skip to main content

Mountain/RPC/CocoonService/GenericNotification/
Dispatcher.rs

1//! Dispatcher for the generic `send_mountain_notification` gRPC endpoint.
2//!
3//! Legacy fire-and-forget rail used by Cocoon's
4//! `MountainGRPCClient.sendNotification(method, params)` for method names
5//! that predate the typed proto endpoints.
6
7use serde_json::json;
8use tonic::{Request, Response, Status};
9use CommonLibrary::{
10	Command::CommandExecutor::CommandExecutor,
11	LanguageFeature::{
12		DTO::ProviderType::ProviderType,
13		LanguageFeatureProviderRegistry::LanguageFeatureProviderRegistry,
14	},
15};
16use ::Vine::Generated::{Empty, GenericNotification as GenericNotificationMsg};
17
18use crate::{RPC::CocoonService::CocoonServiceImpl, dev_log};
19
20pub async fn Fn(
21	Service:&CocoonServiceImpl,
22
23	request:Request<GenericNotificationMsg>,
24) -> Result<Response<Empty>, Status> {
25	let notification = request.into_inner();
26
27	dev_log!(
28		"cocoon",
29		"[CocoonService] Notification router: method='{}'",
30		notification.method
31	);
32
33	// Deserialise notification parameters as JSON
34	let Params:serde_json::Value = if notification.parameter.is_empty() {
35		serde_json::Value::Null
36	} else {
37		serde_json::from_slice(&notification.parameter).unwrap_or(serde_json::Value::Null)
38	};
39
40	match notification.method.as_str() {
41		// ---- Commands ----
42		"registerCommand" => {
43			let CommandId = Params.get("commandId").and_then(|V| V.as_str()).unwrap_or("").to_string();
44
45			let ExtensionId = Params.get("extensionId").and_then(|V| V.as_str()).unwrap_or("").to_string();
46
47			if let Err(Error) = Service.environment.RegisterCommand(ExtensionId, CommandId.clone()).await {
48				dev_log!(
49					"cocoon",
50					"warn: [CocoonService] notification: registerCommand '{}' failed: {:?}",
51					CommandId,
52					Error
53				);
54			}
55		},
56
57		"unregisterCommand" => {
58			let ExtensionId = Params.get("extensionId").and_then(|V| V.as_str()).unwrap_or("").to_string();
59
60			let CommandId = Params.get("commandId").and_then(|V| V.as_str()).unwrap_or("").to_string();
61
62			let _ = Service.environment.UnregisterCommand(ExtensionId, CommandId).await;
63		},
64
65		// ---- Language Providers (APIFactoryService.ts register_*_provider strings) ----
66		"register_hover_provider" => {
67			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
68
69			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
70
71			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
72
73			Service.RegisterProvider(Handle, ProviderType::Hover, Selector, ExtId);
74		},
75
76		"register_completion_item_provider" => {
77			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
78
79			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
80
81			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
82
83			Service.RegisterProvider(Handle, ProviderType::Completion, Selector, ExtId);
84		},
85
86		"register_definition_provider" => {
87			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
88
89			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
90
91			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
92
93			Service.RegisterProvider(Handle, ProviderType::Definition, Selector, ExtId);
94		},
95
96		"register_reference_provider" => {
97			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
98
99			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
100
101			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
102
103			Service.RegisterProvider(Handle, ProviderType::References, Selector, ExtId);
104		},
105
106		"register_code_actions_provider" => {
107			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
108
109			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
110
111			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
112
113			Service.RegisterProvider(Handle, ProviderType::CodeAction, Selector, ExtId);
114		},
115
116		"register_document_highlight_provider" => {
117			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
118
119			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
120
121			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
122
123			Service.RegisterProvider(Handle, ProviderType::DocumentHighlight, Selector, ExtId);
124		},
125
126		"register_document_symbol_provider" => {
127			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
128
129			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
130
131			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
132
133			Service.RegisterProvider(Handle, ProviderType::DocumentSymbol, Selector, ExtId);
134		},
135
136		"register_workspace_symbol_provider" => {
137			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
138
139			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
140
141			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
142
143			Service.RegisterProvider(Handle, ProviderType::WorkspaceSymbol, Selector, ExtId);
144		},
145
146		"register_rename_provider" => {
147			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
148
149			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
150
151			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
152
153			Service.RegisterProvider(Handle, ProviderType::Rename, Selector, ExtId);
154		},
155
156		"register_document_formatting_provider" => {
157			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
158
159			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
160
161			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
162
163			Service.RegisterProvider(Handle, ProviderType::DocumentFormatting, Selector, ExtId);
164		},
165
166		"register_document_range_formatting_provider" => {
167			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
168
169			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
170
171			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
172
173			Service.RegisterProvider(Handle, ProviderType::DocumentRangeFormatting, Selector, ExtId);
174		},
175
176		"register_on_type_formatting_provider" => {
177			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
178
179			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
180
181			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
182
183			Service.RegisterProvider(Handle, ProviderType::OnTypeFormatting, Selector, ExtId);
184		},
185
186		"register_signature_help_provider" => {
187			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
188
189			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
190
191			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
192
193			Service.RegisterProvider(Handle, ProviderType::SignatureHelp, Selector, ExtId);
194		},
195
196		"register_code_lens_provider" => {
197			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
198
199			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
200
201			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
202
203			Service.RegisterProvider(Handle, ProviderType::CodeLens, Selector, ExtId);
204		},
205
206		"register_folding_range_provider" => {
207			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
208
209			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
210
211			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
212
213			Service.RegisterProvider(Handle, ProviderType::FoldingRange, Selector, ExtId);
214		},
215
216		"register_selection_range_provider" => {
217			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
218
219			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
220
221			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
222
223			Service.RegisterProvider(Handle, ProviderType::SelectionRange, Selector, ExtId);
224		},
225
226		"register_semantic_tokens_provider" => {
227			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
228
229			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
230
231			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
232
233			Service.RegisterProvider(Handle, ProviderType::SemanticTokens, Selector, ExtId);
234		},
235
236		"register_inlay_hints_provider" => {
237			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
238
239			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
240
241			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
242
243			Service.RegisterProvider(Handle, ProviderType::InlayHint, Selector, ExtId);
244		},
245
246		"register_type_hierarchy_provider" => {
247			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
248
249			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
250
251			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
252
253			Service.RegisterProvider(Handle, ProviderType::TypeHierarchy, Selector, ExtId);
254		},
255
256		"register_call_hierarchy_provider" => {
257			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
258
259			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
260
261			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
262
263			Service.RegisterProvider(Handle, ProviderType::CallHierarchy, Selector, ExtId);
264		},
265
266		"register_linked_editing_range_provider" => {
267			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
268
269			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
270
271			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
272
273			Service.RegisterProvider(Handle, ProviderType::LinkedEditingRange, Selector, ExtId);
274		},
275
276		"register_document_link_provider" => {
277			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
278
279			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
280
281			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
282
283			Service.RegisterProvider(Handle, ProviderType::DocumentLink, Selector, ExtId);
284		},
285
286		"register_color_provider" => {
287			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
288
289			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
290
291			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
292
293			Service.RegisterProvider(Handle, ProviderType::Color, Selector, ExtId);
294		},
295
296		"register_implementation_provider" => {
297			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
298
299			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
300
301			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
302
303			Service.RegisterProvider(Handle, ProviderType::Implementation, Selector, ExtId);
304		},
305
306		"register_type_definition_provider" => {
307			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
308
309			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
310
311			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
312
313			Service.RegisterProvider(Handle, ProviderType::TypeDefinition, Selector, ExtId);
314		},
315
316		"register_declaration_provider" => {
317			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
318
319			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
320
321			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
322
323			Service.RegisterProvider(Handle, ProviderType::Declaration, Selector, ExtId);
324		},
325
326		"register_evaluatable_expression_provider" => {
327			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
328
329			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
330
331			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
332
333			Service.RegisterProvider(Handle, ProviderType::EvaluatableExpression, Selector, ExtId);
334		},
335
336		"register_inline_values_provider" => {
337			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0) as u32;
338
339			let Selector = Params.get("language_selector").and_then(|V| V.as_str()).unwrap_or("*");
340
341			let ExtId = Params.get("extension_id").and_then(|V| V.as_str()).unwrap_or("");
342
343			Service.RegisterProvider(Handle, ProviderType::InlineValues, Selector, ExtId);
344		},
345
346		// ---- Webview ----
347		"onDidReceiveMessage" => {
348			use tauri::Emitter;
349
350			let Handle = Params.get("handle").and_then(|V| V.as_u64()).unwrap_or(0);
351
352			let Message = Params
353				.get("stringMessage")
354				.and_then(|V| V.as_str())
355				.map(|S| S.to_string())
356				.or_else(|| Params.get("bytesMessage").map(|_| "[binary]".to_string()))
357				.unwrap_or_default();
358
359			let _ = Service
360				.environment
361				.ApplicationHandle
362				.emit("sky://webview/postMessage", json!({ "handle": Handle, "message": Message }));
363		},
364
365		// ---- Secrets (fire-and-forget variants) ----
366		"storeSecret" => {
367			use CommonLibrary::Secret::SecretProvider::SecretProvider;
368
369			let ExtensionId = Params.get("extensionId").and_then(|V| V.as_str()).unwrap_or("").to_string();
370
371			let Key = Params.get("key").and_then(|V| V.as_str()).unwrap_or("").to_string();
372
373			let Value = Params.get("value").and_then(|V| V.as_str()).unwrap_or("").to_string();
374
375			let _ = Service.environment.StoreSecret(ExtensionId, Key, Value).await;
376		},
377
378		"deleteSecret" => {
379			use CommonLibrary::Secret::SecretProvider::SecretProvider;
380
381			let ExtensionId = Params.get("extensionId").and_then(|V| V.as_str()).unwrap_or("").to_string();
382
383			let Key = Params.get("key").and_then(|V| V.as_str()).unwrap_or("").to_string();
384
385			let _ = Service.environment.DeleteSecret(ExtensionId, Key).await;
386		},
387
388		// ---- File system (fire-and-forget write) ----
389		"writeFile" => {
390			let Uri = Params
391				.get("uri")
392				.and_then(|V| V.get("value").or(Some(V)))
393				.and_then(|V| V.as_str())
394				.unwrap_or("")
395				.replace("file://", "");
396
397			let Content:Vec<u8> = Params
398				.get("content")
399				.and_then(|V| V.as_array())
400				.map(|A| A.iter().filter_map(|B| B.as_u64().map(|N| N as u8)).collect())
401				.unwrap_or_default();
402
403			let _ = tokio::fs::write(&Uri, &Content).await;
404		},
405
406		// ---- Webview panel ----
407		"webview.postMessage" => {
408			use tauri::Emitter;
409
410			let PanelId = Params.get("panelId").and_then(|V| V.as_str()).unwrap_or("").to_string();
411
412			let Method = Params.get("method").and_then(|V| V.as_str()).unwrap_or("").to_string();
413
414			let MsgParams = Params.get("params").cloned().unwrap_or(serde_json::Value::Null);
415
416			let _ = Service.environment.ApplicationHandle.emit(
417				"sky://webview/message",
418				json!({ "panelId": PanelId, "method": Method, "params": MsgParams }),
419			);
420		},
421
422		"webview.dispose" => {
423			use tauri::Emitter;
424
425			let PanelId = Params.get("panelId").and_then(|V| V.as_str()).unwrap_or("").to_string();
426
427			let _ = Service
428				.environment
429				.ApplicationHandle
430				.emit("sky://webview/dispose", json!({ "panelId": PanelId }));
431		},
432
433		// ---- Progress indicator ----
434		"progress.start" => {
435			use tauri::Emitter;
436
437			let Id = Params.get("id").and_then(|V| V.as_str()).unwrap_or("").to_string();
438
439			let Title = Params.get("title").and_then(|V| V.as_str()).map(|S| S.to_string());
440
441			let Location = Params.get("location").cloned();
442
443			let Cancellable = Params.get("cancellable").and_then(|V| V.as_bool()).unwrap_or(false);
444
445			let _ = Service.environment.ApplicationHandle.emit(
446				"sky://progress/start",
447				json!({ "id": Id, "title": Title, "location": Location, "cancellable": Cancellable }),
448			);
449		},
450
451		"progress.update" => {
452			use tauri::Emitter;
453
454			let Id = Params.get("id").and_then(|V| V.as_str()).unwrap_or("").to_string();
455
456			let Message = Params.get("message").and_then(|V| V.as_str()).map(|S| S.to_string());
457
458			let Increment = Params.get("increment").and_then(|V| V.as_f64());
459
460			let _ = Service.environment.ApplicationHandle.emit(
461				"sky://progress/update",
462				json!({ "id": Id, "message": Message, "increment": Increment }),
463			);
464		},
465
466		"progress.complete" => {
467			use tauri::Emitter;
468
469			let Id = Params.get("id").and_then(|V| V.as_str()).unwrap_or("").to_string();
470
471			let _ = Service
472				.environment
473				.ApplicationHandle
474				.emit("sky://progress/complete", json!({ "id": Id }));
475		},
476
477		// ---- Native shell ----
478		"openExternal" => {
479			use tauri::Emitter;
480
481			let Url = Params.get("url").and_then(|V| V.as_str()).unwrap_or("").to_string();
482
483			let _ = Service
484				.environment
485				.ApplicationHandle
486				.emit("sky://native/openExternal", json!({ "url": Url }));
487		},
488
489		// ---- StatusBar updates (fire-and-forget from Window.ts setters) ----
490		"setStatusBarText" | "statusBar.setText" => {
491			use tauri::Emitter;
492
493			let ItemId = Params.get("itemId").and_then(|V| V.as_str()).unwrap_or("").to_string();
494
495			let Text = Params.get("text").and_then(|V| V.as_str()).unwrap_or("").to_string();
496
497			let _ = Service
498				.environment
499				.ApplicationHandle
500				.emit("sky://statusbar/update", json!({ "id": ItemId, "text": Text }));
501		},
502
503		"disposeStatusBarItem" | "statusBar.dispose" => {
504			use tauri::Emitter;
505
506			let ItemId = Params.get("itemId").and_then(|V| V.as_str()).unwrap_or("").to_string();
507
508			let _ = Service
509				.environment
510				.ApplicationHandle
511				.emit("sky://statusbar/dispose", json!({ "id": ItemId }));
512		},
513
514		// ---- Output channel (fire-and-forget from Window.ts OutputChannel proxy) ----
515		"output.create" => {
516			use tauri::Emitter;
517
518			let Id = Params.get("id").and_then(|V| V.as_str()).unwrap_or("").to_string();
519
520			let Name = Params.get("name").and_then(|V| V.as_str()).unwrap_or("").to_string();
521
522			let _ = Service
523				.environment
524				.ApplicationHandle
525				.emit("sky://output/create", json!({ "id": Id, "name": Name }));
526		},
527
528		"output.append" => {
529			use tauri::Emitter;
530
531			let Channel = Params.get("channel").and_then(|V| V.as_str()).unwrap_or("").to_string();
532
533			let Text = Params.get("value").and_then(|V| V.as_str()).unwrap_or("").to_string();
534
535			let _ = Service
536				.environment
537				.ApplicationHandle
538				.emit("sky://output/append", json!({ "channel": Channel, "text": Text }));
539		},
540
541		"output.appendLine" => {
542			use tauri::Emitter;
543
544			let Channel = Params.get("channel").and_then(|V| V.as_str()).unwrap_or("").to_string();
545
546			let Line = Params.get("value").and_then(|V| V.as_str()).unwrap_or("").to_string();
547
548			let _ = Service.environment.ApplicationHandle.emit(
549				"sky://output/append",
550				json!({ "channel": Channel, "text": format!("{}\n", Line) }),
551			);
552		},
553
554		"output.clear" => {
555			use tauri::Emitter;
556
557			let Channel = Params.get("channel").and_then(|V| V.as_str()).unwrap_or("").to_string();
558
559			let _ = Service
560				.environment
561				.ApplicationHandle
562				.emit("sky://output/clear", json!({ "channel": Channel }));
563		},
564
565		"output.show" => {
566			use tauri::Emitter;
567
568			let Channel = Params.get("channel").and_then(|V| V.as_str()).unwrap_or("").to_string();
569
570			let _ = Service
571				.environment
572				.ApplicationHandle
573				.emit("sky://output/show", json!({ "channel": Channel }));
574		},
575
576		"output.dispose" => {
577			use tauri::Emitter;
578
579			let Channel = Params.get("channel").and_then(|V| V.as_str()).unwrap_or("").to_string();
580
581			let _ = Service
582				.environment
583				.ApplicationHandle
584				.emit("sky://output/dispose", json!({ "channel": Channel }));
585		},
586
587		// ---- Language configuration ----
588		"set_language_configuration" => {
589			// Forward the full params (language + configuration) to Sky so
590			// Monaco's setLanguageConfiguration() receives the actual rules.
591			use tauri::Emitter;
592
593			let _ = Service.environment.ApplicationHandle.emit("sky://language/configure", &Params);
594		},
595
596		_ => {
597			dev_log!(
598				"cocoon",
599				"[CocoonService] Unknown notification method: '{}'",
600				notification.method
601			);
602		},
603	}
604
605	Ok(Response::new(Empty {}))
606}