-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
376 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,8 @@ | ||
import raw.client.jinja.sql.JinjaSqlCompilerServiceBuilder; | ||
module raw.client.jinja.sql { | ||
requires scala.library; | ||
requires raw.client; | ||
requires jinjava; | ||
|
||
module raw.client.jinja { | ||
requires scala.library; | ||
requires raw.client; | ||
|
||
provides raw.client.api.CompilerServiceBuilder with | ||
JinjaSqlCompilerServiceBuilder; | ||
|
||
} | ||
provides raw.client.api.CompilerServiceBuilder with | ||
raw.client.jinja.sql.JinjaSqlCompilerServiceBuilder; | ||
} |
1 change: 0 additions & 1 deletion
1
jinja-sql-client/src/main/resources/META-INF.services/raw.client.api.CompilerServiceBuilder
This file was deleted.
Oops, something went wrong.
1 change: 1 addition & 0 deletions
1
jinja-sql-client/src/main/resources/META-INF/services/raw.client.api.CompilerServiceBuilder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
raw.client.jinja.sql.JinjaSqlCompilerServiceBuilder |
247 changes: 212 additions & 35 deletions
247
jinja-sql-client/src/main/scala/raw/client/jinja/sql/JinjaSqlCompilerService.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,237 @@ | ||
package raw.client.jinja.sql | ||
|
||
import com.hubspot.jinjava.interpret.TemplateError.{ErrorReason, ErrorType} | ||
import com.hubspot.jinjava.interpret.{JinjavaInterpreter, TemplateError} | ||
import com.hubspot.jinjava.lib.fn.ELFunctionDefinition | ||
import com.hubspot.jinjava.lib.tag.Tag | ||
import com.hubspot.jinjava.tree.TagNode | ||
import com.hubspot.jinjava.{Jinjava, JinjavaConfig} | ||
import raw.client.api._ | ||
import raw.utils.RawSettings | ||
|
||
class JinjaSqlCompilerService(maybeClassLoader: Option[ClassLoader] = None)(implicit protected val settings: RawSettings) extends CompilerService { | ||
import java.util | ||
import scala.collection.mutable | ||
|
||
/** As seen from class JinjaSqlCompilerService, the missing signatures are as follows. | ||
* * For convenience, these are usable as stub implementations. | ||
* */ | ||
// Members declared in raw.client.api.CompilerService | ||
|
||
class JinjaSqlCompilerService(maybeClassLoader: Option[ClassLoader] = None)( | ||
implicit protected val settings: RawSettings | ||
) extends CompilerService { | ||
|
||
def aiValidate(source: String, environment: raw.client.api.ProgramEnvironment): raw.client.api.ValidateResponse = ??? | ||
|
||
private val sqlCompilerService = CompilerServiceProvider("sql", maybeClassLoader) | ||
|
||
def dotAutoComplete( | ||
source: String, | ||
environment: raw.client.api.ProgramEnvironment, | ||
position: raw.client.api.Pos | ||
): raw.client.api.AutoCompleteResponse = AutoCompleteResponse(Array.empty) | ||
|
||
private val validationConfigBuilder = JinjavaConfig | ||
.newBuilder() | ||
.withValidationMode(true) | ||
.withMaxOutputSize(10000) | ||
.withFailOnUnknownTokens(false) | ||
.withNestedInterpretationEnabled(false) | ||
|
||
private val validationConfig = validationConfigBuilder.build() | ||
|
||
private val executionConfig = validationConfigBuilder.withFailOnUnknownTokens(true).build() | ||
|
||
private val validateJinjava = new Jinjava(validationConfig) | ||
private val executeJinjava = new Jinjava(executionConfig) | ||
|
||
private object FailFunc { | ||
def doFail(): String = { | ||
"doFail" | ||
} | ||
def dontFail(): String = { | ||
"dontFail" | ||
} | ||
} | ||
|
||
private class RaiseTag(doRaise: Boolean) extends Tag { | ||
|
||
override def interpret(tagNode: TagNode, interpreter: JinjavaInterpreter): String = { | ||
if (doRaise) { | ||
val o = interpreter.resolveELExpression(tagNode.getHelpers, tagNode.getLineNumber, tagNode.getStartPosition) | ||
val error = new TemplateError(ErrorType.FATAL, ErrorReason.EXCEPTION, o.asInstanceOf[String], null, 0, 0, null) | ||
interpreter.addError(error) | ||
} | ||
s"<$getName>" | ||
} | ||
|
||
override def getEndTagName: String = null | ||
|
||
override def getName: String = "raise" | ||
} | ||
|
||
private class ParamTag() extends Tag { | ||
|
||
override def interpret(tagNode: TagNode, interpreter: JinjavaInterpreter): String = { | ||
s"-- <$getName>" | ||
} | ||
|
||
override def getEndTagName: String = null | ||
|
||
override def getName: String = "param" | ||
} | ||
|
||
private class TypeTag() extends Tag { | ||
|
||
def dotAutoComplete(source: String, environment: raw.client.api.ProgramEnvironment, position: raw.client.api.Pos): raw.client.api.AutoCompleteResponse = ??? | ||
|
||
override def interpret(tagNode: TagNode, interpreter: JinjavaInterpreter): String = { | ||
s"-- <$getName>" | ||
} | ||
|
||
def eval(source: String, tipe: raw.client.api.RawType, environment: raw.client.api.ProgramEnvironment): raw.client.api.EvalResponse = ??? | ||
|
||
override def getEndTagName: String = null | ||
|
||
def execute(source: String, environment: raw.client.api.ProgramEnvironment, maybeDecl: Option[String], outputStream: java.io.OutputStream): raw.client.api.ExecutionResponse = { | ||
override def getName: String = "type" | ||
} | ||
|
||
private class DefaultTag() extends Tag { | ||
|
||
override def interpret(tagNode: TagNode, interpreter: JinjavaInterpreter): String = { | ||
s"-- <$getName>" | ||
} | ||
|
||
override def getEndTagName: String = null | ||
|
||
override def getName: String = "default" | ||
} | ||
|
||
private val doFail = new ELFunctionDefinition("raw", "fail", FailFunc.getClass, "doFail") | ||
private val dontFail = new ELFunctionDefinition("raw", "fail", FailFunc.getClass, "dontFail") | ||
|
||
validateJinjava.getGlobalContext.registerFunction(dontFail) | ||
executeJinjava.getGlobalContext.registerFunction(doFail) | ||
|
||
validateJinjava.getGlobalContext.registerTag(new RaiseTag(doRaise = false)) | ||
executeJinjava.getGlobalContext.registerTag(new RaiseTag(doRaise = true)) | ||
for (tag <- List(new ParamTag(), new DefaultTag(), new TypeTag())) { | ||
validateJinjava.registerTag(tag) | ||
executeJinjava.registerTag(tag) | ||
} | ||
|
||
def execute( | ||
source: String, | ||
environment: raw.client.api.ProgramEnvironment, | ||
maybeDecl: Option[String], | ||
outputStream: java.io.OutputStream | ||
): raw.client.api.ExecutionResponse = { | ||
logger.debug("execute") | ||
??? | ||
val arguments = new util.HashMap[String, Object]() | ||
environment.maybeArguments.foreach(_.foreach { case (k, v) => arguments.put(k, rawValueToString(v)) }) | ||
val result = executeJinjava.renderForResult(source, arguments) | ||
if (result.getErrors.isEmpty) { | ||
val processed = result.getOutput | ||
sqlCompilerService.execute(processed, environment, maybeDecl, outputStream) | ||
} else { | ||
ExecutionValidationFailure(asMessages(result.getErrors)) | ||
} | ||
} | ||
|
||
|
||
def formatCode(source: String, environment: raw.client.api.ProgramEnvironment, maybeIndent: Option[Int], maybeWidth: Option[Int]): raw.client.api.FormatCodeResponse = ??? | ||
|
||
private def rawValueToString(value: RawValue) = value match { | ||
case RawString(v) => v | ||
case _ => ??? | ||
} | ||
|
||
def getProgramDescription(source: String, environment: raw.client.api.ProgramEnvironment): raw.client.api.GetProgramDescriptionResponse = ??? | ||
|
||
def eval( | ||
source: String, | ||
tipe: raw.client.api.RawType, | ||
environment: raw.client.api.ProgramEnvironment | ||
): raw.client.api.EvalResponse = ??? | ||
|
||
def goToDefinition(source: String, environment: raw.client.api.ProgramEnvironment, position: raw.client.api.Pos): raw.client.api.GoToDefinitionResponse = ??? | ||
|
||
def aiValidate(source: String, environment: raw.client.api.ProgramEnvironment): raw.client.api.ValidateResponse = ??? | ||
|
||
def hover(source: String, environment: raw.client.api.ProgramEnvironment, position: raw.client.api.Pos): raw.client.api.HoverResponse = ??? | ||
|
||
def formatCode( | ||
source: String, | ||
environment: raw.client.api.ProgramEnvironment, | ||
maybeIndent: Option[Int], | ||
maybeWidth: Option[Int] | ||
): raw.client.api.FormatCodeResponse = FormatCodeResponse(None) | ||
|
||
def getProgramDescription( | ||
source: String, | ||
environment: raw.client.api.ProgramEnvironment | ||
): raw.client.api.GetProgramDescriptionResponse = { | ||
val unknownVariables = mutable.Set.empty[String] | ||
validateJinjava.getGlobalContext.setDynamicVariableResolver(v => { | ||
unknownVariables.add(v); "" | ||
}) | ||
val result = validateJinjava.renderForResult(source, new java.util.HashMap) | ||
if (result.hasErrors) { | ||
GetProgramDescriptionFailure(asMessages(result.getErrors)) | ||
} else { | ||
GetProgramDescriptionSuccess( | ||
ProgramDescription( | ||
Map.empty, | ||
Some( | ||
DeclDescription( | ||
Some( | ||
unknownVariables.map(ParamDescription(_, Some(RawStringType(false, false)), None, None, true)).toVector | ||
), | ||
Some(RawIterableType(RawAnyType(), false, false)), | ||
None | ||
) | ||
), | ||
None | ||
) | ||
) | ||
} | ||
} | ||
|
||
def rename(source: String, environment: raw.client.api.ProgramEnvironment, position: raw.client.api.Pos): raw.client.api.RenameResponse = ??? | ||
def goToDefinition( | ||
source: String, | ||
environment: raw.client.api.ProgramEnvironment, | ||
position: raw.client.api.Pos | ||
): raw.client.api.GoToDefinitionResponse = GoToDefinitionResponse(None) | ||
|
||
def hover( | ||
source: String, | ||
environment: raw.client.api.ProgramEnvironment, | ||
position: raw.client.api.Pos | ||
): raw.client.api.HoverResponse = HoverResponse(None) | ||
|
||
def rename( | ||
source: String, | ||
environment: raw.client.api.ProgramEnvironment, | ||
position: raw.client.api.Pos | ||
): raw.client.api.RenameResponse = RenameResponse(Array.empty) | ||
|
||
def validate(source: String, environment: raw.client.api.ProgramEnvironment): ValidateResponse = { | ||
val result = validateJinjava.renderForResult(source, new java.util.HashMap()) | ||
val errors = asMessages(result.getErrors) | ||
ValidateResponse(errors) | ||
} | ||
|
||
private def asMessages(errors: util.List[TemplateError]): List[ErrorMessage] = { | ||
val errorMessages = mutable.ArrayBuffer.empty[ErrorMessage] | ||
errors.forEach { error => | ||
val message = error.getMessage | ||
val line = error.getLineno | ||
val column = error.getStartPosition | ||
val range = ErrorRange(ErrorPosition(line, column), ErrorPosition(line, column + 1)) | ||
val errorMessage = ErrorMessage(message, List(range), "") | ||
errorMessages += errorMessage | ||
} | ||
errorMessages.toList | ||
|
||
} | ||
|
||
def validate(source: String, environment: raw.client.api.ProgramEnvironment): raw.client.api.ValidateResponse = ??? | ||
|
||
def wordAutoComplete( | ||
source: String, | ||
environment: raw.client.api.ProgramEnvironment, | ||
prefix: String, | ||
position: raw.client.api.Pos | ||
): raw.client.api.AutoCompleteResponse = AutoCompleteResponse(Array.empty) | ||
|
||
def wordAutoComplete(source: String, environment: raw.client.api.ProgramEnvironment, prefix: String, position: raw.client.api.Pos): raw.client.api.AutoCompleteResponse = ??? | ||
|
||
// Members declared in raw.utils.RawService | ||
|
||
// Members declared in raw.utils.RawService | ||
|
||
def doStop(): Unit = ??? | ||
def doStop(): Unit = { | ||
sqlCompilerService.stop() | ||
} | ||
|
||
def build(maybeClassLoader: Option[ClassLoader])(implicit settings: raw.utils.RawSettings): raw.client.api.CompilerService = ??? | ||
|
||
def build(maybeClassLoader: Option[ClassLoader])( | ||
implicit settings: raw.utils.RawSettings | ||
): raw.client.api.CompilerService = ??? | ||
|
||
def language: Set[String] = ??? | ||
def language: Set[String] = Set("jinja-sql") | ||
|
||
} |
9 changes: 5 additions & 4 deletions
9
jinja-sql-client/src/main/scala/raw/client/jinja/sql/JinjaSqlCompilerServiceBuilder.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
package raw.client.jinja.sql | ||
|
||
import raw.client.api._ | ||
|
||
import raw.client.api.{CompilerService, CompilerServiceBuilder} | ||
import raw.utils.RawSettings | ||
|
||
class JinjaSqlCompilerServiceBuilder extends CompilerServiceBuilder { | ||
override def language: Set[String] = Set("jinja-sql") | ||
|
||
def build(maybeClassLoader: Option[ClassLoader])(implicit settings: raw.utils.RawSettings): raw.client.api.CompilerService = new JinjaSqlCompilerService(maybeClassLoader) | ||
override def build(maybeClassLoader: Option[ClassLoader])(implicit settings: RawSettings): CompilerService = | ||
new JinjaSqlCompilerService(maybeClassLoader) | ||
|
||
def language: Set[String] = Set("jinja-sql") | ||
} |
Oops, something went wrong.