Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ : HCL parsing #167

Merged
merged 16 commits into from
Nov 15, 2019
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
24 changes: 24 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,13 @@
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>

<!-- antlr for HCL parsing -->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.7</version>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -254,6 +261,23 @@
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.7</version>
<executions>
<execution>
<goals>
<goal>antlr4</goal>
</goals>
<configuration>
<visitor>true</visitor>
<listener>false</listener>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
156 changes: 156 additions & 0 deletions src/main/antlr4/io/codeka/gaia/hcl/antlr/hcl.g4
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
grammar hcl;

file
: directive+
;

directive
: variableDirective
| outputDirective
;

variableDirective
: 'variable' STRING variableBlock
;

variableBlock
: '{' (variableType|variableDescription|variableDefault)+ '}'
;

outputDirective
: 'output' STRING outputBlock
;

outputBlock
: '{' (outputValue|outputDescription|outputSensitive)+ '}'
;

outputValue
: 'value' '=' expression
;

outputDescription
: 'description' '=' STRING
;

outputSensitive
: 'sensitive' '=' BOOLEAN
;

variableType
: 'type' '=' type
;

type
: TYPE
| 'list'
| 'list(' type ')'
| 'map(' type ')'
| 'object' '(' object ')'
;

object
: '{' '}'
| '{' field+ '}'
;

field: IDENTIFIER '=' expression;

variableDescription
: 'description' '=' STRING
;

variableDefault
: 'default' '=' expression
;

expression
: STRING
| NUMBER
| BOOLEAN
| array
| object
| complexExpression
;

functionCall
: IDENTIFIER '(' expression ( ',' expression )* ','? ')'
;

complexExpression
: IDENTIFIER
| complexExpression '.' complexExpression // attribute access
| complexExpression '[' index ']' // indexed array access
| complexExpression '.' index // indexed attribute access
| functionCall
;

array
: '[' ']'
| '[' expression ( ',' expression )* ','? ']'
;

index
: NUMBER
| '*'
;

BOOLEAN
: 'true'
| '"true"'
| 'false'
| '"false"'
;

TYPE
: 'string'
| '"string"'
| 'number'
| '"number"'
| 'bool'
| '"bool"'
| 'any'
;

IDENTIFIER: Letter LetterOrDigit*;

fragment LetterOrDigit
: Letter
| [0-9]
;
fragment Letter
: [a-zA-Z$_] // these are the "java letters" below 0x7F
| ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate
| [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
;

/**
* STRING Lexer Rule comes from the JSON grammar
* https://github.com/antlr/grammars-v4/blob/master/json/JSON.g4
*/
STRING
: '"' (ESC | SAFECODEPOINT)* '"'
;

fragment ESC
: '\\' (["\\/bfnrt] | UNICODE)
;
fragment UNICODE
: 'u' HEX HEX HEX HEX
;
fragment HEX
: [0-9a-fA-F]
;
fragment SAFECODEPOINT
: ~ ["\\\u0000-\u001F]
;

NUMBER
: '0' | [1-9] [0-9]*
;

// comments and whitespaces
COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN);
HAS_COMMENT: '#' ~ [\r\n]* -> channel(HIDDEN);
WS: [ \t\r\n]+ -> channel(HIDDEN); // skip spaces, tabs, newlines
40 changes: 40 additions & 0 deletions src/main/java/io/codeka/gaia/hcl/HclParser.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.codeka.gaia.hcl

import io.codeka.gaia.hcl.antlr.hclLexer
import io.codeka.gaia.hcl.antlr.hclParser
import io.codeka.gaia.modules.bo.Output
import io.codeka.gaia.modules.bo.Variable
import org.antlr.v4.runtime.CharStreams
import org.antlr.v4.runtime.CommonTokenStream

class HclParser {

private fun parseContent(content: String): HclVisitor {
// loading test file
val charStream = CharStreams.fromString(content)

// configuring antlr lexer
val lexer = hclLexer(charStream)

// using the lexer to configure a token stream
val tokenStream = CommonTokenStream(lexer)

// configuring antlr parser using the token stream
val parser = hclParser(tokenStream)

// visit the AST
val hclVisitor = HclVisitor()
hclVisitor.visit(parser.file())
return hclVisitor
}

fun parseVariables(content:String): List<Variable> {
val hclVisitor = parseContent(content)
return hclVisitor.variables
}

fun parseOutputs(content:String): List<Output> {
val hclVisitor = parseContent(content)
return hclVisitor.outputs
}
}
52 changes: 52 additions & 0 deletions src/main/java/io/codeka/gaia/hcl/HclVisitor.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.codeka.gaia.hcl

import io.codeka.gaia.hcl.antlr.hclBaseVisitor
import io.codeka.gaia.hcl.antlr.hclParser
import io.codeka.gaia.modules.bo.Output
import io.codeka.gaia.modules.bo.Variable
import java.util.*

class HclVisitor : hclBaseVisitor<Unit>() {

var variables: MutableList<Variable> = LinkedList()
var outputs: MutableList<Output> = LinkedList()

private var currentVariable: Variable = Variable(name = "")
private var currentOutput: Output = Output()

override fun visitVariableDirective(ctx: hclParser.VariableDirectiveContext) {
currentVariable = Variable(name = ctx.STRING().text.removeSurrounding("\""))
variables.add(currentVariable)
visitChildren(ctx)
}

override fun visitVariableType(ctx: hclParser.VariableTypeContext) {
currentVariable.type = ctx.type().text.removeSurrounding("\"")
}

override fun visitVariableDefault(ctx: hclParser.VariableDefaultContext) {
currentVariable.defaultValue = ctx.expression().text.removeSurrounding("\"")
}

override fun visitVariableDescription(ctx: hclParser.VariableDescriptionContext) {
currentVariable.description = ctx.STRING().text.removeSurrounding("\"")
}

override fun visitOutputDirective(ctx: hclParser.OutputDirectiveContext) {
currentOutput = Output(name = ctx.STRING().text.removeSurrounding("\""))
outputs.add(currentOutput)
visitChildren(ctx)
}

override fun visitOutputDescription(ctx: hclParser.OutputDescriptionContext) {
currentOutput.description = ctx.STRING().text.removeSurrounding("\"")
}

override fun visitOutputValue(ctx: hclParser.OutputValueContext) {
currentOutput.value = ctx.expression().text.removeSurrounding("\"")
}

override fun visitOutputSensitive(ctx: hclParser.OutputSensitiveContext) {
currentOutput.sensitive = ctx.BOOLEAN().text.removeSurrounding("\"")
}
}
10 changes: 10 additions & 0 deletions src/main/java/io/codeka/gaia/modules/bo/Output.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.codeka.gaia.modules.bo

/**
* Represents a module output
*/
data class Output(
var name: String = "",
var value: String = "",
var description: String = "",
var sensitive: String = "false");
6 changes: 3 additions & 3 deletions src/main/java/io/codeka/gaia/modules/bo/TerraformModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class TerraformModule {
private String directory;

@Valid
private List<TerraformVariable> variables = new ArrayList<>();
private List<Variable> variables = new ArrayList<>();

@NotBlank
private String name;
Expand Down Expand Up @@ -93,11 +93,11 @@ public String getDescription() {
return description;
}

public List<TerraformVariable> getVariables() {
public List<Variable> getVariables() {
return variables;
}

public void setVariables(List<TerraformVariable> variables) {
public void setVariables(List<Variable> variables) {
this.variables = variables;
}

Expand Down
71 changes: 0 additions & 71 deletions src/main/java/io/codeka/gaia/modules/bo/TerraformVariable.java

This file was deleted.

Loading