Rendering. renderDescription produces SDL that can't be parsed
camarena opened this issue · comments
I'm having a problem with the parsing/rendering code in caliban. I have a couple of cases where the SDL generated by Rendering can't be parsed by RemoteSchema (or by a bunch of other graphQL tools for that matter).
The following snippet shows the problem.
import caliban.Rendering
import caliban.tools.{RemoteSchema, SchemaLoader}
import zio.Console._
import zio._
object ReproduceBug extends ZIOAppDefault {
val tripleQuoteSchema =
"\"\"\"This is a description \nwith a \"quote at the end\"\n\"\"\"" +
"""
|type MyType {
| aField: String
|}
|
|type Query{someQuery: MyType}
|""".stripMargin
def parseSchema(schema: String) = SchemaLoader.fromString(schema).load.flatMap(d => ZIO.fromOption(RemoteSchema.parseRemoteSchema(d)))
override def run = {
var topType = """schema{
| query: Query
|}
|""".stripMargin
for {
schema <- parseSchema(topType + tripleQuoteSchema)
_ <- printLine(s"Schema read ok")
renderedSchema <- ZIO.attempt(Rendering.renderTypes(schema.types))
_ <- printLine(s"Rendered schema contains four double quotes on description:\n$renderedSchema")
parsedRenderedSchema <- parseSchema(topType + renderedSchema).catchAll(_ =>
printLine("ERROR: Rendered schema can't be parsed")) *> ZIO.succeed()
} yield ()
}
}
This is how I'm working around the issue.
private def renderDescription(description: Option[String], newline: Boolean = true): String = description match
case None => ""
case Some(value) if newline =>
if value.contains("\n") then
renderTripleQuotedString("\n" + value + (if value.endsWith("\n") then "" else "\n")) + "\n"
else renderString(value) + "\n"
case Some(value) =>
if value.contains("\n") then renderTripleQuotedString(value + (if value.endsWith("\"") then " " else "")) + " "
else renderString(value) + " "
If you think this is the correct fix I can submit a PR.
Another concern I have as I read the October 2021 spec the grammar production for BlockString should not be greedy. So the parser should deal with BlockStrings that end in """
, """"
and """""
.
All the tools/parsers I tried are greedy since it is a lot easier to implement without looking ahead the incoming tokens. This makes my code necessary to interact with other tools.
You're right! A PR with the related tests would be welcome!
I'll work on the tests and submit the PR. This week is pretty busy at work but I'll get to it as soon as I can