in log4j-api-scala_3/src/main/scala/org/apache/logging/log4j/scala/LoggerMacro.scala [499:532]
private[scala] def deconstructInterpolatedMessage(message: Expr[CharSequence])(using Quotes): (Expr[CharSequence], Seq[Expr[Any]]) = {
import quotes.reflect.*
import util.*
message.asTerm match{
case Inlined(_, _, Apply(Select(Apply(Select(Select(_, "StringContext"), _), messageNode), _), argumentsNode)) =>
val messageTextPartsOpt: Option[List[String]] =
messageNode.collectFirst{
case Typed(Repeated(ls, _), _) =>
ls.collect{ case Literal(StringConstant(s)) => s}
}
val argsOpt: Option[List[Term]] =
argumentsNode.collectFirst {
case Typed(Repeated(ls, _), _) => ls
}
(messageTextPartsOpt, argsOpt) match{
case (Some(messageTextParts), Some(args)) =>
val format = messageTextParts.iterator
// Emulate standard interpolator escaping
.map(StringContext.processEscapes)
// Escape literal log4j format anchors if the resulting call will require a format string
.map(str => if (args.nonEmpty) str.replace("{}", "\\{}") else str)
.mkString("{}")
val formatArgs = args.map(_.asExpr)
(Expr(format), formatArgs)
case _ =>
(message, Seq.empty)
}
case _ => (message, Seq.empty)
}
}