Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 12 additions & 11 deletions crates/proc-macro-api/src/bidirectional_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use paths::AbsPath;
use span::Span;

use crate::{
Codec, ProcMacro, ProcMacroKind, ServerError,
ProcMacro, ProcMacroKind, ServerError,
bidirectional_protocol::msg::{
BidirectionalMessage, ExpandMacro, ExpandMacroData, ExpnGlobals, Request, Response,
SubRequest, SubResponse,
Expand All @@ -22,33 +22,33 @@ use crate::{
},
},
process::ProcMacroServerProcess,
transport::codec::postcard::PostcardProtocol,
transport::postcard,
};

pub mod msg;

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

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

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

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

match msg {
BidirectionalMessage::Response(response) => {
Expand All @@ -57,8 +57,9 @@ pub fn run_conversation<C: Codec>(
BidirectionalMessage::SubRequest(sr) => {
let resp = callback(sr)?;
let reply = BidirectionalMessage::SubResponse(resp);
let encoded = C::encode(&reply).map_err(wrap_encode)?;
C::write(writer, &encoded).map_err(wrap_io("failed to write sub-response"))?;
let encoded = postcard::encode(&reply).map_err(wrap_encode)?;
postcard::write(writer, &encoded)
.map_err(wrap_io("failed to write sub-response"))?;
}
_ => {
return Err(ServerError {
Expand Down Expand Up @@ -207,7 +208,7 @@ fn run_request(
if let Some(err) = srv.exited() {
return Err(err.clone());
}
srv.run_bidirectional::<PostcardProtocol>(msg, callback)
srv.run_bidirectional(msg, callback)
}

pub fn reject_subrequests(req: SubRequest) -> Result<SubResponse, ServerError> {
Expand Down
21 changes: 19 additions & 2 deletions crates/proc-macro-api/src/bidirectional_protocol/msg.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
//! Bidirectional protocol messages

use std::ops::Range;
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)]
Expand Down Expand Up @@ -97,4 +101,17 @@ pub struct ExpnGlobals {
pub mixed_site: usize,
}

impl Message for BidirectionalMessage {}
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)
}
}
12 changes: 5 additions & 7 deletions crates/proc-macro-api/src/legacy_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ use crate::{
flat::serialize_span_data_index_map,
},
process::ProcMacroServerProcess,
transport::codec::Codec,
transport::codec::json::JsonProtocol,
version,
};

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

srv.send_task::<_, _, JsonProtocol>(send_request::<JsonProtocol>, req)
srv.send_task_legacy::<_, _>(send_request, req)
}

/// Sends a request to the server and reads the response.
fn send_request<P: Codec>(
fn send_request(
mut writer: &mut dyn Write,
mut reader: &mut dyn BufRead,
req: Request,
buf: &mut P::Buf,
buf: &mut String,
) -> Result<Option<Response>, ServerError> {
req.write::<P>(&mut writer).map_err(|err| ServerError {
req.write(&mut writer).map_err(|err| ServerError {
message: "failed to write request".into(),
io: Some(Arc::new(err)),
})?;
let res = Response::read::<P>(&mut reader, buf).map_err(|err| ServerError {
let res = Response::read(&mut reader, buf).map_err(|err| ServerError {
message: "failed to read response".into(),
io: Some(Arc::new(err)),
})?;
Expand Down
38 changes: 29 additions & 9 deletions crates/proc-macro-api/src/legacy_protocol/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use paths::Utf8PathBuf;
use serde::de::DeserializeOwned;
use serde_derive::{Deserialize, Serialize};

use crate::{Codec, ProcMacroKind};
use crate::{ProcMacroKind, transport::json};

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

pub trait Message: serde::Serialize + DeserializeOwned {
fn read<C: Codec>(inp: &mut dyn BufRead, buf: &mut C::Buf) -> io::Result<Option<Self>> {
Ok(match C::read(inp, buf)? {
type Buf;
fn read(inp: &mut dyn BufRead, buf: &mut Self::Buf) -> io::Result<Option<Self>>;
fn write(self, out: &mut dyn Write) -> io::Result<()>;
}

impl Message for Request {
type Buf = String;

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

impl Message for Request {}
impl Message for Response {}
impl Message for Response {
type Buf = String;

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

#[cfg(test)]
mod tests {
Expand Down
1 change: 0 additions & 1 deletion crates/proc-macro-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use semver::Version;
use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
use std::{fmt, io, sync::Arc, time::SystemTime};

pub use crate::transport::codec::Codec;
use crate::{
bidirectional_protocol::SubCallback, pool::ProcMacroServerPool, process::ProcMacroServerProcess,
};
Expand Down
21 changes: 10 additions & 11 deletions crates/proc-macro-api/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use span::Span;
use stdx::JodChild;

use crate::{
Codec, ProcMacro, ProcMacroKind, ProtocolFormat, ServerError,
ProcMacro, ProcMacroKind, ProtocolFormat, ServerError,
bidirectional_protocol::{self, SubCallback, msg::BidirectionalMessage, reject_subrequests},
legacy_protocol::{self, SpanMode},
version,
Expand Down Expand Up @@ -305,17 +305,17 @@ impl ProcMacroServerProcess {
result
}

pub(crate) fn send_task<Request, Response, C: Codec>(
pub(crate) fn send_task_legacy<Request, Response>(
&self,
send: impl FnOnce(
&mut dyn Write,
&mut dyn BufRead,
Request,
&mut C::Buf,
&mut String,
) -> Result<Option<Response>, ServerError>,
req: Request,
) -> Result<Response, ServerError> {
self.with_locked_io::<C, _>(|writer, reader, buf| {
self.with_locked_io(String::new(), |writer, reader, buf| {
send(writer, reader, req, buf).and_then(|res| {
res.ok_or_else(|| {
let message = "proc-macro server did not respond with data".to_owned();
Expand All @@ -331,13 +331,12 @@ impl ProcMacroServerProcess {
})
}

pub(crate) fn with_locked_io<C: Codec, R>(
fn with_locked_io<R, B>(
&self,
f: impl FnOnce(&mut dyn Write, &mut dyn BufRead, &mut C::Buf) -> Result<R, ServerError>,
mut buf: B,
f: impl FnOnce(&mut dyn Write, &mut dyn BufRead, &mut B) -> Result<R, ServerError>,
) -> Result<R, ServerError> {
let state = &mut *self.state.lock().unwrap();
let mut buf = C::Buf::default();

f(&mut state.stdin, &mut state.stdout, &mut buf).map_err(|e| {
if e.io.as_ref().map(|it| it.kind()) == Some(io::ErrorKind::BrokenPipe) {
match state.process.exit_err() {
Expand All @@ -352,13 +351,13 @@ impl ProcMacroServerProcess {
})
}

pub(crate) fn run_bidirectional<C: Codec>(
pub(crate) fn run_bidirectional(
&self,
initial: BidirectionalMessage,
callback: SubCallback<'_>,
) -> Result<BidirectionalMessage, ServerError> {
self.with_locked_io::<C, _>(|writer, reader, buf| {
bidirectional_protocol::run_conversation::<C>(writer, reader, buf, initial, callback)
self.with_locked_io(Vec::new(), |writer, reader, buf| {
bidirectional_protocol::run_conversation(writer, reader, buf, initial, callback)
})
}

Expand Down
4 changes: 2 additions & 2 deletions crates/proc-macro-api/src/transport.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
//! Contains construct for transport of messages.
pub mod codec;
pub mod framing;
pub(crate) mod json;
pub(crate) mod postcard;
15 changes: 0 additions & 15 deletions crates/proc-macro-api/src/transport/codec.rs

This file was deleted.

58 changes: 0 additions & 58 deletions crates/proc-macro-api/src/transport/codec/json.rs

This file was deleted.

Loading