proto.rs

  1#![allow(non_snake_case)]
  2
  3pub mod error;
  4mod macros;
  5mod typed_envelope;
  6
  7pub use error::*;
  8pub use typed_envelope::*;
  9
 10use collections::HashMap;
 11pub use prost::Message;
 12use serde::Serialize;
 13use std::any::{Any, TypeId};
 14use std::time::Instant;
 15use std::{
 16    cmp,
 17    fmt::Debug,
 18    iter,
 19    time::{Duration, SystemTime, UNIX_EPOCH},
 20};
 21use std::{fmt, mem};
 22
 23include!(concat!(env!("OUT_DIR"), "/zed.messages.rs"));
 24
 25pub trait EnvelopedMessage: Clone + Debug + Serialize + Sized + Send + Sync + 'static {
 26    const NAME: &'static str;
 27    const PRIORITY: MessagePriority;
 28    fn into_envelope(
 29        self,
 30        id: u32,
 31        responding_to: Option<u32>,
 32        original_sender_id: Option<PeerId>,
 33    ) -> Envelope;
 34    fn from_envelope(envelope: Envelope) -> Option<Self>;
 35}
 36
 37pub trait EntityMessage: EnvelopedMessage {
 38    type Entity;
 39    fn remote_entity_id(&self) -> u64;
 40}
 41
 42pub trait RequestMessage: EnvelopedMessage {
 43    type Response: EnvelopedMessage;
 44}
 45
 46pub trait AnyTypedEnvelope: 'static + Send + Sync {
 47    fn payload_type_id(&self) -> TypeId;
 48    fn payload_type_name(&self) -> &'static str;
 49    fn as_any(&self) -> &dyn Any;
 50    fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync>;
 51    fn is_background(&self) -> bool;
 52    fn original_sender_id(&self) -> Option<PeerId>;
 53    fn sender_id(&self) -> PeerId;
 54    fn message_id(&self) -> u32;
 55}
 56
 57pub enum MessagePriority {
 58    Foreground,
 59    Background,
 60}
 61
 62impl<T: EnvelopedMessage> AnyTypedEnvelope for TypedEnvelope<T> {
 63    fn payload_type_id(&self) -> TypeId {
 64        TypeId::of::<T>()
 65    }
 66
 67    fn payload_type_name(&self) -> &'static str {
 68        T::NAME
 69    }
 70
 71    fn as_any(&self) -> &dyn Any {
 72        self
 73    }
 74
 75    fn into_any(self: Box<Self>) -> Box<dyn Any + Send + Sync> {
 76        self
 77    }
 78
 79    fn is_background(&self) -> bool {
 80        matches!(T::PRIORITY, MessagePriority::Background)
 81    }
 82
 83    fn original_sender_id(&self) -> Option<PeerId> {
 84        self.original_sender_id
 85    }
 86
 87    fn sender_id(&self) -> PeerId {
 88        self.sender_id
 89    }
 90
 91    fn message_id(&self) -> u32 {
 92        self.message_id
 93    }
 94}
 95
 96impl PeerId {
 97    pub fn from_u64(peer_id: u64) -> Self {
 98        let owner_id = (peer_id >> 32) as u32;
 99        let id = peer_id as u32;
100        Self { owner_id, id }
101    }
102
103    pub fn as_u64(self) -> u64 {
104        ((self.owner_id as u64) << 32) | (self.id as u64)
105    }
106}
107
108impl Copy for PeerId {}
109
110impl Eq for PeerId {}
111
112impl Ord for PeerId {
113    fn cmp(&self, other: &Self) -> cmp::Ordering {
114        self.owner_id
115            .cmp(&other.owner_id)
116            .then_with(|| self.id.cmp(&other.id))
117    }
118}
119
120impl PartialOrd for PeerId {
121    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
122        Some(self.cmp(other))
123    }
124}
125
126impl std::hash::Hash for PeerId {
127    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
128        self.owner_id.hash(state);
129        self.id.hash(state);
130    }
131}
132
133impl fmt::Display for PeerId {
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        write!(f, "{}/{}", self.owner_id, self.id)
136    }
137}
138
139messages!(
140    (Ack, Foreground),
141    (AckBufferOperation, Background),
142    (AckChannelMessage, Background),
143    (AddNotification, Foreground),
144    (AddProjectCollaborator, Foreground),
145    (ApplyCodeAction, Background),
146    (ApplyCodeActionResponse, Background),
147    (ApplyCompletionAdditionalEdits, Background),
148    (ApplyCompletionAdditionalEditsResponse, Background),
149    (BufferReloaded, Foreground),
150    (BufferSaved, Foreground),
151    (Call, Foreground),
152    (CallCanceled, Foreground),
153    (CancelCall, Foreground),
154    (ChannelMessageSent, Foreground),
155    (ChannelMessageUpdate, Foreground),
156    (CompleteWithLanguageModel, Background),
157    (ComputeEmbeddings, Background),
158    (ComputeEmbeddingsResponse, Background),
159    (CopyProjectEntry, Foreground),
160    (CountTokensWithLanguageModel, Background),
161    (CountTokensResponse, Background),
162    (CreateBufferForPeer, Foreground),
163    (CreateChannel, Foreground),
164    (CreateChannelResponse, Foreground),
165    (CreateProjectEntry, Foreground),
166    (CreateRoom, Foreground),
167    (CreateRoomResponse, Foreground),
168    (DeclineCall, Foreground),
169    (DeleteChannel, Foreground),
170    (DeleteNotification, Foreground),
171    (UpdateNotification, Foreground),
172    (DeleteProjectEntry, Foreground),
173    (EndStream, Foreground),
174    (Error, Foreground),
175    (ExpandProjectEntry, Foreground),
176    (ExpandProjectEntryResponse, Foreground),
177    (Follow, Foreground),
178    (FollowResponse, Foreground),
179    (FormatBuffers, Foreground),
180    (FormatBuffersResponse, Foreground),
181    (FuzzySearchUsers, Foreground),
182    (GetCachedEmbeddings, Background),
183    (GetCachedEmbeddingsResponse, Background),
184    (GetChannelMembers, Foreground),
185    (GetChannelMembersResponse, Foreground),
186    (GetChannelMessages, Background),
187    (GetChannelMessagesById, Background),
188    (GetChannelMessagesResponse, Background),
189    (GetCodeActions, Background),
190    (GetCodeActionsResponse, Background),
191    (GetCompletions, Background),
192    (GetCompletionsResponse, Background),
193    (GetDefinition, Background),
194    (GetDefinitionResponse, Background),
195    (GetDocumentHighlights, Background),
196    (GetDocumentHighlightsResponse, Background),
197    (GetHover, Background),
198    (GetHoverResponse, Background),
199    (GetNotifications, Foreground),
200    (GetNotificationsResponse, Foreground),
201    (GetPrivateUserInfo, Foreground),
202    (GetPrivateUserInfoResponse, Foreground),
203    (GetProjectSymbols, Background),
204    (GetProjectSymbolsResponse, Background),
205    (GetReferences, Background),
206    (GetReferencesResponse, Background),
207    (GetSupermavenApiKey, Background),
208    (GetSupermavenApiKeyResponse, Background),
209    (GetTypeDefinition, Background),
210    (GetTypeDefinitionResponse, Background),
211    (GetImplementation, Background),
212    (GetImplementationResponse, Background),
213    (GetUsers, Foreground),
214    (Hello, Foreground),
215    (IncomingCall, Foreground),
216    (InlayHints, Background),
217    (InlayHintsResponse, Background),
218    (InviteChannelMember, Foreground),
219    (JoinChannel, Foreground),
220    (JoinChannelBuffer, Foreground),
221    (JoinChannelBufferResponse, Foreground),
222    (JoinChannelChat, Foreground),
223    (JoinChannelChatResponse, Foreground),
224    (JoinProject, Foreground),
225    (JoinHostedProject, Foreground),
226    (JoinProjectResponse, Foreground),
227    (JoinRoom, Foreground),
228    (JoinRoomResponse, Foreground),
229    (LanguageModelResponse, Background),
230    (LeaveChannelBuffer, Background),
231    (LeaveChannelChat, Foreground),
232    (LeaveProject, Foreground),
233    (LeaveRoom, Foreground),
234    (MarkNotificationRead, Foreground),
235    (MoveChannel, Foreground),
236    (OnTypeFormatting, Background),
237    (OnTypeFormattingResponse, Background),
238    (OpenBufferById, Background),
239    (OpenBufferByPath, Background),
240    (OpenBufferForSymbol, Background),
241    (OpenBufferForSymbolResponse, Background),
242    (OpenBufferResponse, Background),
243    (PerformRename, Background),
244    (PerformRenameResponse, Background),
245    (Ping, Foreground),
246    (PrepareRename, Background),
247    (PrepareRenameResponse, Background),
248    (ProjectEntryResponse, Foreground),
249    (RefreshInlayHints, Foreground),
250    (RejoinChannelBuffers, Foreground),
251    (RejoinChannelBuffersResponse, Foreground),
252    (RejoinRoom, Foreground),
253    (RejoinRoomResponse, Foreground),
254    (ReloadBuffers, Foreground),
255    (ReloadBuffersResponse, Foreground),
256    (RemoveChannelMember, Foreground),
257    (RemoveChannelMessage, Foreground),
258    (UpdateChannelMessage, Foreground),
259    (RemoveContact, Foreground),
260    (RemoveProjectCollaborator, Foreground),
261    (RenameChannel, Foreground),
262    (RenameChannelResponse, Foreground),
263    (RenameProjectEntry, Foreground),
264    (RequestContact, Foreground),
265    (ResolveCompletionDocumentation, Background),
266    (ResolveCompletionDocumentationResponse, Background),
267    (ResolveInlayHint, Background),
268    (ResolveInlayHintResponse, Background),
269    (RespondToChannelInvite, Foreground),
270    (RespondToContactRequest, Foreground),
271    (RoomUpdated, Foreground),
272    (SaveBuffer, Foreground),
273    (SetChannelMemberRole, Foreground),
274    (SetChannelVisibility, Foreground),
275    (SearchProject, Background),
276    (SearchProjectResponse, Background),
277    (SendChannelMessage, Background),
278    (SendChannelMessageResponse, Background),
279    (ShareProject, Foreground),
280    (ShareProjectResponse, Foreground),
281    (ShowContacts, Foreground),
282    (StartLanguageServer, Foreground),
283    (SubscribeToChannels, Foreground),
284    (SynchronizeBuffers, Foreground),
285    (SynchronizeBuffersResponse, Foreground),
286    (TaskContextForLocation, Background),
287    (TaskContext, Background),
288    (TaskTemplates, Background),
289    (TaskTemplatesResponse, Background),
290    (Test, Foreground),
291    (Unfollow, Foreground),
292    (UnshareProject, Foreground),
293    (UpdateBuffer, Foreground),
294    (UpdateBufferFile, Foreground),
295    (UpdateChannelBuffer, Foreground),
296    (UpdateChannelBufferCollaborators, Foreground),
297    (UpdateChannels, Foreground),
298    (UpdateUserChannels, Foreground),
299    (UpdateContacts, Foreground),
300    (UpdateDiagnosticSummary, Foreground),
301    (UpdateDiffBase, Foreground),
302    (UpdateFollowers, Foreground),
303    (UpdateInviteInfo, Foreground),
304    (UpdateLanguageServer, Foreground),
305    (UpdateParticipantLocation, Foreground),
306    (UpdateProject, Foreground),
307    (UpdateProjectCollaborator, Foreground),
308    (UpdateWorktree, Foreground),
309    (UpdateWorktreeSettings, Foreground),
310    (UsersResponse, Foreground),
311    (LspExtExpandMacro, Background),
312    (LspExtExpandMacroResponse, Background),
313    (SetRoomParticipantRole, Foreground),
314    (BlameBuffer, Foreground),
315    (BlameBufferResponse, Foreground),
316    (CreateDevServerProject, Background),
317    (CreateDevServerProjectResponse, Foreground),
318    (CreateDevServer, Foreground),
319    (CreateDevServerResponse, Foreground),
320    (DevServerInstructions, Foreground),
321    (ShutdownDevServer, Foreground),
322    (ReconnectDevServer, Foreground),
323    (ReconnectDevServerResponse, Foreground),
324    (ShareDevServerProject, Foreground),
325    (JoinDevServerProject, Foreground),
326    (RejoinRemoteProjects, Foreground),
327    (RejoinRemoteProjectsResponse, Foreground),
328    (MultiLspQuery, Background),
329    (MultiLspQueryResponse, Background),
330    (DevServerProjectsUpdate, Foreground),
331    (ValidateDevServerProjectRequest, Background),
332    (DeleteDevServer, Foreground),
333    (DeleteDevServerProject, Foreground),
334    (RegenerateDevServerToken, Foreground),
335    (RegenerateDevServerTokenResponse, Foreground),
336    (RenameDevServer, Foreground),
337    (OpenNewBuffer, Foreground),
338    (RestartLanguageServers, Foreground),
339    (LinkedEditingRange, Background),
340    (LinkedEditingRangeResponse, Background)
341);
342
343request_messages!(
344    (ApplyCodeAction, ApplyCodeActionResponse),
345    (
346        ApplyCompletionAdditionalEdits,
347        ApplyCompletionAdditionalEditsResponse
348    ),
349    (Call, Ack),
350    (CancelCall, Ack),
351    (CopyProjectEntry, ProjectEntryResponse),
352    (CompleteWithLanguageModel, LanguageModelResponse),
353    (ComputeEmbeddings, ComputeEmbeddingsResponse),
354    (CountTokensWithLanguageModel, CountTokensResponse),
355    (CreateChannel, CreateChannelResponse),
356    (CreateProjectEntry, ProjectEntryResponse),
357    (CreateRoom, CreateRoomResponse),
358    (DeclineCall, Ack),
359    (DeleteChannel, Ack),
360    (DeleteProjectEntry, ProjectEntryResponse),
361    (ExpandProjectEntry, ExpandProjectEntryResponse),
362    (Follow, FollowResponse),
363    (FormatBuffers, FormatBuffersResponse),
364    (FuzzySearchUsers, UsersResponse),
365    (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
366    (GetChannelMembers, GetChannelMembersResponse),
367    (GetChannelMessages, GetChannelMessagesResponse),
368    (GetChannelMessagesById, GetChannelMessagesResponse),
369    (GetCodeActions, GetCodeActionsResponse),
370    (GetCompletions, GetCompletionsResponse),
371    (GetDefinition, GetDefinitionResponse),
372    (GetImplementation, GetImplementationResponse),
373    (GetDocumentHighlights, GetDocumentHighlightsResponse),
374    (GetHover, GetHoverResponse),
375    (GetNotifications, GetNotificationsResponse),
376    (GetPrivateUserInfo, GetPrivateUserInfoResponse),
377    (GetProjectSymbols, GetProjectSymbolsResponse),
378    (GetReferences, GetReferencesResponse),
379    (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
380    (GetTypeDefinition, GetTypeDefinitionResponse),
381    (LinkedEditingRange, LinkedEditingRangeResponse),
382    (GetUsers, UsersResponse),
383    (IncomingCall, Ack),
384    (InlayHints, InlayHintsResponse),
385    (InviteChannelMember, Ack),
386    (JoinChannel, JoinRoomResponse),
387    (JoinChannelBuffer, JoinChannelBufferResponse),
388    (JoinChannelChat, JoinChannelChatResponse),
389    (JoinHostedProject, JoinProjectResponse),
390    (JoinProject, JoinProjectResponse),
391    (JoinRoom, JoinRoomResponse),
392    (LeaveChannelBuffer, Ack),
393    (LeaveRoom, Ack),
394    (MarkNotificationRead, Ack),
395    (MoveChannel, Ack),
396    (OnTypeFormatting, OnTypeFormattingResponse),
397    (OpenBufferById, OpenBufferResponse),
398    (OpenBufferByPath, OpenBufferResponse),
399    (OpenBufferForSymbol, OpenBufferForSymbolResponse),
400    (OpenNewBuffer, OpenBufferResponse),
401    (PerformRename, PerformRenameResponse),
402    (Ping, Ack),
403    (PrepareRename, PrepareRenameResponse),
404    (RefreshInlayHints, Ack),
405    (RejoinChannelBuffers, RejoinChannelBuffersResponse),
406    (RejoinRoom, RejoinRoomResponse),
407    (ReloadBuffers, ReloadBuffersResponse),
408    (RemoveChannelMember, Ack),
409    (RemoveChannelMessage, Ack),
410    (UpdateChannelMessage, Ack),
411    (RemoveContact, Ack),
412    (RenameChannel, RenameChannelResponse),
413    (RenameProjectEntry, ProjectEntryResponse),
414    (RequestContact, Ack),
415    (
416        ResolveCompletionDocumentation,
417        ResolveCompletionDocumentationResponse
418    ),
419    (ResolveInlayHint, ResolveInlayHintResponse),
420    (RespondToChannelInvite, Ack),
421    (RespondToContactRequest, Ack),
422    (SaveBuffer, BufferSaved),
423    (SearchProject, SearchProjectResponse),
424    (SendChannelMessage, SendChannelMessageResponse),
425    (SetChannelMemberRole, Ack),
426    (SetChannelVisibility, Ack),
427    (ShareProject, ShareProjectResponse),
428    (SynchronizeBuffers, SynchronizeBuffersResponse),
429    (TaskContextForLocation, TaskContext),
430    (TaskTemplates, TaskTemplatesResponse),
431    (Test, Test),
432    (UpdateBuffer, Ack),
433    (UpdateParticipantLocation, Ack),
434    (UpdateProject, Ack),
435    (UpdateWorktree, Ack),
436    (LspExtExpandMacro, LspExtExpandMacroResponse),
437    (SetRoomParticipantRole, Ack),
438    (BlameBuffer, BlameBufferResponse),
439    (CreateDevServerProject, CreateDevServerProjectResponse),
440    (CreateDevServer, CreateDevServerResponse),
441    (ShutdownDevServer, Ack),
442    (ShareDevServerProject, ShareProjectResponse),
443    (JoinDevServerProject, JoinProjectResponse),
444    (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
445    (ReconnectDevServer, ReconnectDevServerResponse),
446    (ValidateDevServerProjectRequest, Ack),
447    (MultiLspQuery, MultiLspQueryResponse),
448    (DeleteDevServer, Ack),
449    (DeleteDevServerProject, Ack),
450    (RegenerateDevServerToken, RegenerateDevServerTokenResponse),
451    (RenameDevServer, Ack),
452    (RestartLanguageServers, Ack)
453);
454
455entity_messages!(
456    {project_id, ShareProject},
457    AddProjectCollaborator,
458    ApplyCodeAction,
459    ApplyCompletionAdditionalEdits,
460    BlameBuffer,
461    BufferReloaded,
462    BufferSaved,
463    CopyProjectEntry,
464    CreateBufferForPeer,
465    CreateProjectEntry,
466    DeleteProjectEntry,
467    ExpandProjectEntry,
468    FormatBuffers,
469    GetCodeActions,
470    GetCompletions,
471    GetDefinition,
472    GetImplementation,
473    GetDocumentHighlights,
474    GetHover,
475    GetProjectSymbols,
476    GetReferences,
477    GetTypeDefinition,
478    InlayHints,
479    JoinProject,
480    LeaveProject,
481    LinkedEditingRange,
482    MultiLspQuery,
483    RestartLanguageServers,
484    OnTypeFormatting,
485    OpenNewBuffer,
486    OpenBufferById,
487    OpenBufferByPath,
488    OpenBufferForSymbol,
489    PerformRename,
490    PrepareRename,
491    RefreshInlayHints,
492    ReloadBuffers,
493    RemoveProjectCollaborator,
494    RenameProjectEntry,
495    ResolveCompletionDocumentation,
496    ResolveInlayHint,
497    SaveBuffer,
498    SearchProject,
499    StartLanguageServer,
500    SynchronizeBuffers,
501    TaskContextForLocation,
502    TaskTemplates,
503    UnshareProject,
504    UpdateBuffer,
505    UpdateBufferFile,
506    UpdateDiagnosticSummary,
507    UpdateDiffBase,
508    UpdateLanguageServer,
509    UpdateProject,
510    UpdateProjectCollaborator,
511    UpdateWorktree,
512    UpdateWorktreeSettings,
513    LspExtExpandMacro,
514);
515
516entity_messages!(
517    {channel_id, Channel},
518    ChannelMessageSent,
519    ChannelMessageUpdate,
520    RemoveChannelMessage,
521    UpdateChannelMessage,
522    UpdateChannelBuffer,
523    UpdateChannelBufferCollaborators,
524);
525
526impl From<Timestamp> for SystemTime {
527    fn from(val: Timestamp) -> Self {
528        UNIX_EPOCH
529            .checked_add(Duration::new(val.seconds, val.nanos))
530            .unwrap()
531    }
532}
533
534impl From<SystemTime> for Timestamp {
535    fn from(time: SystemTime) -> Self {
536        let duration = time.duration_since(UNIX_EPOCH).unwrap();
537        Self {
538            seconds: duration.as_secs(),
539            nanos: duration.subsec_nanos(),
540        }
541    }
542}
543
544impl From<u128> for Nonce {
545    fn from(nonce: u128) -> Self {
546        let upper_half = (nonce >> 64) as u64;
547        let lower_half = nonce as u64;
548        Self {
549            upper_half,
550            lower_half,
551        }
552    }
553}
554
555impl From<Nonce> for u128 {
556    fn from(nonce: Nonce) -> Self {
557        let upper_half = (nonce.upper_half as u128) << 64;
558        let lower_half = nonce.lower_half as u128;
559        upper_half | lower_half
560    }
561}
562
563pub fn split_worktree_update(
564    mut message: UpdateWorktree,
565    max_chunk_size: usize,
566) -> impl Iterator<Item = UpdateWorktree> {
567    let mut done_files = false;
568
569    let mut repository_map = message
570        .updated_repositories
571        .into_iter()
572        .map(|repo| (repo.work_directory_id, repo))
573        .collect::<HashMap<_, _>>();
574
575    iter::from_fn(move || {
576        if done_files {
577            return None;
578        }
579
580        let updated_entries_chunk_size = cmp::min(message.updated_entries.len(), max_chunk_size);
581        let updated_entries: Vec<_> = message
582            .updated_entries
583            .drain(..updated_entries_chunk_size)
584            .collect();
585
586        let removed_entries_chunk_size = cmp::min(message.removed_entries.len(), max_chunk_size);
587        let removed_entries = message
588            .removed_entries
589            .drain(..removed_entries_chunk_size)
590            .collect();
591
592        done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
593
594        let mut updated_repositories = Vec::new();
595
596        if !repository_map.is_empty() {
597            for entry in &updated_entries {
598                if let Some(repo) = repository_map.remove(&entry.id) {
599                    updated_repositories.push(repo)
600                }
601            }
602        }
603
604        let removed_repositories = if done_files {
605            mem::take(&mut message.removed_repositories)
606        } else {
607            Default::default()
608        };
609
610        if done_files {
611            updated_repositories.extend(mem::take(&mut repository_map).into_values());
612        }
613
614        Some(UpdateWorktree {
615            project_id: message.project_id,
616            worktree_id: message.worktree_id,
617            root_name: message.root_name.clone(),
618            abs_path: message.abs_path.clone(),
619            updated_entries,
620            removed_entries,
621            scan_id: message.scan_id,
622            is_last_update: done_files && message.is_last_update,
623            updated_repositories,
624            removed_repositories,
625        })
626    })
627}
628
629#[cfg(test)]
630mod tests {
631    use super::*;
632
633    #[test]
634    fn test_converting_peer_id_from_and_to_u64() {
635        let peer_id = PeerId {
636            owner_id: 10,
637            id: 3,
638        };
639        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
640        let peer_id = PeerId {
641            owner_id: u32::MAX,
642            id: 3,
643        };
644        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
645        let peer_id = PeerId {
646            owner_id: 10,
647            id: u32::MAX,
648        };
649        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
650        let peer_id = PeerId {
651            owner_id: u32::MAX,
652            id: u32::MAX,
653        };
654        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
655    }
656}