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);
340
341request_messages!(
342    (ApplyCodeAction, ApplyCodeActionResponse),
343    (
344        ApplyCompletionAdditionalEdits,
345        ApplyCompletionAdditionalEditsResponse
346    ),
347    (Call, Ack),
348    (CancelCall, Ack),
349    (CopyProjectEntry, ProjectEntryResponse),
350    (CompleteWithLanguageModel, LanguageModelResponse),
351    (ComputeEmbeddings, ComputeEmbeddingsResponse),
352    (CountTokensWithLanguageModel, CountTokensResponse),
353    (CreateChannel, CreateChannelResponse),
354    (CreateProjectEntry, ProjectEntryResponse),
355    (CreateRoom, CreateRoomResponse),
356    (DeclineCall, Ack),
357    (DeleteChannel, Ack),
358    (DeleteProjectEntry, ProjectEntryResponse),
359    (ExpandProjectEntry, ExpandProjectEntryResponse),
360    (Follow, FollowResponse),
361    (FormatBuffers, FormatBuffersResponse),
362    (FuzzySearchUsers, UsersResponse),
363    (GetCachedEmbeddings, GetCachedEmbeddingsResponse),
364    (GetChannelMembers, GetChannelMembersResponse),
365    (GetChannelMessages, GetChannelMessagesResponse),
366    (GetChannelMessagesById, GetChannelMessagesResponse),
367    (GetCodeActions, GetCodeActionsResponse),
368    (GetCompletions, GetCompletionsResponse),
369    (GetDefinition, GetDefinitionResponse),
370    (GetImplementation, GetImplementationResponse),
371    (GetDocumentHighlights, GetDocumentHighlightsResponse),
372    (GetHover, GetHoverResponse),
373    (GetNotifications, GetNotificationsResponse),
374    (GetPrivateUserInfo, GetPrivateUserInfoResponse),
375    (GetProjectSymbols, GetProjectSymbolsResponse),
376    (GetReferences, GetReferencesResponse),
377    (GetSupermavenApiKey, GetSupermavenApiKeyResponse),
378    (GetTypeDefinition, GetTypeDefinitionResponse),
379    (GetUsers, UsersResponse),
380    (IncomingCall, Ack),
381    (InlayHints, InlayHintsResponse),
382    (InviteChannelMember, Ack),
383    (JoinChannel, JoinRoomResponse),
384    (JoinChannelBuffer, JoinChannelBufferResponse),
385    (JoinChannelChat, JoinChannelChatResponse),
386    (JoinHostedProject, JoinProjectResponse),
387    (JoinProject, JoinProjectResponse),
388    (JoinRoom, JoinRoomResponse),
389    (LeaveChannelBuffer, Ack),
390    (LeaveRoom, Ack),
391    (MarkNotificationRead, Ack),
392    (MoveChannel, Ack),
393    (OnTypeFormatting, OnTypeFormattingResponse),
394    (OpenBufferById, OpenBufferResponse),
395    (OpenBufferByPath, OpenBufferResponse),
396    (OpenBufferForSymbol, OpenBufferForSymbolResponse),
397    (OpenNewBuffer, OpenBufferResponse),
398    (PerformRename, PerformRenameResponse),
399    (Ping, Ack),
400    (PrepareRename, PrepareRenameResponse),
401    (RefreshInlayHints, Ack),
402    (RejoinChannelBuffers, RejoinChannelBuffersResponse),
403    (RejoinRoom, RejoinRoomResponse),
404    (ReloadBuffers, ReloadBuffersResponse),
405    (RemoveChannelMember, Ack),
406    (RemoveChannelMessage, Ack),
407    (UpdateChannelMessage, Ack),
408    (RemoveContact, Ack),
409    (RenameChannel, RenameChannelResponse),
410    (RenameProjectEntry, ProjectEntryResponse),
411    (RequestContact, Ack),
412    (
413        ResolveCompletionDocumentation,
414        ResolveCompletionDocumentationResponse
415    ),
416    (ResolveInlayHint, ResolveInlayHintResponse),
417    (RespondToChannelInvite, Ack),
418    (RespondToContactRequest, Ack),
419    (SaveBuffer, BufferSaved),
420    (SearchProject, SearchProjectResponse),
421    (SendChannelMessage, SendChannelMessageResponse),
422    (SetChannelMemberRole, Ack),
423    (SetChannelVisibility, Ack),
424    (ShareProject, ShareProjectResponse),
425    (SynchronizeBuffers, SynchronizeBuffersResponse),
426    (TaskContextForLocation, TaskContext),
427    (TaskTemplates, TaskTemplatesResponse),
428    (Test, Test),
429    (UpdateBuffer, Ack),
430    (UpdateParticipantLocation, Ack),
431    (UpdateProject, Ack),
432    (UpdateWorktree, Ack),
433    (LspExtExpandMacro, LspExtExpandMacroResponse),
434    (SetRoomParticipantRole, Ack),
435    (BlameBuffer, BlameBufferResponse),
436    (CreateDevServerProject, CreateDevServerProjectResponse),
437    (CreateDevServer, CreateDevServerResponse),
438    (ShutdownDevServer, Ack),
439    (ShareDevServerProject, ShareProjectResponse),
440    (JoinDevServerProject, JoinProjectResponse),
441    (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
442    (ReconnectDevServer, ReconnectDevServerResponse),
443    (ValidateDevServerProjectRequest, Ack),
444    (MultiLspQuery, MultiLspQueryResponse),
445    (DeleteDevServer, Ack),
446    (DeleteDevServerProject, Ack),
447    (RegenerateDevServerToken, RegenerateDevServerTokenResponse),
448    (RenameDevServer, Ack),
449    (RestartLanguageServers, Ack)
450);
451
452entity_messages!(
453    {project_id, ShareProject},
454    AddProjectCollaborator,
455    ApplyCodeAction,
456    ApplyCompletionAdditionalEdits,
457    BlameBuffer,
458    BufferReloaded,
459    BufferSaved,
460    CopyProjectEntry,
461    CreateBufferForPeer,
462    CreateProjectEntry,
463    DeleteProjectEntry,
464    ExpandProjectEntry,
465    FormatBuffers,
466    GetCodeActions,
467    GetCompletions,
468    GetDefinition,
469    GetImplementation,
470    GetDocumentHighlights,
471    GetHover,
472    GetProjectSymbols,
473    GetReferences,
474    GetTypeDefinition,
475    InlayHints,
476    JoinProject,
477    LeaveProject,
478    MultiLspQuery,
479    RestartLanguageServers,
480    OnTypeFormatting,
481    OpenNewBuffer,
482    OpenBufferById,
483    OpenBufferByPath,
484    OpenBufferForSymbol,
485    PerformRename,
486    PrepareRename,
487    RefreshInlayHints,
488    ReloadBuffers,
489    RemoveProjectCollaborator,
490    RenameProjectEntry,
491    ResolveCompletionDocumentation,
492    ResolveInlayHint,
493    SaveBuffer,
494    SearchProject,
495    StartLanguageServer,
496    SynchronizeBuffers,
497    TaskContextForLocation,
498    TaskTemplates,
499    UnshareProject,
500    UpdateBuffer,
501    UpdateBufferFile,
502    UpdateDiagnosticSummary,
503    UpdateDiffBase,
504    UpdateLanguageServer,
505    UpdateProject,
506    UpdateProjectCollaborator,
507    UpdateWorktree,
508    UpdateWorktreeSettings,
509    LspExtExpandMacro,
510);
511
512entity_messages!(
513    {channel_id, Channel},
514    ChannelMessageSent,
515    ChannelMessageUpdate,
516    RemoveChannelMessage,
517    UpdateChannelMessage,
518    UpdateChannelBuffer,
519    UpdateChannelBufferCollaborators,
520);
521
522impl From<Timestamp> for SystemTime {
523    fn from(val: Timestamp) -> Self {
524        UNIX_EPOCH
525            .checked_add(Duration::new(val.seconds, val.nanos))
526            .unwrap()
527    }
528}
529
530impl From<SystemTime> for Timestamp {
531    fn from(time: SystemTime) -> Self {
532        let duration = time.duration_since(UNIX_EPOCH).unwrap();
533        Self {
534            seconds: duration.as_secs(),
535            nanos: duration.subsec_nanos(),
536        }
537    }
538}
539
540impl From<u128> for Nonce {
541    fn from(nonce: u128) -> Self {
542        let upper_half = (nonce >> 64) as u64;
543        let lower_half = nonce as u64;
544        Self {
545            upper_half,
546            lower_half,
547        }
548    }
549}
550
551impl From<Nonce> for u128 {
552    fn from(nonce: Nonce) -> Self {
553        let upper_half = (nonce.upper_half as u128) << 64;
554        let lower_half = nonce.lower_half as u128;
555        upper_half | lower_half
556    }
557}
558
559pub fn split_worktree_update(
560    mut message: UpdateWorktree,
561    max_chunk_size: usize,
562) -> impl Iterator<Item = UpdateWorktree> {
563    let mut done_files = false;
564
565    let mut repository_map = message
566        .updated_repositories
567        .into_iter()
568        .map(|repo| (repo.work_directory_id, repo))
569        .collect::<HashMap<_, _>>();
570
571    iter::from_fn(move || {
572        if done_files {
573            return None;
574        }
575
576        let updated_entries_chunk_size = cmp::min(message.updated_entries.len(), max_chunk_size);
577        let updated_entries: Vec<_> = message
578            .updated_entries
579            .drain(..updated_entries_chunk_size)
580            .collect();
581
582        let removed_entries_chunk_size = cmp::min(message.removed_entries.len(), max_chunk_size);
583        let removed_entries = message
584            .removed_entries
585            .drain(..removed_entries_chunk_size)
586            .collect();
587
588        done_files = message.updated_entries.is_empty() && message.removed_entries.is_empty();
589
590        let mut updated_repositories = Vec::new();
591
592        if !repository_map.is_empty() {
593            for entry in &updated_entries {
594                if let Some(repo) = repository_map.remove(&entry.id) {
595                    updated_repositories.push(repo)
596                }
597            }
598        }
599
600        let removed_repositories = if done_files {
601            mem::take(&mut message.removed_repositories)
602        } else {
603            Default::default()
604        };
605
606        if done_files {
607            updated_repositories.extend(mem::take(&mut repository_map).into_values());
608        }
609
610        Some(UpdateWorktree {
611            project_id: message.project_id,
612            worktree_id: message.worktree_id,
613            root_name: message.root_name.clone(),
614            abs_path: message.abs_path.clone(),
615            updated_entries,
616            removed_entries,
617            scan_id: message.scan_id,
618            is_last_update: done_files && message.is_last_update,
619            updated_repositories,
620            removed_repositories,
621        })
622    })
623}
624
625#[cfg(test)]
626mod tests {
627    use super::*;
628
629    #[test]
630    fn test_converting_peer_id_from_and_to_u64() {
631        let peer_id = PeerId {
632            owner_id: 10,
633            id: 3,
634        };
635        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
636        let peer_id = PeerId {
637            owner_id: u32::MAX,
638            id: 3,
639        };
640        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
641        let peer_id = PeerId {
642            owner_id: 10,
643            id: u32::MAX,
644        };
645        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
646        let peer_id = PeerId {
647            owner_id: u32::MAX,
648            id: u32::MAX,
649        };
650        assert_eq!(PeerId::from_u64(peer_id.as_u64()), peer_id);
651    }
652}