Unnamed repository; edit this file 'description' to name the repository.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! Bidirectional protocol messages

use std::{
    io::{self, BufRead, Write},
    ops::Range,
};

use paths::Utf8PathBuf;
use serde::{Deserialize, Serialize};

use crate::{
    ProcMacroKind,
    legacy_protocol::msg::{FlatTree, Message, PanicMessage, ServerConfig},
    transport::postcard,
};

#[derive(Debug, Serialize, Deserialize)]
pub enum SubRequest {
    FilePath { file_id: u32 },
    SourceText { file_id: u32, ast_id: u32, start: u32, end: u32 },
    LocalFilePath { file_id: u32 },
    LineColumn { file_id: u32, ast_id: u32, offset: u32 },
    ByteRange { file_id: u32, ast_id: u32, start: u32, end: u32 },
    SpanSource { file_id: u32, ast_id: u32, start: u32, end: u32, ctx: u32 },
}

#[derive(Debug, Serialize, Deserialize)]
pub enum SubResponse {
    FilePathResult {
        name: String,
    },
    SourceTextResult {
        text: Option<String>,
    },
    LocalFilePathResult {
        name: Option<String>,
    },
    /// Line and column are 1-based.
    LineColumnResult {
        line: u32,
        column: u32,
    },
    ByteRangeResult {
        range: Range<usize>,
    },
    SpanSourceResult {
        file_id: u32,
        ast_id: u32,
        start: u32,
        end: u32,
        ctx: u32,
    },
    Cancel {
        reason: String,
    },
}

#[derive(Debug, Serialize, Deserialize)]
pub enum BidirectionalMessage {
    Request(Request),
    Response(Response),
    SubRequest(SubRequest),
    SubResponse(SubResponse),
}

#[derive(Debug, Serialize, Deserialize)]
pub enum Request {
    ListMacros { dylib_path: Utf8PathBuf },
    ExpandMacro(Box<ExpandMacro>),
    ApiVersionCheck {},
    SetConfig(ServerConfig),
}

#[derive(Debug, Serialize, Deserialize)]
pub enum Response {
    ListMacros(Result<Vec<(String, ProcMacroKind)>, String>),
    ExpandMacro(Result<FlatTree, PanicMessage>),
    ApiVersionCheck(u32),
    SetConfig(ServerConfig),
    ExpandMacroExtended(Result<ExpandMacroExtended, PanicMessage>),
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ExpandMacro {
    pub lib: Utf8PathBuf,
    pub env: Vec<(String, String)>,
    pub current_dir: Option<String>,
    pub data: ExpandMacroData,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ExpandMacroExtended {
    pub tree: FlatTree,
    pub span_data_table: Vec<u32>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ExpandMacroData {
    pub macro_body: FlatTree,
    pub macro_name: String,
    pub attributes: Option<FlatTree>,
    #[serde(default)]
    pub has_global_spans: ExpnGlobals,
    #[serde(default)]
    pub span_data_table: Vec<u32>,
}

#[derive(Clone, Copy, Default, Debug, Serialize, Deserialize)]
pub struct ExpnGlobals {
    pub def_site: usize,
    pub call_site: usize,
    pub mixed_site: usize,
}

impl Message for BidirectionalMessage {
    type Buf = Vec<u8>;

    fn read(inp: &mut dyn BufRead, buf: &mut Self::Buf) -> io::Result<Option<Self>> {
        Ok(match postcard::read(inp, buf)? {
            None => None,
            Some(buf) => Some(postcard::decode(buf)?),
        })
    }
    fn write(self, out: &mut dyn Write) -> io::Result<()> {
        let value = postcard::encode(&self)?;
        postcard::write(out, &value)
    }
}