Description
The problem
Using Scala 2 macros, we have built an RPC framework that can automatically generate implementations of arbitrary traits. These implementations are effectively network proxies that translate every method call into a network request. When the request is received by the RPC server, a reverse translation is performed and a real implementation of this trait is invoked.
A very simplified example of this mechanism:
trait RawRpc {
def invoke(methodName: String, parameters: Map[String, Json]): Future[Json]
}
object RawRpc {
def asReal[RealRpc](rawRpc: RawRpc): RealRpc = macro ...
def asRaw[RealRpc](realRpc: RealRpc): RawRpc = macro ...
}
The asReal
macro needs to do the following:
- enumerate all (abstract) methods of
RealRpc
- for every parameter of every method, find a typeclass instance that would allow it to serialize it into
Json
- for every method's result type, find a typeclass instance that would allow it to deserialize it from
Json
(assuming that the result type is aFuture
) - generate an implementation of every method that forwards it to
rawRpc
- inspect annotations on methods and parameters in order to treat them in some special way
The asRaw
macro needs similar capabilities in order to perform a reverse translation.
Situation in Scala 3
It's unclear to me whether something like this is possible with Scala 3. Looking at the Quotes
API, it should in principle be possible if I was able to generate arbitrary trees, starting with ClassDef
. However, it seems that currently ClassDef.apply
is commented out and marked as TODO.
So my questions are:
- First of all, is this a valid use case for Scala 3 metaprogramming?
- If yes, can this be done with
Quotes
API? - Are there any serious obstacles preventing methods like
ClassDef.apply
from being exposed?
(Note: I asked this question briefly on Gitter and it was recommended to me to create an issue.)