Skip to content

Commit 17304e9

Browse files
authored
Merge pull request #21548 from Shourya742/2026-01-29-decouple-codec-with-proc-macro
Make json and postcard protocols explicit, drop generic Codec
2 parents bb96978 + fb67545 commit 17304e9

17 files changed

Lines changed: 192 additions & 218 deletions

File tree

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/proc-macro-api/src/bidirectional_protocol.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use paths::AbsPath;
99
use span::Span;
1010

1111
use crate::{
12-
Codec, ProcMacro, ProcMacroKind, ServerError,
12+
ProcMacro, ProcMacroKind, ServerError,
1313
bidirectional_protocol::msg::{
1414
BidirectionalMessage, ExpandMacro, ExpandMacroData, ExpnGlobals, Request, Response,
1515
SubRequest, SubResponse,
@@ -22,33 +22,33 @@ use crate::{
2222
},
2323
},
2424
process::ProcMacroServerProcess,
25-
transport::codec::postcard::PostcardProtocol,
25+
transport::postcard,
2626
};
2727

2828
pub mod msg;
2929

3030
pub type SubCallback<'a> = &'a dyn Fn(SubRequest) -> Result<SubResponse, ServerError>;
3131

32-
pub fn run_conversation<C: Codec>(
32+
pub fn run_conversation(
3333
writer: &mut dyn Write,
3434
reader: &mut dyn BufRead,
35-
buf: &mut C::Buf,
35+
buf: &mut Vec<u8>,
3636
msg: BidirectionalMessage,
3737
callback: SubCallback<'_>,
3838
) -> Result<BidirectionalMessage, ServerError> {
39-
let encoded = C::encode(&msg).map_err(wrap_encode)?;
40-
C::write(writer, &encoded).map_err(wrap_io("failed to write initial request"))?;
39+
let encoded = postcard::encode(&msg).map_err(wrap_encode)?;
40+
postcard::write(writer, &encoded).map_err(wrap_io("failed to write initial request"))?;
4141

4242
loop {
43-
let maybe_buf = C::read(reader, buf).map_err(wrap_io("failed to read message"))?;
43+
let maybe_buf = postcard::read(reader, buf).map_err(wrap_io("failed to read message"))?;
4444
let Some(b) = maybe_buf else {
4545
return Err(ServerError {
4646
message: "proc-macro server closed the stream".into(),
4747
io: Some(Arc::new(io::Error::new(io::ErrorKind::UnexpectedEof, "closed"))),
4848
});
4949
};
5050

51-
let msg: BidirectionalMessage = C::decode(b).map_err(wrap_decode)?;
51+
let msg: BidirectionalMessage = postcard::decode(b).map_err(wrap_decode)?;
5252

5353
match msg {
5454
BidirectionalMessage::Response(response) => {
@@ -57,8 +57,9 @@ pub fn run_conversation<C: Codec>(
5757
BidirectionalMessage::SubRequest(sr) => {
5858
let resp = callback(sr)?;
5959
let reply = BidirectionalMessage::SubResponse(resp);
60-
let encoded = C::encode(&reply).map_err(wrap_encode)?;
61-
C::write(writer, &encoded).map_err(wrap_io("failed to write sub-response"))?;
60+
let encoded = postcard::encode(&reply).map_err(wrap_encode)?;
61+
postcard::write(writer, &encoded)
62+
.map_err(wrap_io("failed to write sub-response"))?;
6263
}
6364
_ => {
6465
return Err(ServerError {
@@ -207,7 +208,7 @@ fn run_request(
207208
if let Some(err) = srv.exited() {
208209
return Err(err.clone());
209210
}
210-
srv.run_bidirectional::<PostcardProtocol>(msg, callback)
211+
srv.run_bidirectional(msg, callback)
211212
}
212213

213214
pub fn reject_subrequests(req: SubRequest) -> Result<SubResponse, ServerError> {

crates/proc-macro-api/src/bidirectional_protocol/msg.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
//! Bidirectional protocol messages
22
3-
use std::ops::Range;
3+
use std::{
4+
io::{self, BufRead, Write},
5+
ops::Range,
6+
};
47

58
use paths::Utf8PathBuf;
69
use serde::{Deserialize, Serialize};
710

811
use crate::{
912
ProcMacroKind,
1013
legacy_protocol::msg::{FlatTree, Message, PanicMessage, ServerConfig},
14+
transport::postcard,
1115
};
1216

1317
#[derive(Debug, Serialize, Deserialize)]
@@ -97,4 +101,17 @@ pub struct ExpnGlobals {
97101
pub mixed_site: usize,
98102
}
99103

100-
impl Message for BidirectionalMessage {}
104+
impl Message for BidirectionalMessage {
105+
type Buf = Vec<u8>;
106+
107+
fn read(inp: &mut dyn BufRead, buf: &mut Self::Buf) -> io::Result<Option<Self>> {
108+
Ok(match postcard::read(inp, buf)? {
109+
None => None,
110+
Some(buf) => Some(postcard::decode(buf)?),
111+
})
112+
}
113+
fn write(self, out: &mut dyn Write) -> io::Result<()> {
114+
let value = postcard::encode(&self)?;
115+
postcard::write(out, &value)
116+
}
117+
}

crates/proc-macro-api/src/legacy_protocol.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ use crate::{
1818
flat::serialize_span_data_index_map,
1919
},
2020
process::ProcMacroServerProcess,
21-
transport::codec::Codec,
22-
transport::codec::json::JsonProtocol,
2321
version,
2422
};
2523

@@ -149,21 +147,21 @@ fn send_task(srv: &ProcMacroServerProcess, req: Request) -> Result<Response, Ser
149147
return Err(server_error.clone());
150148
}
151149

152-
srv.send_task::<_, _, JsonProtocol>(send_request::<JsonProtocol>, req)
150+
srv.send_task_legacy::<_, _>(send_request, req)
153151
}
154152

155153
/// Sends a request to the server and reads the response.
156-
fn send_request<P: Codec>(
154+
fn send_request(
157155
mut writer: &mut dyn Write,
158156
mut reader: &mut dyn BufRead,
159157
req: Request,
160-
buf: &mut P::Buf,
158+
buf: &mut String,
161159
) -> Result<Option<Response>, ServerError> {
162-
req.write::<P>(&mut writer).map_err(|err| ServerError {
160+
req.write(&mut writer).map_err(|err| ServerError {
163161
message: "failed to write request".into(),
164162
io: Some(Arc::new(err)),
165163
})?;
166-
let res = Response::read::<P>(&mut reader, buf).map_err(|err| ServerError {
164+
let res = Response::read(&mut reader, buf).map_err(|err| ServerError {
167165
message: "failed to read response".into(),
168166
io: Some(Arc::new(err)),
169167
})?;

crates/proc-macro-api/src/legacy_protocol/msg.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use paths::Utf8PathBuf;
88
use serde::de::DeserializeOwned;
99
use serde_derive::{Deserialize, Serialize};
1010

11-
use crate::{Codec, ProcMacroKind};
11+
use crate::{ProcMacroKind, transport::json};
1212

1313
/// Represents requests sent from the client to the proc-macro-srv.
1414
#[derive(Debug, Serialize, Deserialize)]
@@ -155,20 +155,40 @@ impl ExpnGlobals {
155155
}
156156

157157
pub trait Message: serde::Serialize + DeserializeOwned {
158-
fn read<C: Codec>(inp: &mut dyn BufRead, buf: &mut C::Buf) -> io::Result<Option<Self>> {
159-
Ok(match C::read(inp, buf)? {
158+
type Buf;
159+
fn read(inp: &mut dyn BufRead, buf: &mut Self::Buf) -> io::Result<Option<Self>>;
160+
fn write(self, out: &mut dyn Write) -> io::Result<()>;
161+
}
162+
163+
impl Message for Request {
164+
type Buf = String;
165+
166+
fn read(inp: &mut dyn BufRead, buf: &mut Self::Buf) -> io::Result<Option<Self>> {
167+
Ok(match json::read(inp, buf)? {
160168
None => None,
161-
Some(buf) => Some(C::decode(buf)?),
169+
Some(buf) => Some(json::decode(buf)?),
162170
})
163171
}
164-
fn write<C: Codec>(self, out: &mut dyn Write) -> io::Result<()> {
165-
let value = C::encode(&self)?;
166-
C::write(out, &value)
172+
fn write(self, out: &mut dyn Write) -> io::Result<()> {
173+
let value = json::encode(&self)?;
174+
json::write(out, &value)
167175
}
168176
}
169177

170-
impl Message for Request {}
171-
impl Message for Response {}
178+
impl Message for Response {
179+
type Buf = String;
180+
181+
fn read(inp: &mut dyn BufRead, buf: &mut Self::Buf) -> io::Result<Option<Self>> {
182+
Ok(match json::read(inp, buf)? {
183+
None => None,
184+
Some(buf) => Some(json::decode(buf)?),
185+
})
186+
}
187+
fn write(self, out: &mut dyn Write) -> io::Result<()> {
188+
let value = json::encode(&self)?;
189+
json::write(out, &value)
190+
}
191+
}
172192

173193
#[cfg(test)]
174194
mod tests {

crates/proc-macro-api/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use semver::Version;
2727
use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
2828
use std::{fmt, io, sync::Arc, time::SystemTime};
2929

30-
pub use crate::transport::codec::Codec;
3130
use crate::{
3231
bidirectional_protocol::SubCallback, pool::ProcMacroServerPool, process::ProcMacroServerProcess,
3332
};

crates/proc-macro-api/src/process.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use span::Span;
1717
use stdx::JodChild;
1818

1919
use crate::{
20-
Codec, ProcMacro, ProcMacroKind, ProtocolFormat, ServerError,
20+
ProcMacro, ProcMacroKind, ProtocolFormat, ServerError,
2121
bidirectional_protocol::{self, SubCallback, msg::BidirectionalMessage, reject_subrequests},
2222
legacy_protocol::{self, SpanMode},
2323
version,
@@ -305,17 +305,17 @@ impl ProcMacroServerProcess {
305305
result
306306
}
307307

308-
pub(crate) fn send_task<Request, Response, C: Codec>(
308+
pub(crate) fn send_task_legacy<Request, Response>(
309309
&self,
310310
send: impl FnOnce(
311311
&mut dyn Write,
312312
&mut dyn BufRead,
313313
Request,
314-
&mut C::Buf,
314+
&mut String,
315315
) -> Result<Option<Response>, ServerError>,
316316
req: Request,
317317
) -> Result<Response, ServerError> {
318-
self.with_locked_io::<C, _>(|writer, reader, buf| {
318+
self.with_locked_io(String::new(), |writer, reader, buf| {
319319
send(writer, reader, req, buf).and_then(|res| {
320320
res.ok_or_else(|| {
321321
let message = "proc-macro server did not respond with data".to_owned();
@@ -331,13 +331,12 @@ impl ProcMacroServerProcess {
331331
})
332332
}
333333

334-
pub(crate) fn with_locked_io<C: Codec, R>(
334+
fn with_locked_io<R, B>(
335335
&self,
336-
f: impl FnOnce(&mut dyn Write, &mut dyn BufRead, &mut C::Buf) -> Result<R, ServerError>,
336+
mut buf: B,
337+
f: impl FnOnce(&mut dyn Write, &mut dyn BufRead, &mut B) -> Result<R, ServerError>,
337338
) -> Result<R, ServerError> {
338339
let state = &mut *self.state.lock().unwrap();
339-
let mut buf = C::Buf::default();
340-
341340
f(&mut state.stdin, &mut state.stdout, &mut buf).map_err(|e| {
342341
if e.io.as_ref().map(|it| it.kind()) == Some(io::ErrorKind::BrokenPipe) {
343342
match state.process.exit_err() {
@@ -352,13 +351,13 @@ impl ProcMacroServerProcess {
352351
})
353352
}
354353

355-
pub(crate) fn run_bidirectional<C: Codec>(
354+
pub(crate) fn run_bidirectional(
356355
&self,
357356
initial: BidirectionalMessage,
358357
callback: SubCallback<'_>,
359358
) -> Result<BidirectionalMessage, ServerError> {
360-
self.with_locked_io::<C, _>(|writer, reader, buf| {
361-
bidirectional_protocol::run_conversation::<C>(writer, reader, buf, initial, callback)
359+
self.with_locked_io(Vec::new(), |writer, reader, buf| {
360+
bidirectional_protocol::run_conversation(writer, reader, buf, initial, callback)
362361
})
363362
}
364363

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
//! Contains construct for transport of messages.
2-
pub mod codec;
3-
pub mod framing;
2+
pub(crate) mod json;
3+
pub(crate) mod postcard;

crates/proc-macro-api/src/transport/codec.rs

Lines changed: 0 additions & 15 deletions
This file was deleted.

crates/proc-macro-api/src/transport/codec/json.rs

Lines changed: 0 additions & 58 deletions
This file was deleted.

0 commit comments

Comments
 (0)