syntax = "proto3";
package zed.messages;

// Looking for a number? Search "// current max"

message PeerId {
    uint32 owner_id = 1;
    uint32 id = 2;
}

message Envelope {
    uint32 id = 1;
    optional uint32 responding_to = 2;
    optional PeerId original_sender_id = 3;

    /*
        When you are adding a new message type, instead of adding it in semantic order
        and bumping the message ID's of everything that follows, add it at the end of the
        file and bump the max number. See this
        https://github.com/zed-industries/zed/pull/7890#discussion_r1496621823

    */
    oneof payload {
        Hello hello = 4;
        Ack ack = 5;
        Error error = 6;
        Ping ping = 7;
        Test test = 8;
        EndStream end_stream = 165;

        CreateRoom create_room = 9;
        CreateRoomResponse create_room_response = 10;
        JoinRoom join_room = 11;
        JoinRoomResponse join_room_response = 12;
        RejoinRoom rejoin_room = 13;
        RejoinRoomResponse rejoin_room_response = 14;
        LeaveRoom leave_room = 15;
        Call call = 16;
        IncomingCall incoming_call = 17;
        CallCanceled call_canceled = 18;
        CancelCall cancel_call = 19;
        DeclineCall decline_call = 20;
        UpdateParticipantLocation update_participant_location = 21;
        RoomUpdated room_updated = 22;

        ShareProject share_project = 23;
        ShareProjectResponse share_project_response = 24;
        UnshareProject unshare_project = 25;
        JoinProject join_project = 26;
        JoinProjectResponse join_project_response = 27;
        LeaveProject leave_project = 28;
        AddProjectCollaborator add_project_collaborator = 29;
        UpdateProjectCollaborator update_project_collaborator = 30;
        RemoveProjectCollaborator remove_project_collaborator = 31;

        GetDefinition get_definition = 32;
        GetDefinitionResponse get_definition_response = 33;
        GetTypeDefinition get_type_definition = 34;
        GetTypeDefinitionResponse get_type_definition_response = 35;

        GetReferences get_references = 36;
        GetReferencesResponse get_references_response = 37;
        GetDocumentHighlights get_document_highlights = 38;
        GetDocumentHighlightsResponse get_document_highlights_response = 39;
        GetProjectSymbols get_project_symbols = 40;
        GetProjectSymbolsResponse get_project_symbols_response = 41;
        OpenBufferForSymbol open_buffer_for_symbol = 42;
        OpenBufferForSymbolResponse open_buffer_for_symbol_response = 43;

        UpdateProject update_project = 44;
        UpdateWorktree update_worktree = 45;

        CreateProjectEntry create_project_entry = 46;
        RenameProjectEntry rename_project_entry = 47;
        CopyProjectEntry copy_project_entry = 48;
        DeleteProjectEntry delete_project_entry = 49;
        ProjectEntryResponse project_entry_response = 50;
        ExpandProjectEntry expand_project_entry = 51;
        ExpandProjectEntryResponse expand_project_entry_response = 52;

        UpdateDiagnosticSummary update_diagnostic_summary = 53;
        StartLanguageServer start_language_server = 54;
        UpdateLanguageServer update_language_server = 55;

        OpenBufferById open_buffer_by_id = 56;
        OpenBufferByPath open_buffer_by_path = 57;
        OpenBufferResponse open_buffer_response = 58;
        CreateBufferForPeer create_buffer_for_peer = 59;
        UpdateBuffer update_buffer = 60;
        UpdateBufferFile update_buffer_file = 61;
        SaveBuffer save_buffer = 62;
        BufferSaved buffer_saved = 63;
        BufferReloaded buffer_reloaded = 64;
        ReloadBuffers reload_buffers = 65;
        ReloadBuffersResponse reload_buffers_response = 66;
        SynchronizeBuffers synchronize_buffers = 67;
        SynchronizeBuffersResponse synchronize_buffers_response = 68;
        FormatBuffers format_buffers = 69;
        FormatBuffersResponse format_buffers_response = 70;
        GetCompletions get_completions = 71;
        GetCompletionsResponse get_completions_response = 72;
        ResolveCompletionDocumentation resolve_completion_documentation = 73;
        ResolveCompletionDocumentationResponse resolve_completion_documentation_response = 74;
        ApplyCompletionAdditionalEdits apply_completion_additional_edits = 75;
        ApplyCompletionAdditionalEditsResponse apply_completion_additional_edits_response = 76;
        GetCodeActions get_code_actions = 77;
        GetCodeActionsResponse get_code_actions_response = 78;
        GetHover get_hover = 79;
        GetHoverResponse get_hover_response = 80;
        ApplyCodeAction apply_code_action = 81;
        ApplyCodeActionResponse apply_code_action_response = 82;
        PrepareRename prepare_rename = 83;
        PrepareRenameResponse prepare_rename_response = 84;
        PerformRename perform_rename = 85;
        PerformRenameResponse perform_rename_response = 86;
        SearchProject search_project = 87;
        SearchProjectResponse search_project_response = 88;

        UpdateContacts update_contacts = 89;
        UpdateInviteInfo update_invite_info = 90;
        ShowContacts show_contacts = 91;

        GetUsers get_users = 92;
        FuzzySearchUsers fuzzy_search_users = 93;
        UsersResponse users_response = 94;
        RequestContact request_contact = 95;
        RespondToContactRequest respond_to_contact_request = 96;
        RemoveContact remove_contact = 97;

        Follow follow = 98;
        FollowResponse follow_response = 99;
        UpdateFollowers update_followers = 100;
        Unfollow unfollow = 101;
        GetPrivateUserInfo get_private_user_info = 102;
        GetPrivateUserInfoResponse get_private_user_info_response = 103;
        UpdateDiffBase update_diff_base = 104;

        OnTypeFormatting on_type_formatting = 105;
        OnTypeFormattingResponse on_type_formatting_response = 106;

        UpdateWorktreeSettings update_worktree_settings = 107;

        InlayHints inlay_hints = 108;
        InlayHintsResponse inlay_hints_response = 109;
        ResolveInlayHint resolve_inlay_hint = 110;
        ResolveInlayHintResponse resolve_inlay_hint_response = 111;
        RefreshInlayHints refresh_inlay_hints = 112;

        CreateChannel create_channel = 113;
        CreateChannelResponse create_channel_response = 114;
        InviteChannelMember invite_channel_member = 115;
        RemoveChannelMember remove_channel_member = 116;
        RespondToChannelInvite respond_to_channel_invite = 117;
        UpdateChannels update_channels = 118;
        JoinChannel join_channel = 119;
        DeleteChannel delete_channel = 120;
        GetChannelMembers get_channel_members = 121;
        GetChannelMembersResponse get_channel_members_response = 122;
        SetChannelMemberRole set_channel_member_role = 123;
        RenameChannel rename_channel = 124;
        RenameChannelResponse rename_channel_response = 125;

        JoinChannelBuffer join_channel_buffer = 126;
        JoinChannelBufferResponse join_channel_buffer_response = 127;
        UpdateChannelBuffer update_channel_buffer = 128;
        LeaveChannelBuffer leave_channel_buffer = 129;
        UpdateChannelBufferCollaborators update_channel_buffer_collaborators = 130;
        RejoinChannelBuffers rejoin_channel_buffers = 131;
        RejoinChannelBuffersResponse rejoin_channel_buffers_response = 132;
        AckBufferOperation ack_buffer_operation = 133;

        JoinChannelChat join_channel_chat = 134;
        JoinChannelChatResponse join_channel_chat_response = 135;
        LeaveChannelChat leave_channel_chat = 136;
        SendChannelMessage send_channel_message = 137;
        SendChannelMessageResponse send_channel_message_response = 138;
        ChannelMessageSent channel_message_sent = 139;
        GetChannelMessages get_channel_messages = 140;
        GetChannelMessagesResponse get_channel_messages_response = 141;
        RemoveChannelMessage remove_channel_message = 142;
        AckChannelMessage ack_channel_message = 143;
        GetChannelMessagesById get_channel_messages_by_id = 144;

        MoveChannel move_channel = 147;
        SetChannelVisibility set_channel_visibility = 148;

        AddNotification add_notification = 149;
        GetNotifications get_notifications = 150;
        GetNotificationsResponse get_notifications_response = 151;
        DeleteNotification delete_notification = 152;
        MarkNotificationRead mark_notification_read = 153;
        LspExtExpandMacro lsp_ext_expand_macro = 154;
        LspExtExpandMacroResponse lsp_ext_expand_macro_response = 155;
        SetRoomParticipantRole set_room_participant_role = 156;

        UpdateUserChannels update_user_channels = 157;

        GetImplementation get_implementation = 162;
        GetImplementationResponse get_implementation_response = 163;

        JoinHostedProject join_hosted_project = 164;

        CompleteWithLanguageModel complete_with_language_model = 166;
        LanguageModelResponse language_model_response = 167;
        CountTokensWithLanguageModel count_tokens_with_language_model = 168;
        CountTokensResponse count_tokens_response = 169;
        UpdateChannelMessage update_channel_message = 170;
        ChannelMessageUpdate channel_message_update = 171;

        BlameBuffer blame_buffer = 172;
        BlameBufferResponse blame_buffer_response = 173;

        UpdateNotification update_notification = 174;

        MultiLspQuery multi_lsp_query = 175;
        MultiLspQueryResponse multi_lsp_query_response = 176;

        CreateRemoteProject create_remote_project = 177;
        CreateRemoteProjectResponse create_remote_project_response = 188; // current max
        CreateDevServer create_dev_server = 178;
        CreateDevServerResponse create_dev_server_response = 179;
        ShutdownDevServer shutdown_dev_server = 180;
        DevServerInstructions dev_server_instructions = 181;
        ReconnectDevServer reconnect_dev_server = 182;
        ReconnectDevServerResponse reconnect_dev_server_response = 183;

        ShareRemoteProject share_remote_project = 184;
        JoinRemoteProject join_remote_project = 185;
        RejoinRemoteProjects rejoin_remote_projects = 186;
        RejoinRemoteProjectsResponse rejoin_remote_projects_response = 187;
    }

    reserved 158 to 161;
}

// Messages

message Hello {
    PeerId peer_id = 1;
}

message Ping {}

message Ack {}

message Error {
    string message = 1;
    ErrorCode code = 2;
    repeated string tags = 3;
}

enum ErrorCode {
    Internal = 0;
    NoSuchChannel = 1;
    Disconnected = 2;
    SignedOut = 3;
    UpgradeRequired = 4;
    Forbidden = 5;
    NeedsCla = 7;
    NotARootChannel = 8;
    BadPublicNesting = 9;
    CircularNesting = 10;
    WrongMoveTarget = 11;
    UnsharedItem = 12;
    NoSuchProject = 13;
    DevServerAlreadyOnline = 14;
    reserved 6;
}

message EndStream {}

message Test {
    uint64 id = 1;
}

message CreateRoom {}

message CreateRoomResponse {
    Room room = 1;
    optional LiveKitConnectionInfo live_kit_connection_info = 2;
}

message JoinRoom {
    uint64 id = 1;
}

message JoinRoomResponse {
    Room room = 1;
    optional uint64 channel_id = 2;
    optional LiveKitConnectionInfo live_kit_connection_info = 3;
}

message RejoinRoom {
    uint64 id = 1;
    repeated UpdateProject reshared_projects = 2;
    repeated RejoinProject rejoined_projects = 3;
}
message RejoinRemoteProjects {
    repeated RejoinProject rejoined_projects = 1;
}

message RejoinRemoteProjectsResponse {
    repeated RejoinedProject rejoined_projects = 1;
}

message RejoinProject {
    uint64 id = 1;
    repeated RejoinWorktree worktrees = 2;
}

message RejoinWorktree {
    uint64 id = 1;
    uint64 scan_id = 2;
}

message RejoinRoomResponse {
    Room room = 1;
    repeated ResharedProject reshared_projects = 2;
    repeated RejoinedProject rejoined_projects = 3;
}

message ResharedProject {
    uint64 id = 1;
    repeated Collaborator collaborators = 2;
}

message RejoinedProject {
    uint64 id = 1;
    repeated WorktreeMetadata worktrees = 2;
    repeated Collaborator collaborators = 3;
    repeated LanguageServer language_servers = 4;
}

message LeaveRoom {}

message Room {
    uint64 id = 1;
    repeated Participant participants = 2;
    repeated PendingParticipant pending_participants = 3;
    repeated Follower followers = 4;
    string live_kit_room = 5;
}

message Participant {
    uint64 user_id = 1;
    PeerId peer_id = 2;
    repeated ParticipantProject projects = 3;
    ParticipantLocation location = 4;
    uint32 participant_index = 5;
    ChannelRole role = 6;
    reserved 7;
}

message PendingParticipant {
    uint64 user_id = 1;
    uint64 calling_user_id = 2;
    optional uint64 initial_project_id = 3;
}

message ParticipantProject {
    uint64 id = 1;
    repeated string worktree_root_names = 2;
}

message Follower {
    PeerId leader_id = 1;
    PeerId follower_id = 2;
    uint64 project_id = 3;
}

message ParticipantLocation {
    oneof variant {
        SharedProject shared_project = 1;
        UnsharedProject unshared_project = 2;
        External external = 3;
    }

    message SharedProject {
        uint64 id = 1;
    }

    message UnsharedProject {}

    message External {}
}

message Call {
    uint64 room_id = 1;
    uint64 called_user_id = 2;
    optional uint64 initial_project_id = 3;
}

message IncomingCall {
    uint64 room_id = 1;
    uint64 calling_user_id = 2;
    repeated uint64 participant_user_ids = 3;
    optional ParticipantProject initial_project = 4;
}

message CallCanceled {
    uint64 room_id = 1;
}

message CancelCall {
    uint64 room_id = 1;
    uint64 called_user_id = 2;
}

message DeclineCall {
    uint64 room_id = 1;
}

message UpdateParticipantLocation {
    uint64 room_id = 1;
    ParticipantLocation location = 2;
}

message RoomUpdated {
    Room room = 1;
}

message LiveKitConnectionInfo {
    string server_url = 1;
    string token = 2;
    bool can_publish = 3;
}

message ShareProject {
    uint64 room_id = 1;
    repeated WorktreeMetadata worktrees = 2;
}

message ShareProjectResponse {
    uint64 project_id = 1;
}

message UnshareProject {
    uint64 project_id = 1;
}

message UpdateProject {
    uint64 project_id = 1;
    repeated WorktreeMetadata worktrees = 2;
}

message JoinProject {
    uint64 project_id = 1;
}

message JoinHostedProject {
    uint64 project_id = 1;
}

message CreateRemoteProject {
    uint64 channel_id = 1;
    string name = 2;
    uint64 dev_server_id = 3;
    string path = 4;
}
message CreateRemoteProjectResponse {
    RemoteProject remote_project = 1;
}

message CreateDevServer {
    uint64 channel_id = 1;
    string name = 2;
}

message CreateDevServerResponse {
    uint64 dev_server_id = 1;
    uint64 channel_id = 2;
    string access_token = 3;
    string name = 4;
}

message ShutdownDevServer {
}

message ReconnectDevServer {
    repeated UpdateProject reshared_projects = 1;
}

message ReconnectDevServerResponse {
    repeated ResharedProject reshared_projects = 1;
}

message DevServerInstructions {
    repeated RemoteProject projects = 1;
}

message ShareRemoteProject {
    uint64 remote_project_id = 1;
    repeated WorktreeMetadata worktrees = 2;
}

message JoinRemoteProject {
    uint64 remote_project_id = 1;
}

message JoinProjectResponse {
    uint64 project_id = 5;
    uint32 replica_id = 1;
    repeated WorktreeMetadata worktrees = 2;
    repeated Collaborator collaborators = 3;
    repeated LanguageServer language_servers = 4;
    ChannelRole role = 6;
}

message LeaveProject {
    uint64 project_id = 1;
}

message UpdateWorktree {
    uint64 project_id = 1;
    uint64 worktree_id = 2;
    string root_name = 3;
    repeated Entry updated_entries = 4;
    repeated uint64 removed_entries = 5;
    repeated RepositoryEntry updated_repositories = 6;
    repeated uint64 removed_repositories = 7;
    uint64 scan_id = 8;
    bool is_last_update = 9;
    string abs_path = 10;
}

message UpdateWorktreeSettings {
    uint64 project_id = 1;
    uint64 worktree_id = 2;
    string path = 3;
    optional string content = 4;
}

message CreateProjectEntry {
    uint64 project_id = 1;
    uint64 worktree_id = 2;
    string path = 3;
    bool is_directory = 4;
}

message RenameProjectEntry {
    uint64 project_id = 1;
    uint64 entry_id = 2;
    string new_path = 3;
}

message CopyProjectEntry {
    uint64 project_id = 1;
    uint64 entry_id = 2;
    string new_path = 3;
}

message DeleteProjectEntry {
    uint64 project_id = 1;
    uint64 entry_id = 2;
}

message ExpandProjectEntry {
    uint64 project_id = 1;
    uint64 entry_id = 2;
}

message ExpandProjectEntryResponse {
    uint64 worktree_scan_id = 1;
}

message ProjectEntryResponse {
    optional Entry entry = 1;
    uint64 worktree_scan_id = 2;
}

message AddProjectCollaborator {
    uint64 project_id = 1;
    Collaborator collaborator = 2;
}

message UpdateProjectCollaborator {
    uint64 project_id = 1;
    PeerId old_peer_id = 2;
    PeerId new_peer_id = 3;
}

message RemoveProjectCollaborator {
    uint64 project_id = 1;
    PeerId peer_id = 2;
}

message UpdateChannelBufferCollaborators {
    uint64 channel_id = 1;
    repeated Collaborator collaborators = 2;
}

message GetDefinition {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
 }

message GetDefinitionResponse {
    repeated LocationLink links = 1;
}

message GetTypeDefinition {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
 }

message GetTypeDefinitionResponse {
    repeated LocationLink links = 1;
}
message GetImplementation {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
 }

message GetImplementationResponse {
    repeated LocationLink links = 1;
}

message GetReferences {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
 }

message GetReferencesResponse {
    repeated Location locations = 1;
}

message GetDocumentHighlights {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
 }

message GetDocumentHighlightsResponse {
    repeated DocumentHighlight highlights = 1;
}

message Location {
    uint64 buffer_id = 1;
    Anchor start = 2;
    Anchor end = 3;
}

message LocationLink {
    optional Location origin = 1;
    Location target = 2;
}

message DocumentHighlight {
    Kind kind = 1;
    Anchor start = 2;
    Anchor end = 3;

    enum Kind {
        Text = 0;
        Read = 1;
        Write = 2;
    }
}

message GetProjectSymbols {
    uint64 project_id = 1;
    string query = 2;
}

message GetProjectSymbolsResponse {
    repeated Symbol symbols = 4;
}

message Symbol {
    uint64 source_worktree_id = 1;
    uint64 worktree_id = 2;
    string language_server_name = 3;
    string name = 4;
    int32 kind = 5;
    string path = 6;
    // Cannot use generate anchors for unopened files,
    // so we are forced to use point coords instead
    PointUtf16 start = 7;
    PointUtf16 end = 8;
    bytes signature = 9;
}

message OpenBufferForSymbol {
    uint64 project_id = 1;
    Symbol symbol = 2;
}

message OpenBufferForSymbolResponse {
    uint64 buffer_id = 1;
}

message OpenBufferByPath {
    uint64 project_id = 1;
    uint64 worktree_id = 2;
    string path = 3;
}

message OpenBufferById {
    uint64 project_id = 1;
    uint64 id = 2;
}

message OpenBufferResponse {
    uint64 buffer_id = 1;
}

message CreateBufferForPeer {
    uint64 project_id = 1;
    PeerId peer_id = 2;
    oneof variant {
        BufferState state = 3;
        BufferChunk chunk = 4;
    }
}

message UpdateBuffer {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated Operation operations = 3;
}

message UpdateChannelBuffer {
    uint64 channel_id = 1;
    repeated Operation operations = 2;
}

message UpdateBufferFile {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    File file = 3;
}

message SaveBuffer {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated VectorClockEntry version = 3;
}

message BufferSaved {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated VectorClockEntry version = 3;
    Timestamp mtime = 4;
    string fingerprint = 5;
}

message BufferReloaded {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated VectorClockEntry version = 3;
    Timestamp mtime = 4;
    string fingerprint = 5;
    LineEnding line_ending = 6;
}

message ReloadBuffers {
    uint64 project_id = 1;
    repeated uint64 buffer_ids = 2;
}

message ReloadBuffersResponse {
    ProjectTransaction transaction = 1;
}

message SynchronizeBuffers {
    uint64 project_id = 1;
    repeated BufferVersion buffers = 2;
}

message SynchronizeBuffersResponse {
    repeated BufferVersion buffers = 1;
}

message BufferVersion {
    uint64 id = 1;
    repeated VectorClockEntry version = 2;
}

message ChannelBufferVersion {
    uint64 channel_id = 1;
    repeated VectorClockEntry version = 2;
    uint64 epoch = 3;
}

enum FormatTrigger {
    Save = 0;
    Manual = 1;
}

message FormatBuffers {
    uint64 project_id = 1;
    FormatTrigger trigger = 2;
    repeated uint64 buffer_ids = 3;
}

message FormatBuffersResponse {
    ProjectTransaction transaction = 1;
}

message GetCompletions {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    repeated VectorClockEntry version = 4;
}

message GetCompletionsResponse {
    repeated Completion completions = 1;
    repeated VectorClockEntry version = 2;
}

message ApplyCompletionAdditionalEdits {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Completion completion = 3;
}

message ApplyCompletionAdditionalEditsResponse {
    Transaction transaction = 1;
}

message Completion {
    Anchor old_start = 1;
    Anchor old_end = 2;
    string new_text = 3;
    uint64 server_id = 4;
    bytes lsp_completion = 5;
}

message GetCodeActions {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor start = 3;
    Anchor end = 4;
    repeated VectorClockEntry version = 5;
}

message GetCodeActionsResponse {
    repeated CodeAction actions = 1;
    repeated VectorClockEntry version = 2;
}

message GetHover {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    repeated VectorClockEntry version = 5;
}

message GetHoverResponse {
    optional Anchor start = 1;
    optional Anchor end = 2;
    repeated HoverBlock contents = 3;
}

message HoverBlock {
    string text = 1;
    optional string language = 2;
    bool is_markdown = 3;
}

message ApplyCodeAction {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    CodeAction action = 3;
}

message ApplyCodeActionResponse {
    ProjectTransaction transaction = 1;
}

message PrepareRename {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    repeated VectorClockEntry version = 4;
}

message PrepareRenameResponse {
    bool can_rename = 1;
    Anchor start = 2;
    Anchor end = 3;
    repeated VectorClockEntry version = 4;
}

message PerformRename {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    string new_name = 4;
    repeated VectorClockEntry version = 5;
}

message OnTypeFormatting {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    string trigger = 4;
    repeated VectorClockEntry version = 5;
}

message OnTypeFormattingResponse {
    Transaction transaction = 1;
}

message InlayHints {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor start = 3;
    Anchor end = 4;
    repeated VectorClockEntry version = 5;
}

message InlayHintsResponse {
    repeated InlayHint hints = 1;
    repeated VectorClockEntry version = 2;
}

message InlayHint {
    Anchor position = 1;
    InlayHintLabel label = 2;
    optional string kind = 3;
    bool padding_left = 4;
    bool padding_right = 5;
    InlayHintTooltip tooltip = 6;
    ResolveState resolve_state = 7;
}

message InlayHintLabel {
    oneof label {
        string value = 1;
        InlayHintLabelParts label_parts = 2;
    }
}

message InlayHintLabelParts {
    repeated InlayHintLabelPart parts = 1;
}

message InlayHintLabelPart {
    string value = 1;
    InlayHintLabelPartTooltip tooltip = 2;
    optional string location_url = 3;
    PointUtf16 location_range_start = 4;
    PointUtf16 location_range_end = 5;
    optional uint64 language_server_id = 6;
}

message InlayHintTooltip {
    oneof content {
        string value = 1;
        MarkupContent markup_content = 2;
    }
}

message InlayHintLabelPartTooltip {
    oneof content {
        string value = 1;
        MarkupContent markup_content = 2;
    }
}

message ResolveState {
    State state = 1;
    LspResolveState lsp_resolve_state = 2;

    enum State {
        Resolved = 0;
        CanResolve = 1;
        Resolving = 2;
    }

    message LspResolveState {
        string value = 1;
        uint64 server_id = 2;
    }
}

message ResolveCompletionDocumentation {
    uint64 project_id = 1;
    uint64 language_server_id = 2;
    bytes lsp_completion = 3;
}

message ResolveCompletionDocumentationResponse {
    string text = 1;
    bool is_markdown = 2;
}

message ResolveInlayHint {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    uint64 language_server_id = 3;
    InlayHint hint = 4;
}

message ResolveInlayHintResponse {
    InlayHint hint = 1;
}

message RefreshInlayHints {
    uint64 project_id = 1;
}

message MarkupContent {
    bool is_markdown = 1;
    string value = 2;
}

message PerformRenameResponse {
    ProjectTransaction transaction = 2;
}

message SearchProject {
    uint64 project_id = 1;
    string query = 2;
    bool regex = 3;
    bool whole_word = 4;
    bool case_sensitive = 5;
    string files_to_include = 6;
    string files_to_exclude = 7;
    bool include_ignored = 8;
}

message SearchProjectResponse {
    repeated Location locations = 1;
    bool limit_reached = 2;
}

message CodeAction {
    uint64 server_id = 1;
    Anchor start = 2;
    Anchor end = 3;
    bytes lsp_action = 4;
}

message ProjectTransaction {
    repeated uint64 buffer_ids = 1;
    repeated Transaction transactions = 2;
}

message Transaction {
    LamportTimestamp id = 1;
    repeated LamportTimestamp edit_ids = 2;
    repeated VectorClockEntry start = 3;
}

message LamportTimestamp {
    uint32 replica_id = 1;
    uint32 value = 2;
}

message LanguageServer {
    uint64 id = 1;
    string name = 2;
}

message StartLanguageServer {
    uint64 project_id = 1;
    LanguageServer server = 2;
}

message UpdateDiagnosticSummary {
    uint64 project_id = 1;
    uint64 worktree_id = 2;
    DiagnosticSummary summary = 3;
}

message DiagnosticSummary {
    string path = 1;
    uint64 language_server_id = 2;
    uint32 error_count = 3;
    uint32 warning_count = 4;
}

message UpdateLanguageServer {
    uint64 project_id = 1;
    uint64 language_server_id = 2;
    oneof variant {
        LspWorkStart work_start = 3;
        LspWorkProgress work_progress = 4;
        LspWorkEnd work_end = 5;
        LspDiskBasedDiagnosticsUpdating disk_based_diagnostics_updating = 6;
        LspDiskBasedDiagnosticsUpdated disk_based_diagnostics_updated = 7;
    }
}

message LspWorkStart {
    string token = 1;
    optional string message = 2;
    optional uint32 percentage = 3;
}

message LspWorkProgress {
    string token = 1;
    optional string message = 2;
    optional uint32 percentage = 3;
}

message LspWorkEnd {
    string token = 1;
}

message LspDiskBasedDiagnosticsUpdating {}

message LspDiskBasedDiagnosticsUpdated {}

message UpdateChannels {
    repeated Channel channels = 1;
    repeated uint64 delete_channels = 4;
    repeated Channel channel_invitations = 5;
    repeated uint64 remove_channel_invitations = 6;
    repeated ChannelParticipants channel_participants = 7;
    repeated ChannelMessageId latest_channel_message_ids = 8;
    repeated ChannelBufferVersion latest_channel_buffer_versions = 9;

    repeated HostedProject hosted_projects = 10;
    repeated uint64 deleted_hosted_projects = 11;

    repeated DevServer dev_servers = 12;
    repeated uint64 deleted_dev_servers = 13;

    repeated RemoteProject remote_projects = 14;
    repeated uint64 deleted_remote_projects = 15;
}

message UpdateUserChannels {
    repeated ChannelMessageId observed_channel_message_id = 1;
    repeated ChannelBufferVersion observed_channel_buffer_version = 2;
    repeated ChannelMembership channel_memberships = 3;
}

message ChannelMembership {
    uint64 channel_id = 1;
    ChannelRole role = 2;
}

message ChannelMessageId {
    uint64 channel_id = 1;
    uint64 message_id = 2;
}

message ChannelPermission {
    uint64 channel_id = 1;
    ChannelRole role = 3;
}

message ChannelParticipants {
    uint64 channel_id = 1;
    repeated uint64 participant_user_ids = 2;
}

message HostedProject {
    uint64 project_id = 1;
    uint64 channel_id = 2;
    string name = 3;
    ChannelVisibility visibility = 4;
}

message RemoteProject {
    uint64 id = 1;
    optional uint64 project_id = 2;
    uint64 channel_id = 3;
    string name = 4;
    uint64 dev_server_id = 5;
    string path = 6;
}

message DevServer {
    uint64 channel_id = 1;
    uint64 dev_server_id = 2;
    string name = 3;
    DevServerStatus status = 4;
}

enum DevServerStatus {
    Offline = 0;
    Online = 1;
}

message JoinChannel {
    uint64 channel_id = 1;
}

message DeleteChannel {
    uint64 channel_id = 1;
}

message GetChannelMembers {
    uint64 channel_id = 1;
}

message GetChannelMembersResponse {
    repeated ChannelMember members = 1;
}

message ChannelMember {
    uint64 user_id = 1;
    Kind kind = 3;
    ChannelRole role = 4;

    enum Kind {
        Member = 0;
        Invitee = 1;
    }
}

message CreateChannel {
    string name = 1;
    optional uint64 parent_id = 2;
}

message CreateChannelResponse {
    Channel channel = 1;
    optional uint64 parent_id = 2;
}

message InviteChannelMember {
    uint64 channel_id = 1;
    uint64 user_id = 2;
    ChannelRole role = 4;
}

message RemoveChannelMember {
    uint64 channel_id = 1;
    uint64 user_id = 2;
}

enum ChannelRole {
    Admin = 0;
    Member = 1;
    Guest = 2;
    Banned = 3;
    Talker = 4;
}

message SetChannelMemberRole {
    uint64 channel_id = 1;
    uint64 user_id = 2;
    ChannelRole role = 3;
}

message SetChannelVisibility {
    uint64 channel_id = 1;
    ChannelVisibility visibility = 2;
}

message RenameChannel {
    uint64 channel_id = 1;
    string name = 2;
}

message RenameChannelResponse {
    Channel channel = 1;
}

message JoinChannelChat {
    uint64 channel_id = 1;
}

message JoinChannelChatResponse {
    repeated ChannelMessage messages = 1;
    bool done = 2;
}

message LeaveChannelChat {
    uint64 channel_id = 1;
}

message SendChannelMessage {
    uint64 channel_id = 1;
    string body = 2;
    Nonce nonce = 3;
    repeated ChatMention mentions = 4;
    optional uint64 reply_to_message_id = 5;
}

message RemoveChannelMessage {
    uint64 channel_id = 1;
    uint64 message_id = 2;
}

message UpdateChannelMessage {
    uint64 channel_id = 1;
    uint64 message_id = 2;
    Nonce nonce = 4;
    string body = 5;
    repeated ChatMention mentions = 6;
}

message AckChannelMessage {
    uint64 channel_id = 1;
    uint64 message_id = 2;
}

message SendChannelMessageResponse {
    ChannelMessage message = 1;
}

message ChannelMessageSent {
    uint64 channel_id = 1;
    ChannelMessage message = 2;
}

message ChannelMessageUpdate {
    uint64 channel_id = 1;
    ChannelMessage message = 2;
}

message GetChannelMessages {
    uint64 channel_id = 1;
    uint64 before_message_id = 2;
}

message GetChannelMessagesResponse {
    repeated ChannelMessage messages = 1;
    bool done = 2;
}

message GetChannelMessagesById {
    repeated uint64 message_ids = 1;
}

message MoveChannel {
    uint64 channel_id = 1;
    uint64 to = 2;
}

message JoinChannelBuffer {
    uint64 channel_id = 1;
}

message ChannelMessage {
    uint64 id = 1;
    string body = 2;
    uint64 timestamp = 3;
    uint64 sender_id = 4;
    Nonce nonce = 5;
    repeated ChatMention mentions = 6;
    optional uint64 reply_to_message_id = 7;
    optional uint64 edited_at = 8;
}

message ChatMention {
    Range range = 1;
    uint64 user_id = 2;
}

message RejoinChannelBuffers {
    repeated ChannelBufferVersion buffers = 1;
}

message RejoinChannelBuffersResponse {
    repeated RejoinedChannelBuffer buffers = 1;
}

message AckBufferOperation {
    uint64 buffer_id = 1;
    uint64 epoch = 2;
    repeated VectorClockEntry version = 3;
}

message JoinChannelBufferResponse {
    uint64 buffer_id = 1;
    uint32 replica_id = 2;
    string base_text = 3;
    repeated Operation operations = 4;
    repeated Collaborator collaborators = 5;
    uint64 epoch = 6;
}

message RejoinedChannelBuffer {
    uint64 channel_id = 1;
    repeated VectorClockEntry version = 2;
    repeated Operation operations = 3;
    repeated Collaborator collaborators = 4;
}

message LeaveChannelBuffer {
    uint64 channel_id = 1;
}

message RespondToChannelInvite {
    uint64 channel_id = 1;
    bool accept = 2;
}

message GetUsers {
    repeated uint64 user_ids = 1;
}

message FuzzySearchUsers {
    string query = 1;
}

message UsersResponse {
    repeated User users = 1;
}

message RequestContact {
    uint64 responder_id = 1;
}

message RemoveContact {
    uint64 user_id = 1;
}

message RespondToContactRequest {
    uint64 requester_id = 1;
    ContactRequestResponse response = 2;
}

enum ContactRequestResponse {
    Accept = 0;
    Decline = 1;
    Block = 2;
    Dismiss = 3;
}

message UpdateContacts {
    repeated Contact contacts = 1;
    repeated uint64 remove_contacts = 2;
    repeated IncomingContactRequest incoming_requests = 3;
    repeated uint64 remove_incoming_requests = 4;
    repeated uint64 outgoing_requests = 5;
    repeated uint64 remove_outgoing_requests = 6;
}

message UpdateInviteInfo {
    string url = 1;
    uint32 count = 2;
}

message ShowContacts {}

message IncomingContactRequest {
    uint64 requester_id = 1;
}

message UpdateDiagnostics {
    uint32 replica_id = 1;
    uint32 lamport_timestamp = 2;
    uint64 server_id = 3;
    repeated Diagnostic diagnostics = 4;
}

message Follow {
    uint64 room_id = 1;
    optional uint64 project_id = 2;
    PeerId leader_id = 3;
}

message FollowResponse {
    View active_view = 3;
    // TODO: after 0.124.0 is retired, remove these.
    optional ViewId active_view_id = 1;
    repeated View views = 2;
}

message UpdateFollowers {
    uint64 room_id = 1;
    optional uint64 project_id = 2;
    reserved 3;
    oneof variant {
        View create_view = 5;
        // TODO: after 0.124.0 is retired, remove these.
        UpdateActiveView update_active_view = 4;
        UpdateView update_view = 6;
    }
}

message Unfollow {
    uint64 room_id = 1;
    optional uint64 project_id = 2;
    PeerId leader_id = 3;
}

message GetPrivateUserInfo {}

message GetPrivateUserInfoResponse {
    string metrics_id = 1;
    bool staff = 2;
    repeated string flags = 3;
}

// Entities

message ViewId {
    PeerId creator = 1;
    uint64 id = 2;
}

message UpdateActiveView {
    optional ViewId id = 1;
    optional PeerId leader_id = 2;
    View view = 3;
}

message UpdateView {
    ViewId id = 1;
    optional PeerId leader_id = 2;

    oneof variant {
        Editor editor = 3;
    }

    message Editor {
        repeated ExcerptInsertion inserted_excerpts = 1;
        repeated uint64 deleted_excerpts = 2;
        repeated Selection selections = 3;
        optional Selection pending_selection = 4;
        EditorAnchor scroll_top_anchor = 5;
        float scroll_x = 6;
        float scroll_y = 7;
    }
}

message View {
    ViewId id = 1;
    optional PeerId leader_id = 2;

    oneof variant {
        Editor editor = 3;
        ChannelView channel_view = 4;
    }

    message Editor {
        bool singleton = 1;
        optional string title = 2;
        repeated Excerpt excerpts = 3;
        repeated Selection selections = 4;
        optional Selection pending_selection = 5;
        EditorAnchor scroll_top_anchor = 6;
        float scroll_x = 7;
        float scroll_y = 8;
    }

    message ChannelView {
        uint64 channel_id = 1;
        Editor editor = 2;
    }
}

message Collaborator {
    PeerId peer_id = 1;
    uint32 replica_id = 2;
    uint64 user_id = 3;
}

message User {
    uint64 id = 1;
    string github_login = 2;
    string avatar_url = 3;
}

message File {
    uint64 worktree_id = 1;
    optional uint64 entry_id = 2;
    string path = 3;
    Timestamp mtime = 4;
    bool is_deleted = 5;
}

message Entry {
    uint64 id = 1;
    bool is_dir = 2;
    string path = 3;
    uint64 inode = 4;
    Timestamp mtime = 5;
    bool is_symlink = 6;
    bool is_ignored = 7;
    bool is_external = 8;
    optional GitStatus git_status = 9;
}

message RepositoryEntry {
    uint64 work_directory_id = 1;
    optional string branch = 2;
}

message StatusEntry {
    string repo_path = 1;
    GitStatus status = 2;
}

enum GitStatus {
    Added = 0;
    Modified = 1;
    Conflict = 2;
}

message BufferState {
    uint64 id = 1;
    optional File file = 2;
    string base_text = 3;
    optional string diff_base = 4;
    LineEnding line_ending = 5;
    repeated VectorClockEntry saved_version = 6;
    string saved_version_fingerprint = 7;
    Timestamp saved_mtime = 8;
}

message BufferChunk {
    uint64 buffer_id = 1;
    repeated Operation operations = 2;
    bool is_last = 3;
}

enum LineEnding {
    Unix = 0;
    Windows = 1;
}

message Selection {
    uint64 id = 1;
    EditorAnchor start = 2;
    EditorAnchor end = 3;
    bool reversed = 4;
}

message EditorAnchor {
    uint64 excerpt_id = 1;
    Anchor anchor = 2;
}

enum CursorShape {
    CursorBar = 0;
    CursorBlock = 1;
    CursorUnderscore = 2;
    CursorHollow = 3;
}

message ExcerptInsertion {
    Excerpt excerpt = 1;
    optional uint64 previous_excerpt_id = 2;
}

message Excerpt {
    uint64 id = 1;
    uint64 buffer_id = 2;
    Anchor context_start = 3;
    Anchor context_end = 4;
    Anchor primary_start = 5;
    Anchor primary_end = 6;
}

message Anchor {
    uint32 replica_id = 1;
    uint32 timestamp = 2;
    uint64 offset = 3;
    Bias bias = 4;
    optional uint64 buffer_id = 5;
}

enum Bias {
    Left = 0;
    Right = 1;
}

message Diagnostic {
    Anchor start = 1;
    Anchor end = 2;
    optional string source = 3;
    Severity severity = 4;
    string message = 5;
    optional string code = 6;
    uint64 group_id = 7;
    bool is_primary = 8;

    // TODO: remove this field
    bool is_valid = 9;

    bool is_disk_based = 10;
    bool is_unnecessary = 11;

    enum Severity {
        None = 0;
        Error = 1;
        Warning = 2;
        Information = 3;
        Hint = 4;
    }
}

message Operation {
    oneof variant {
        Edit edit = 1;
        Undo undo = 2;
        UpdateSelections update_selections = 3;
        UpdateDiagnostics update_diagnostics = 4;
        UpdateCompletionTriggers update_completion_triggers = 5;
    }

    message Edit {
        uint32 replica_id = 1;
        uint32 lamport_timestamp = 2;
        repeated VectorClockEntry version = 3;
        repeated Range ranges = 4;
        repeated string new_text = 5;
    }

    message Undo {
        uint32 replica_id = 1;
        uint32 lamport_timestamp = 2;
        repeated VectorClockEntry version = 3;
        repeated UndoCount counts = 4;
    }

    message UpdateSelections {
        uint32 replica_id = 1;
        uint32 lamport_timestamp = 2;
        repeated Selection selections = 3;
        bool line_mode = 4;
        CursorShape cursor_shape = 5;
    }

    message UpdateCompletionTriggers {
        uint32 replica_id = 1;
        uint32 lamport_timestamp = 2;
        repeated string triggers = 3;
    }
}

message UndoMapEntry {
    uint32 replica_id = 1;
    uint32 local_timestamp = 2;
    repeated UndoCount counts = 3;
}

message UndoCount {
    uint32 replica_id = 1;
    uint32 lamport_timestamp = 2;
    uint32 count = 3;
}

message VectorClockEntry {
    uint32 replica_id = 1;
    uint32 timestamp = 2;
}

message Timestamp {
    uint64 seconds = 1;
    uint32 nanos = 2;
}

message Range {
    uint64 start = 1;
    uint64 end = 2;
}

message PointUtf16 {
    uint32 row = 1;
    uint32 column = 2;
}

message Nonce {
    uint64 upper_half = 1;
    uint64 lower_half = 2;
}

enum ChannelVisibility {
    Public = 0;
    Members = 1;
}

message Channel {
    uint64 id = 1;
    string name = 2;
    ChannelVisibility visibility = 3;
    repeated uint64 parent_path = 5;
}

message Contact {
    uint64 user_id = 1;
    bool online = 2;
    bool busy = 3;
}

message WorktreeMetadata {
    uint64 id = 1;
    string root_name = 2;
    bool visible = 3;
    string abs_path = 4;
}

message UpdateDiffBase {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    optional string diff_base = 3;
}

message GetNotifications {
    optional uint64 before_id = 1;
}

message AddNotification {
    Notification notification = 1;
}

message GetNotificationsResponse {
    repeated Notification notifications = 1;
    bool done = 2;
}

message DeleteNotification {
    uint64 notification_id = 1;
}

message UpdateNotification {
    Notification notification = 1;
}

message MarkNotificationRead {
    uint64 notification_id = 1;
}

message Notification {
    uint64 id = 1;
    uint64 timestamp = 2;
    string kind = 3;
    optional uint64 entity_id = 4;
    string content = 5;
    bool is_read = 6;
    optional bool response = 7;
}

message LspExtExpandMacro {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
}

message LspExtExpandMacroResponse {
    string name = 1;
    string expansion = 2;
}

message SetRoomParticipantRole {
    uint64 room_id = 1;
    uint64 user_id = 2;
    ChannelRole role = 3;
}

message CompleteWithLanguageModel {
    string model = 1;
    repeated LanguageModelRequestMessage messages = 2;
    repeated string stop = 3;
    float temperature = 4;
}

message LanguageModelRequestMessage {
    LanguageModelRole role = 1;
    string content = 2;
}

enum LanguageModelRole {
    LanguageModelUser = 0;
    LanguageModelAssistant = 1;
    LanguageModelSystem = 2;
}

message LanguageModelResponseMessage {
    optional LanguageModelRole role = 1;
    optional string content = 2;
}

message LanguageModelResponse {
    repeated LanguageModelChoiceDelta choices = 1;
}

message LanguageModelChoiceDelta {
    uint32 index = 1;
    LanguageModelResponseMessage delta = 2;
    optional string finish_reason = 3;
}

message CountTokensWithLanguageModel {
    string model = 1;
    repeated LanguageModelRequestMessage messages = 2;
}

message CountTokensResponse {
    uint32 token_count = 1;
}

message BlameBuffer {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated VectorClockEntry version = 3;
}

message BlameEntry {
    bytes sha = 1;

    uint32 start_line = 2;
    uint32 end_line = 3;
    uint32 original_line_number = 4;

    optional string author = 5;
    optional string author_mail = 6;
    optional int64 author_time = 7;
    optional string author_tz = 8;

    optional string committer = 9;
    optional string committer_mail = 10;
    optional int64 committer_time = 11;
    optional string committer_tz = 12;

    optional string summary = 13;
    optional string previous = 14;

    string filename = 15;
}

message CommitMessage {
    bytes oid = 1;
    string message = 2;
}

message CommitPermalink {
    bytes oid = 1;
    string permalink = 2;
}

message BlameBufferResponse {
    repeated BlameEntry entries = 1;
    repeated CommitMessage messages = 2;
    repeated CommitPermalink permalinks = 3;
}

message MultiLspQuery {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated VectorClockEntry version = 3;
    oneof strategy {
        AllLanguageServers all = 4;
    }
    oneof request {
        GetHover get_hover = 5;
        GetCodeActions get_code_actions = 6;
    }
}

message AllLanguageServers {}

message MultiLspQueryResponse {
    repeated LspResponse responses = 1;
}

message LspResponse {
    oneof response {
        GetHoverResponse get_hover_response = 1;
        GetCodeActionsResponse get_code_actions_response = 2;
    }
}
