summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/hashicorp/hcl/hcl/printer
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/hcl/hcl/printer')
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go779
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/printer.go67
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/printer_test.go153
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.golden36
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.input37
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.golden32
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.input28
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_array.golden13
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_array.input13
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_end_file.golden6
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_end_file.input5
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_indent.golden12
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_indent.input13
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_no_stanza.golden7
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_no_stanza.input6
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_stanza.golden10
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_stanza.input10
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_newline.golden3
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_newline.input2
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_object_multi.golden9
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_object_multi.input9
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.golden17
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.input16
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.golden54
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.input53
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.golden12
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.input14
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.golden43
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.input37
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_comment.golden7
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_comment.input6
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_of_objects.golden10
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_of_objects.input10
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/multiline_string.golden7
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/multiline_string.input7
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_singleline.golden26
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_singleline.input19
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_with_heredoc.golden6
-rw-r--r--vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_with_heredoc.input6
39 files changed, 1600 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go b/vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go
new file mode 100644
index 000000000..c896d5844
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go
@@ -0,0 +1,779 @@
+package printer
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+
+ "github.com/hashicorp/hcl/hcl/ast"
+ "github.com/hashicorp/hcl/hcl/token"
+)
+
+const (
+ blank = byte(' ')
+ newline = byte('\n')
+ tab = byte('\t')
+ infinity = 1 << 30 // offset or line
+)
+
+var (
+ unindent = []byte("\uE123") // in the private use space
+)
+
+type printer struct {
+ cfg Config
+ prev token.Pos
+
+ comments []*ast.CommentGroup // may be nil, contains all comments
+ standaloneComments []*ast.CommentGroup // contains all standalone comments (not assigned to any node)
+
+ enableTrace bool
+ indentTrace int
+}
+
+type ByPosition []*ast.CommentGroup
+
+func (b ByPosition) Len() int { return len(b) }
+func (b ByPosition) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
+func (b ByPosition) Less(i, j int) bool { return b[i].Pos().Before(b[j].Pos()) }
+
+// collectComments comments all standalone comments which are not lead or line
+// comment
+func (p *printer) collectComments(node ast.Node) {
+ // first collect all comments. This is already stored in
+ // ast.File.(comments)
+ ast.Walk(node, func(nn ast.Node) (ast.Node, bool) {
+ switch t := nn.(type) {
+ case *ast.File:
+ p.comments = t.Comments
+ return nn, false
+ }
+ return nn, true
+ })
+
+ standaloneComments := make(map[token.Pos]*ast.CommentGroup, 0)
+ for _, c := range p.comments {
+ standaloneComments[c.Pos()] = c
+ }
+
+ // next remove all lead and line comments from the overall comment map.
+ // This will give us comments which are standalone, comments which are not
+ // assigned to any kind of node.
+ ast.Walk(node, func(nn ast.Node) (ast.Node, bool) {
+ switch t := nn.(type) {
+ case *ast.LiteralType:
+ if t.LeadComment != nil {
+ for _, comment := range t.LeadComment.List {
+ if _, ok := standaloneComments[comment.Pos()]; ok {
+ delete(standaloneComments, comment.Pos())
+ }
+ }
+ }
+
+ if t.LineComment != nil {
+ for _, comment := range t.LineComment.List {
+ if _, ok := standaloneComments[comment.Pos()]; ok {
+ delete(standaloneComments, comment.Pos())
+ }
+ }
+ }
+ case *ast.ObjectItem:
+ if t.LeadComment != nil {
+ for _, comment := range t.LeadComment.List {
+ if _, ok := standaloneComments[comment.Pos()]; ok {
+ delete(standaloneComments, comment.Pos())
+ }
+ }
+ }
+
+ if t.LineComment != nil {
+ for _, comment := range t.LineComment.List {
+ if _, ok := standaloneComments[comment.Pos()]; ok {
+ delete(standaloneComments, comment.Pos())
+ }
+ }
+ }
+ }
+
+ return nn, true
+ })
+
+ for _, c := range standaloneComments {
+ p.standaloneComments = append(p.standaloneComments, c)
+ }
+
+ sort.Sort(ByPosition(p.standaloneComments))
+}
+
+// output prints creates b printable HCL output and returns it.
+func (p *printer) output(n interface{}) []byte {
+ var buf bytes.Buffer
+
+ switch t := n.(type) {
+ case *ast.File:
+ // File doesn't trace so we add the tracing here
+ defer un(trace(p, "File"))
+ return p.output(t.Node)
+ case *ast.ObjectList:
+ defer un(trace(p, "ObjectList"))
+
+ var index int
+ for {
+ // Determine the location of the next actual non-comment
+ // item. If we're at the end, the next item is at "infinity"
+ var nextItem token.Pos
+ if index != len(t.Items) {
+ nextItem = t.Items[index].Pos()
+ } else {
+ nextItem = token.Pos{Offset: infinity, Line: infinity}
+ }
+
+ // Go through the standalone comments in the file and print out
+ // the comments that we should be for this object item.
+ for _, c := range p.standaloneComments {
+ // Go through all the comments in the group. The group
+ // should be printed together, not separated by double newlines.
+ printed := false
+ newlinePrinted := false
+ for _, comment := range c.List {
+ // We only care about comments after the previous item
+ // we've printed so that comments are printed in the
+ // correct locations (between two objects for example).
+ // And before the next item.
+ if comment.Pos().After(p.prev) && comment.Pos().Before(nextItem) {
+ // if we hit the end add newlines so we can print the comment
+ // we don't do this if prev is invalid which means the
+ // beginning of the file since the first comment should
+ // be at the first line.
+ if !newlinePrinted && p.prev.IsValid() && index == len(t.Items) {
+ buf.Write([]byte{newline, newline})
+ newlinePrinted = true
+ }
+
+ // Write the actual comment.
+ buf.WriteString(comment.Text)
+ buf.WriteByte(newline)
+
+ // Set printed to true to note that we printed something
+ printed = true
+ }
+ }
+
+ // If we're not at the last item, write a new line so
+ // that there is a newline separating this comment from
+ // the next object.
+ if printed && index != len(t.Items) {
+ buf.WriteByte(newline)
+ }
+ }
+
+ if index == len(t.Items) {
+ break
+ }
+
+ buf.Write(p.output(t.Items[index]))
+ if index != len(t.Items)-1 {
+ // Always write a newline to separate us from the next item
+ buf.WriteByte(newline)
+
+ // Need to determine if we're going to separate the next item
+ // with a blank line. The logic here is simple, though there
+ // are a few conditions:
+ //
+ // 1. The next object is more than one line away anyways,
+ // so we need an empty line.
+ //
+ // 2. The next object is not a "single line" object, so
+ // we need an empty line.
+ //
+ // 3. This current object is not a single line object,
+ // so we need an empty line.
+ current := t.Items[index]
+ next := t.Items[index+1]
+ if next.Pos().Line != t.Items[index].Pos().Line+1 ||
+ !p.isSingleLineObject(next) ||
+ !p.isSingleLineObject(current) {
+ buf.WriteByte(newline)
+ }
+ }
+ index++
+ }
+ case *ast.ObjectKey:
+ buf.WriteString(t.Token.Text)
+ case *ast.ObjectItem:
+ p.prev = t.Pos()
+ buf.Write(p.objectItem(t))
+ case *ast.LiteralType:
+ buf.Write(p.literalType(t))
+ case *ast.ListType:
+ buf.Write(p.list(t))
+ case *ast.ObjectType:
+ buf.Write(p.objectType(t))
+ default:
+ fmt.Printf(" unknown type: %T\n", n)
+ }
+
+ return buf.Bytes()
+}
+
+func (p *printer) literalType(lit *ast.LiteralType) []byte {
+ result := []byte(lit.Token.Text)
+ switch lit.Token.Type {
+ case token.HEREDOC:
+ // Clear the trailing newline from heredocs
+ if result[len(result)-1] == '\n' {
+ result = result[:len(result)-1]
+ }
+
+ // Poison lines 2+ so that we don't indent them
+ result = p.heredocIndent(result)
+ case token.STRING:
+ // If this is a multiline string, poison lines 2+ so we don't
+ // indent them.
+ if bytes.IndexRune(result, '\n') >= 0 {
+ result = p.heredocIndent(result)
+ }
+ }
+
+ return result
+}
+
+// objectItem returns the printable HCL form of an object item. An object type
+// starts with one/multiple keys and has a value. The value might be of any
+// type.
+func (p *printer) objectItem(o *ast.ObjectItem) []byte {
+ defer un(trace(p, fmt.Sprintf("ObjectItem: %s", o.Keys[0].Token.Text)))
+ var buf bytes.Buffer
+
+ if o.LeadComment != nil {
+ for _, comment := range o.LeadComment.List {
+ buf.WriteString(comment.Text)
+ buf.WriteByte(newline)
+ }
+ }
+
+ for i, k := range o.Keys {
+ buf.WriteString(k.Token.Text)
+ buf.WriteByte(blank)
+
+ // reach end of key
+ if o.Assign.IsValid() && i == len(o.Keys)-1 && len(o.Keys) == 1 {
+ buf.WriteString("=")
+ buf.WriteByte(blank)
+ }
+ }
+
+ buf.Write(p.output(o.Val))
+
+ if o.Val.Pos().Line == o.Keys[0].Pos().Line && o.LineComment != nil {
+ buf.WriteByte(blank)
+ for _, comment := range o.LineComment.List {
+ buf.WriteString(comment.Text)
+ }
+ }
+
+ return buf.Bytes()
+}
+
+// objectType returns the printable HCL form of an object type. An object type
+// begins with a brace and ends with a brace.
+func (p *printer) objectType(o *ast.ObjectType) []byte {
+ defer un(trace(p, "ObjectType"))
+ var buf bytes.Buffer
+ buf.WriteString("{")
+
+ var index int
+ var nextItem token.Pos
+ var commented, newlinePrinted bool
+ for {
+ // Determine the location of the next actual non-comment
+ // item. If we're at the end, the next item is the closing brace
+ if index != len(o.List.Items) {
+ nextItem = o.List.Items[index].Pos()
+ } else {
+ nextItem = o.Rbrace
+ }
+
+ // Go through the standalone comments in the file and print out
+ // the comments that we should be for this object item.
+ for _, c := range p.standaloneComments {
+ printed := false
+ var lastCommentPos token.Pos
+ for _, comment := range c.List {
+ // We only care about comments after the previous item
+ // we've printed so that comments are printed in the
+ // correct locations (between two objects for example).
+ // And before the next item.
+ if comment.Pos().After(p.prev) && comment.Pos().Before(nextItem) {
+ // If there are standalone comments and the initial newline has not
+ // been printed yet, do it now.
+ if !newlinePrinted {
+ newlinePrinted = true
+ buf.WriteByte(newline)
+ }
+
+ // add newline if it's between other printed nodes
+ if index > 0 {
+ commented = true
+ buf.WriteByte(newline)
+ }
+
+ // Store this position
+ lastCommentPos = comment.Pos()
+
+ // output the comment itself
+ buf.Write(p.indent(p.heredocIndent([]byte(comment.Text))))
+
+ // Set printed to true to note that we printed something
+ printed = true
+
+ /*
+ if index != len(o.List.Items) {
+ buf.WriteByte(newline) // do not print on the end
+ }
+ */
+ }
+ }
+
+ // Stuff to do if we had comments
+ if printed {
+ // Always write a newline
+ buf.WriteByte(newline)
+
+ // If there is another item in the object and our comment
+ // didn't hug it directly, then make sure there is a blank
+ // line separating them.
+ if nextItem != o.Rbrace && nextItem.Line != lastCommentPos.Line+1 {
+ buf.WriteByte(newline)
+ }
+ }
+ }
+
+ if index == len(o.List.Items) {
+ p.prev = o.Rbrace
+ break
+ }
+
+ // At this point we are sure that it's not a totally empty block: print
+ // the initial newline if it hasn't been printed yet by the previous
+ // block about standalone comments.
+ if !newlinePrinted {
+ buf.WriteByte(newline)
+ newlinePrinted = true
+ }
+
+ // check if we have adjacent one liner items. If yes we'll going to align
+ // the comments.
+ var aligned []*ast.ObjectItem
+ for _, item := range o.List.Items[index:] {
+ // we don't group one line lists
+ if len(o.List.Items) == 1 {
+ break
+ }
+
+ // one means a oneliner with out any lead comment
+ // two means a oneliner with lead comment
+ // anything else might be something else
+ cur := lines(string(p.objectItem(item)))
+ if cur > 2 {
+ break
+ }
+
+ curPos := item.Pos()
+
+ nextPos := token.Pos{}
+ if index != len(o.List.Items)-1 {
+ nextPos = o.List.Items[index+1].Pos()
+ }
+
+ prevPos := token.Pos{}
+ if index != 0 {
+ prevPos = o.List.Items[index-1].Pos()
+ }
+
+ // fmt.Println("DEBUG ----------------")
+ // fmt.Printf("prev = %+v prevPos: %s\n", prev, prevPos)
+ // fmt.Printf("cur = %+v curPos: %s\n", cur, curPos)
+ // fmt.Printf("next = %+v nextPos: %s\n", next, nextPos)
+
+ if curPos.Line+1 == nextPos.Line {
+ aligned = append(aligned, item)
+ index++
+ continue
+ }
+
+ if curPos.Line-1 == prevPos.Line {
+ aligned = append(aligned, item)
+ index++
+
+ // finish if we have a new line or comment next. This happens
+ // if the next item is not adjacent
+ if curPos.Line+1 != nextPos.Line {
+ break
+ }
+ continue
+ }
+
+ break
+ }
+
+ // put newlines if the items are between other non aligned items.
+ // newlines are also added if there is a standalone comment already, so
+ // check it too
+ if !commented && index != len(aligned) {
+ buf.WriteByte(newline)
+ }
+
+ if len(aligned) >= 1 {
+ p.prev = aligned[len(aligned)-1].Pos()
+
+ items := p.alignedItems(aligned)
+ buf.Write(p.indent(items))
+ } else {
+ p.prev = o.List.Items[index].Pos()
+
+ buf.Write(p.indent(p.objectItem(o.List.Items[index])))
+ index++
+ }
+
+ buf.WriteByte(newline)
+ }
+
+ buf.WriteString("}")
+ return buf.Bytes()
+}
+
+func (p *printer) alignedItems(items []*ast.ObjectItem) []byte {
+ var buf bytes.Buffer
+
+ // find the longest key and value length, needed for alignment
+ var longestKeyLen int // longest key length
+ var longestValLen int // longest value length
+ for _, item := range items {
+ key := len(item.Keys[0].Token.Text)
+ val := len(p.output(item.Val))
+
+ if key > longestKeyLen {
+ longestKeyLen = key
+ }
+
+ if val > longestValLen {
+ longestValLen = val
+ }
+ }
+
+ for i, item := range items {
+ if item.LeadComment != nil {
+ for _, comment := range item.LeadComment.List {
+ buf.WriteString(comment.Text)
+ buf.WriteByte(newline)
+ }
+ }
+
+ for i, k := range item.Keys {
+ keyLen := len(k.Token.Text)
+ buf.WriteString(k.Token.Text)
+ for i := 0; i < longestKeyLen-keyLen+1; i++ {
+ buf.WriteByte(blank)
+ }
+
+ // reach end of key
+ if i == len(item.Keys)-1 && len(item.Keys) == 1 {
+ buf.WriteString("=")
+ buf.WriteByte(blank)
+ }
+ }
+
+ val := p.output(item.Val)
+ valLen := len(val)
+ buf.Write(val)
+
+ if item.Val.Pos().Line == item.Keys[0].Pos().Line && item.LineComment != nil {
+ for i := 0; i < longestValLen-valLen+1; i++ {
+ buf.WriteByte(blank)
+ }
+
+ for _, comment := range item.LineComment.List {
+ buf.WriteString(comment.Text)
+ }
+ }
+
+ // do not print for the last item
+ if i != len(items)-1 {
+ buf.WriteByte(newline)
+ }
+ }
+
+ return buf.Bytes()
+}
+
+// list returns the printable HCL form of an list type.
+func (p *printer) list(l *ast.ListType) []byte {
+ var buf bytes.Buffer
+ buf.WriteString("[")
+
+ var longestLine int
+ for _, item := range l.List {
+ // for now we assume that the list only contains literal types
+ if lit, ok := item.(*ast.LiteralType); ok {
+ lineLen := len(lit.Token.Text)
+ if lineLen > longestLine {
+ longestLine = lineLen
+ }
+ }
+ }
+
+ insertSpaceBeforeItem := false
+ lastHadLeadComment := false
+ for i, item := range l.List {
+ // Keep track of whether this item is a heredoc since that has
+ // unique behavior.
+ heredoc := false
+ if lit, ok := item.(*ast.LiteralType); ok && lit.Token.Type == token.HEREDOC {
+ heredoc = true
+ }
+
+ if item.Pos().Line != l.Lbrack.Line {
+ // multiline list, add newline before we add each item
+ buf.WriteByte(newline)
+ insertSpaceBeforeItem = false
+
+ // If we have a lead comment, then we want to write that first
+ leadComment := false
+ if lit, ok := item.(*ast.LiteralType); ok && lit.LeadComment != nil {
+ leadComment = true
+
+ // If this isn't the first item and the previous element
+ // didn't have a lead comment, then we need to add an extra
+ // newline to properly space things out. If it did have a
+ // lead comment previously then this would be done
+ // automatically.
+ if i > 0 && !lastHadLeadComment {
+ buf.WriteByte(newline)
+ }
+
+ for _, comment := range lit.LeadComment.List {
+ buf.Write(p.indent([]byte(comment.Text)))
+ buf.WriteByte(newline)
+ }
+ }
+
+ // also indent each line
+ val := p.output(item)
+ curLen := len(val)
+ buf.Write(p.indent(val))
+
+ // if this item is a heredoc, then we output the comma on
+ // the next line. This is the only case this happens.
+ comma := []byte{','}
+ if heredoc {
+ buf.WriteByte(newline)
+ comma = p.indent(comma)
+ }
+
+ buf.Write(comma)
+
+ if lit, ok := item.(*ast.LiteralType); ok && lit.LineComment != nil {
+ // if the next item doesn't have any comments, do not align
+ buf.WriteByte(blank) // align one space
+ for i := 0; i < longestLine-curLen; i++ {
+ buf.WriteByte(blank)
+ }
+
+ for _, comment := range lit.LineComment.List {
+ buf.WriteString(comment.Text)
+ }
+ }
+
+ lastItem := i == len(l.List)-1
+ if lastItem {
+ buf.WriteByte(newline)
+ }
+
+ if leadComment && !lastItem {
+ buf.WriteByte(newline)
+ }
+
+ lastHadLeadComment = leadComment
+ } else {
+ if insertSpaceBeforeItem {
+ buf.WriteByte(blank)
+ insertSpaceBeforeItem = false
+ }
+
+ // Output the item itself
+ // also indent each line
+ val := p.output(item)
+ curLen := len(val)
+ buf.Write(val)
+
+ // If this is a heredoc item we always have to output a newline
+ // so that it parses properly.
+ if heredoc {
+ buf.WriteByte(newline)
+ }
+
+ // If this isn't the last element, write a comma.
+ if i != len(l.List)-1 {
+ buf.WriteString(",")
+ insertSpaceBeforeItem = true
+ }
+
+ if lit, ok := item.(*ast.LiteralType); ok && lit.LineComment != nil {
+ // if the next item doesn't have any comments, do not align
+ buf.WriteByte(blank) // align one space
+ for i := 0; i < longestLine-curLen; i++ {
+ buf.WriteByte(blank)
+ }
+
+ for _, comment := range lit.LineComment.List {
+ buf.WriteString(comment.Text)
+ }
+ }
+ }
+
+ }
+
+ buf.WriteString("]")
+ return buf.Bytes()
+}
+
+// indent indents the lines of the given buffer for each non-empty line
+func (p *printer) indent(buf []byte) []byte {
+ var prefix []byte
+ if p.cfg.SpacesWidth != 0 {
+ for i := 0; i < p.cfg.SpacesWidth; i++ {
+ prefix = append(prefix, blank)
+ }
+ } else {
+ prefix = []byte{tab}
+ }
+
+ var res []byte
+ bol := true
+ for _, c := range buf {
+ if bol && c != '\n' {
+ res = append(res, prefix...)
+ }
+
+ res = append(res, c)
+ bol = c == '\n'
+ }
+ return res
+}
+
+// unindent removes all the indentation from the tombstoned lines
+func (p *printer) unindent(buf []byte) []byte {
+ var res []byte
+ for i := 0; i < len(buf); i++ {
+ skip := len(buf)-i <= len(unindent)
+ if !skip {
+ skip = !bytes.Equal(unindent, buf[i:i+len(unindent)])
+ }
+ if skip {
+ res = append(res, buf[i])
+ continue
+ }
+
+ // We have a marker. we have to backtrace here and clean out
+ // any whitespace ahead of our tombstone up to a \n
+ for j := len(res) - 1; j >= 0; j-- {
+ if res[j] == '\n' {
+ break
+ }
+
+ res = res[:j]
+ }
+
+ // Skip the entire unindent marker
+ i += len(unindent) - 1
+ }
+
+ return res
+}
+
+// heredocIndent marks all the 2nd and further lines as unindentable
+func (p *printer) heredocIndent(buf []byte) []byte {
+ var res []byte
+ bol := false
+ for _, c := range buf {
+ if bol && c != '\n' {
+ res = append(res, unindent...)
+ }
+ res = append(res, c)
+ bol = c == '\n'
+ }
+ return res
+}
+
+// isSingleLineObject tells whether the given object item is a single
+// line object such as "obj {}".
+//
+// A single line object:
+//
+// * has no lead comments (hence multi-line)
+// * has no assignment
+// * has no values in the stanza (within {})
+//
+func (p *printer) isSingleLineObject(val *ast.ObjectItem) bool {
+ // If there is a lead comment, can't be one line
+ if val.LeadComment != nil {
+ return false
+ }
+
+ // If there is assignment, we always break by line
+ if val.Assign.IsValid() {
+ return false
+ }
+
+ // If it isn't an object type, then its not a single line object
+ ot, ok := val.Val.(*ast.ObjectType)
+ if !ok {
+ return false
+ }
+
+ // If the object has no items, it is single line!
+ return len(ot.List.Items) == 0
+}
+
+func lines(txt string) int {
+ endline := 1
+ for i := 0; i < len(txt); i++ {
+ if txt[i] == '\n' {
+ endline++
+ }
+ }
+ return endline
+}
+
+// ----------------------------------------------------------------------------
+// Tracing support
+
+func (p *printer) printTrace(a ...interface{}) {
+ if !p.enableTrace {
+ return
+ }
+
+ const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
+ const n = len(dots)
+ i := 2 * p.indentTrace
+ for i > n {
+ fmt.Print(dots)
+ i -= n
+ }
+ // i <= n
+ fmt.Print(dots[0:i])
+ fmt.Println(a...)
+}
+
+func trace(p *printer, msg string) *printer {
+ p.printTrace(msg, "(")
+ p.indentTrace++
+ return p
+}
+
+// Usage pattern: defer un(trace(p, "..."))
+func un(p *printer) {
+ p.indentTrace--
+ p.printTrace(")")
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/printer.go b/vendor/github.com/hashicorp/hcl/hcl/printer/printer.go
new file mode 100644
index 000000000..a296fc851
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/printer.go
@@ -0,0 +1,67 @@
+// Package printer implements printing of AST nodes to HCL format.
+package printer
+
+import (
+ "bytes"
+ "io"
+ "text/tabwriter"
+
+ "github.com/hashicorp/hcl/hcl/ast"
+ "github.com/hashicorp/hcl/hcl/parser"
+)
+
+var DefaultConfig = Config{
+ SpacesWidth: 2,
+}
+
+// A Config node controls the output of Fprint.
+type Config struct {
+ SpacesWidth int // if set, it will use spaces instead of tabs for alignment
+}
+
+func (c *Config) Fprint(output io.Writer, node ast.Node) error {
+ p := &printer{
+ cfg: *c,
+ comments: make([]*ast.CommentGroup, 0),
+ standaloneComments: make([]*ast.CommentGroup, 0),
+ // enableTrace: true,
+ }
+
+ p.collectComments(node)
+
+ if _, err := output.Write(p.unindent(p.output(node))); err != nil {
+ return err
+ }
+
+ // flush tabwriter, if any
+ var err error
+ if tw, _ := output.(*tabwriter.Writer); tw != nil {
+ err = tw.Flush()
+ }
+
+ return err
+}
+
+// Fprint "pretty-prints" an HCL node to output
+// It calls Config.Fprint with default settings.
+func Fprint(output io.Writer, node ast.Node) error {
+ return DefaultConfig.Fprint(output, node)
+}
+
+// Format formats src HCL and returns the result.
+func Format(src []byte) ([]byte, error) {
+ node, err := parser.Parse(src)
+ if err != nil {
+ return nil, err
+ }
+
+ var buf bytes.Buffer
+ if err := DefaultConfig.Fprint(&buf, node); err != nil {
+ return nil, err
+ }
+
+ // Add trailing newline to result
+ buf.WriteString("\n")
+
+ return buf.Bytes(), nil
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/printer_test.go b/vendor/github.com/hashicorp/hcl/hcl/printer/printer_test.go
new file mode 100644
index 000000000..01ea3b2de
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/printer_test.go
@@ -0,0 +1,153 @@
+// +build !windows
+// TODO(jen20): These need fixing on Windows but printer is not used right now
+// and red CI is making it harder to process other bugs, so ignore until
+// we get around to fixing them.package printer
+
+package printer
+
+import (
+ "bytes"
+ "errors"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "path/filepath"
+ "testing"
+
+ "github.com/hashicorp/hcl/hcl/parser"
+)
+
+var update = flag.Bool("update", false, "update golden files")
+
+const (
+ dataDir = "testdata"
+)
+
+type entry struct {
+ source, golden string
+}
+
+// Use go test -update to create/update the respective golden files.
+var data = []entry{
+ {"complexhcl.input", "complexhcl.golden"},
+ {"list.input", "list.golden"},
+ {"list_comment.input", "list_comment.golden"},
+ {"comment.input", "comment.golden"},
+ {"comment_aligned.input", "comment_aligned.golden"},
+ {"comment_array.input", "comment_array.golden"},
+ {"comment_end_file.input", "comment_end_file.golden"},
+ {"comment_multiline_indent.input", "comment_multiline_indent.golden"},
+ {"comment_multiline_no_stanza.input", "comment_multiline_no_stanza.golden"},
+ {"comment_multiline_stanza.input", "comment_multiline_stanza.golden"},
+ {"comment_newline.input", "comment_newline.golden"},
+ {"comment_object_multi.input", "comment_object_multi.golden"},
+ {"comment_standalone.input", "comment_standalone.golden"},
+ {"empty_block.input", "empty_block.golden"},
+ {"list_of_objects.input", "list_of_objects.golden"},
+ {"multiline_string.input", "multiline_string.golden"},
+ {"object_singleline.input", "object_singleline.golden"},
+ {"object_with_heredoc.input", "object_with_heredoc.golden"},
+}
+
+func TestFiles(t *testing.T) {
+ for _, e := range data {
+ source := filepath.Join(dataDir, e.source)
+ golden := filepath.Join(dataDir, e.golden)
+ t.Run(e.source, func(t *testing.T) {
+ check(t, source, golden)
+ })
+ }
+}
+
+func check(t *testing.T, source, golden string) {
+ src, err := ioutil.ReadFile(source)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ res, err := format(src)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ // update golden files if necessary
+ if *update {
+ if err := ioutil.WriteFile(golden, res, 0644); err != nil {
+ t.Error(err)
+ }
+ return
+ }
+
+ // get golden
+ gld, err := ioutil.ReadFile(golden)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ // formatted source and golden must be the same
+ if err := diff(source, golden, res, gld); err != nil {
+ t.Error(err)
+ return
+ }
+}
+
+// diff compares a and b.
+func diff(aname, bname string, a, b []byte) error {
+ var buf bytes.Buffer // holding long error message
+
+ // compare lengths
+ if len(a) != len(b) {
+ fmt.Fprintf(&buf, "\nlength changed: len(%s) = %d, len(%s) = %d", aname, len(a), bname, len(b))
+ }
+
+ // compare contents
+ line := 1
+ offs := 1
+ for i := 0; i < len(a) && i < len(b); i++ {
+ ch := a[i]
+ if ch != b[i] {
+ fmt.Fprintf(&buf, "\n%s:%d:%d: %s", aname, line, i-offs+1, lineAt(a, offs))
+ fmt.Fprintf(&buf, "\n%s:%d:%d: %s", bname, line, i-offs+1, lineAt(b, offs))
+ fmt.Fprintf(&buf, "\n\n")
+ break
+ }
+ if ch == '\n' {
+ line++
+ offs = i + 1
+ }
+ }
+
+ if buf.Len() > 0 {
+ return errors.New(buf.String())
+ }
+ return nil
+}
+
+// format parses src, prints the corresponding AST, verifies the resulting
+// src is syntactically correct, and returns the resulting src or an error
+// if any.
+func format(src []byte) ([]byte, error) {
+ formatted, err := Format(src)
+ if err != nil {
+ return nil, err
+ }
+
+ // make sure formatted output is syntactically correct
+ if _, err := parser.Parse(formatted); err != nil {
+ return nil, fmt.Errorf("parse: %s\n%s", err, formatted)
+ }
+
+ return formatted, nil
+}
+
+// lineAt returns the line in text starting at offset offs.
+func lineAt(text []byte, offs int) []byte {
+ i := offs
+ for i < len(text) && text[i] != '\n' {
+ i++
+ }
+ return text[offs:i]
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.golden
new file mode 100644
index 000000000..9d4b072a0
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.golden
@@ -0,0 +1,36 @@
+// A standalone comment is a comment which is not attached to any kind of node
+
+// This comes from Terraform, as a test
+variable "foo" {
+ # Standalone comment should be still here
+
+ default = "bar"
+ description = "bar" # yooo
+}
+
+/* This is a multi line standalone
+comment*/
+
+// fatih arslan
+/* This is a developer test
+account and a multine comment */
+developer = ["fatih", "arslan"] // fatih arslan
+
+# One line here
+numbers = [1, 2] // another line here
+
+# Another comment
+variable = {
+ description = "bar" # another yooo
+
+ foo {
+ # Nested standalone
+
+ bar = "fatih"
+ }
+}
+
+// lead comment
+foo {
+ bar = "fatih" // line comment 2
+} // line comment 3
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.input
new file mode 100644
index 000000000..57c37ac1d
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment.input
@@ -0,0 +1,37 @@
+// A standalone comment is a comment which is not attached to any kind of node
+
+ // This comes from Terraform, as a test
+variable "foo" {
+ # Standalone comment should be still here
+
+ default = "bar"
+ description = "bar" # yooo
+}
+
+/* This is a multi line standalone
+comment*/
+
+
+// fatih arslan
+/* This is a developer test
+account and a multine comment */
+developer = [ "fatih", "arslan"] // fatih arslan
+
+# One line here
+numbers = [1,2] // another line here
+
+ # Another comment
+variable = {
+ description = "bar" # another yooo
+ foo {
+ # Nested standalone
+
+ bar = "fatih"
+ }
+}
+
+ // lead comment
+foo {
+ bar = "fatih" // line comment 2
+} // line comment 3
+
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.golden
new file mode 100644
index 000000000..6ff21504c
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.golden
@@ -0,0 +1,32 @@
+aligned {
+ # We have some aligned items below
+ foo = "fatih" # yoo1
+ default = "bar" # yoo2
+ bar = "bar and foo" # yoo3
+
+ default = {
+ bar = "example"
+ }
+
+ #deneme arslan
+ fatih = ["fatih"] # yoo4
+
+ #fatih arslan
+ fatiharslan = ["arslan"] // yoo5
+
+ default = {
+ bar = "example"
+ }
+
+ security_groups = [
+ "foo", # kenya 1
+ "${aws_security_group.firewall.foo}", # kenya 2
+ ]
+
+ security_groups2 = [
+ "foo", # kenya 1
+ "bar", # kenya 1.5
+ "${aws_security_group.firewall.foo}", # kenya 2
+ "foobar", # kenya 3
+ ]
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.input
new file mode 100644
index 000000000..bd43ab1ad
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_aligned.input
@@ -0,0 +1,28 @@
+aligned {
+# We have some aligned items below
+ foo = "fatih" # yoo1
+ default = "bar" # yoo2
+ bar = "bar and foo" # yoo3
+ default = {
+ bar = "example"
+ }
+ #deneme arslan
+ fatih = ["fatih"] # yoo4
+ #fatih arslan
+ fatiharslan = ["arslan"] // yoo5
+ default = {
+ bar = "example"
+ }
+
+security_groups = [
+ "foo", # kenya 1
+ "${aws_security_group.firewall.foo}", # kenya 2
+]
+
+security_groups2 = [
+ "foo", # kenya 1
+ "bar", # kenya 1.5
+ "${aws_security_group.firewall.foo}", # kenya 2
+ "foobar", # kenya 3
+]
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_array.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_array.golden
new file mode 100644
index 000000000..e778eafa3
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_array.golden
@@ -0,0 +1,13 @@
+banana = [
+ # I really want to comment this item in the array.
+ "a",
+
+ # This as well
+ "b",
+
+ "c", # And C
+ "d",
+
+ # And another
+ "e",
+]
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_array.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_array.input
new file mode 100644
index 000000000..e778eafa3
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_array.input
@@ -0,0 +1,13 @@
+banana = [
+ # I really want to comment this item in the array.
+ "a",
+
+ # This as well
+ "b",
+
+ "c", # And C
+ "d",
+
+ # And another
+ "e",
+]
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_end_file.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_end_file.golden
new file mode 100644
index 000000000..dbeae36a8
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_end_file.golden
@@ -0,0 +1,6 @@
+resource "blah" "blah" {}
+
+//
+//
+//
+
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_end_file.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_end_file.input
new file mode 100644
index 000000000..68c4c282e
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_end_file.input
@@ -0,0 +1,5 @@
+resource "blah" "blah" {}
+
+//
+//
+//
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_indent.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_indent.golden
new file mode 100644
index 000000000..74c4ccd89
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_indent.golden
@@ -0,0 +1,12 @@
+resource "provider" "resource" {
+ /*
+ SPACE_SENSITIVE_CODE = <<EOF
+yaml code:
+ foo: ""
+ bar: ""
+EOF
+ */
+ /*
+ OTHER
+ */
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_indent.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_indent.input
new file mode 100644
index 000000000..b07ac4d3c
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_indent.input
@@ -0,0 +1,13 @@
+resource "provider" "resource" {
+ /*
+ SPACE_SENSITIVE_CODE = <<EOF
+yaml code:
+ foo: ""
+ bar: ""
+EOF
+ */
+
+ /*
+ OTHER
+ */
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_no_stanza.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_no_stanza.golden
new file mode 100644
index 000000000..7ad7ca296
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_no_stanza.golden
@@ -0,0 +1,7 @@
+# This is a multiline comment
+# That has values like this:
+#
+# ami-abcd1234
+#
+# Do not delete this comment
+
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_no_stanza.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_no_stanza.input
new file mode 100644
index 000000000..8b818e91d
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_no_stanza.input
@@ -0,0 +1,6 @@
+# This is a multiline comment
+# That has values like this:
+#
+# ami-abcd1234
+#
+# Do not delete this comment
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_stanza.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_stanza.golden
new file mode 100644
index 000000000..e9db4f2ae
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_stanza.golden
@@ -0,0 +1,10 @@
+# This is a multiline comment
+# That has values like this:
+#
+# ami-abcd1234
+#
+# Do not delete this comment
+
+resource "aws_instance" "web" {
+ ami_id = "ami-abcd1234"
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_stanza.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_stanza.input
new file mode 100644
index 000000000..6a8b90230
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_multiline_stanza.input
@@ -0,0 +1,10 @@
+# This is a multiline comment
+# That has values like this:
+#
+# ami-abcd1234
+#
+# Do not delete this comment
+
+resource "aws_instance" "web" {
+ami_id = "ami-abcd1234"
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_newline.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_newline.golden
new file mode 100644
index 000000000..2162c8845
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_newline.golden
@@ -0,0 +1,3 @@
+# Hello
+# World
+
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_newline.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_newline.input
new file mode 100644
index 000000000..aa56a9880
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_newline.input
@@ -0,0 +1,2 @@
+# Hello
+# World
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_object_multi.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_object_multi.golden
new file mode 100644
index 000000000..4c0f0004a
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_object_multi.golden
@@ -0,0 +1,9 @@
+variable "environment" {
+ default = {}
+
+ # default {
+ # "region" = "us-west-2"
+ # "sg" = "playground"
+ # "env" = "prod"
+ # }
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_object_multi.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_object_multi.input
new file mode 100644
index 000000000..4c0f0004a
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_object_multi.input
@@ -0,0 +1,9 @@
+variable "environment" {
+ default = {}
+
+ # default {
+ # "region" = "us-west-2"
+ # "sg" = "playground"
+ # "env" = "prod"
+ # }
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.golden
new file mode 100644
index 000000000..3236d9e69
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.golden
@@ -0,0 +1,17 @@
+// A standalone comment
+
+aligned {
+ # Standalone 1
+
+ a = "bar" # yoo1
+ default = "bar" # yoo2
+
+ # Standalone 2
+}
+
+# Standalone 3
+
+numbers = [1, 2] // another line here
+
+# Standalone 4
+
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.input
new file mode 100644
index 000000000..4436cb16c
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/comment_standalone.input
@@ -0,0 +1,16 @@
+// A standalone comment
+
+aligned {
+ # Standalone 1
+
+ a = "bar" # yoo1
+ default = "bar" # yoo2
+
+ # Standalone 2
+}
+
+ # Standalone 3
+
+numbers = [1,2] // another line here
+
+ # Standalone 4
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.golden
new file mode 100644
index 000000000..198c32d28
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.golden
@@ -0,0 +1,54 @@
+variable "foo" {
+ default = "bar"
+ description = "bar"
+}
+
+developer = ["fatih", "arslan"]
+
+provider "aws" {
+ access_key = "foo"
+ secret_key = "bar"
+}
+
+provider "do" {
+ api_key = "${var.foo}"
+}
+
+resource "aws_security_group" "firewall" {
+ count = 5
+}
+
+resource aws_instance "web" {
+ ami = "${var.foo}"
+
+ security_groups = [
+ "foo",
+ "${aws_security_group.firewall.foo}",
+ ]
+
+ network_interface {
+ device_index = 0
+ description = "Main network interface"
+ }
+
+ network_interface = {
+ device_index = 1
+
+ description = <<EOF
+ANOTHER NETWORK INTERFACE
+EOF
+ }
+}
+
+resource "aws_instance" "db" {
+ security_groups = "${aws_security_group.firewall.*.id}"
+ VPC = "foo"
+
+ depends_on = ["aws_instance.web"]
+}
+
+output "web_ip" {
+ value = <<EOF
+TUBES
+EOF
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.input
new file mode 100644
index 000000000..712341840
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/complexhcl.input
@@ -0,0 +1,53 @@
+variable "foo" {
+ default = "bar"
+ description = "bar"
+}
+
+developer = [ "fatih", "arslan"]
+
+provider "aws" {
+ access_key ="foo"
+ secret_key = "bar"
+}
+
+ provider "do" {
+ api_key = "${var.foo}"
+}
+
+resource "aws_security_group" "firewall" {
+ count = 5
+ }
+
+ resource aws_instance "web" {
+ ami = "${var.foo}"
+ security_groups = [
+ "foo",
+ "${aws_security_group.firewall.foo}"
+ ]
+
+ network_interface {
+ device_index = 0
+ description = "Main network interface"
+ }
+
+ network_interface = {
+ device_index = 1
+ description = <<EOF
+ANOTHER NETWORK INTERFACE
+EOF
+ }
+ }
+
+resource "aws_instance" "db" {
+ security_groups = "${aws_security_group.firewall.*.id}"
+ VPC = "foo"
+
+ depends_on = ["aws_instance.web"]
+}
+
+output "web_ip" {
+
+ value=<<EOF
+TUBES
+EOF
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.golden
new file mode 100644
index 000000000..4ff1cb3e4
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.golden
@@ -0,0 +1,12 @@
+variable "foo" {}
+variable "foo" {}
+
+variable "foo" {
+ # Standalone comment should be still here
+}
+
+foo {}
+
+foo {
+ bar = "mssola"
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.input
new file mode 100644
index 000000000..627bf3e3f
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/empty_block.input
@@ -0,0 +1,14 @@
+variable "foo" {}
+variable "foo" {
+}
+
+variable "foo" {
+ # Standalone comment should be still here
+}
+
+foo {
+}
+
+foo {
+ bar = "mssola"
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.golden
new file mode 100644
index 000000000..14c37ac0f
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.golden
@@ -0,0 +1,43 @@
+foo = ["fatih", "arslan"]
+
+foo = ["bar", "qaz"]
+
+foo = ["zeynep",
+ "arslan",
+]
+
+foo = ["fatih", "zeynep",
+ "arslan",
+]
+
+foo = [
+ "vim-go",
+ "golang",
+ "hcl",
+]
+
+foo = []
+
+foo = [1, 2, 3, 4]
+
+foo = [
+ "kenya",
+ "ethiopia",
+ "columbia",
+]
+
+foo = [
+ <<EOS
+one
+EOS
+ ,
+ <<EOS
+two
+EOS
+ ,
+]
+
+foo = [<<EOS
+one
+EOS
+]
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.input
new file mode 100644
index 000000000..f55a38200
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list.input
@@ -0,0 +1,37 @@
+foo = ["fatih", "arslan" ]
+
+foo = [ "bar", "qaz", ]
+
+foo = [ "zeynep",
+"arslan", ]
+
+foo = ["fatih", "zeynep",
+"arslan", ]
+
+foo = [
+ "vim-go",
+ "golang", "hcl"]
+
+foo = []
+
+foo = [1, 2,3, 4]
+
+foo = [
+ "kenya", "ethiopia",
+ "columbia"]
+
+foo = [
+ <<EOS
+one
+EOS
+,
+ <<EOS
+two
+EOS
+,
+ ]
+
+foo = [<<EOS
+one
+EOS
+ ]
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_comment.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_comment.golden
new file mode 100644
index 000000000..e5753c91a
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_comment.golden
@@ -0,0 +1,7 @@
+foo = [1, # Hello
+ 2,
+]
+
+foo = [1, # Hello
+ 2, # World
+]
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_comment.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_comment.input
new file mode 100644
index 000000000..1d636c88d
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_comment.input
@@ -0,0 +1,6 @@
+foo = [1, # Hello
+2]
+
+foo = [1, # Hello
+2, # World
+]
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_of_objects.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_of_objects.golden
new file mode 100644
index 000000000..401ded6ef
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_of_objects.golden
@@ -0,0 +1,10 @@
+list_of_objects = [
+ {
+ key1 = "value1"
+ key2 = "value2"
+ },
+ {
+ key3 = "value3"
+ key4 = "value4"
+ },
+]
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_of_objects.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_of_objects.input
new file mode 100644
index 000000000..f2adcf015
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/list_of_objects.input
@@ -0,0 +1,10 @@
+list_of_objects = [
+ {
+ key1 = "value1"
+ key2 = "value2"
+ },
+ {
+ key3 = "value3"
+ key4 = "value4"
+ }
+] \ No newline at end of file
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/multiline_string.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/multiline_string.golden
new file mode 100644
index 000000000..3d10c741d
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/multiline_string.golden
@@ -0,0 +1,7 @@
+resource "null_resource" "some_command" {
+ provisioner "local-exec" {
+ command = "${echo '
+some newlines
+and additonal output'}"
+ }
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/multiline_string.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/multiline_string.input
new file mode 100644
index 000000000..3d10c741d
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/multiline_string.input
@@ -0,0 +1,7 @@
+resource "null_resource" "some_command" {
+ provisioner "local-exec" {
+ command = "${echo '
+some newlines
+and additonal output'}"
+ }
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_singleline.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_singleline.golden
new file mode 100644
index 000000000..c3d914702
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_singleline.golden
@@ -0,0 +1,26 @@
+variable "foo" {}
+variable "bar" {}
+variable "baz" {}
+
+variable "qux" {}
+
+variable "foo" {
+ foo = "bar"
+}
+
+variable "foo" {}
+
+# lead comment
+variable "bar" {}
+
+variable "foo" {
+ default = "bar"
+}
+
+variable "bar" {}
+
+# Purposeful newline check below:
+
+variable "foo" {}
+
+variable "purposeful-newline" {}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_singleline.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_singleline.input
new file mode 100644
index 000000000..7b34834a4
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_singleline.input
@@ -0,0 +1,19 @@
+variable "foo" {}
+variable "bar" {}
+variable "baz" {}
+
+variable "qux" {}
+variable "foo" { foo = "bar" }
+
+variable "foo" {}
+# lead comment
+variable "bar" {}
+
+variable "foo" { default = "bar" }
+variable "bar" {}
+
+# Purposeful newline check below:
+
+variable "foo" {}
+
+variable "purposeful-newline" {}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_with_heredoc.golden b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_with_heredoc.golden
new file mode 100644
index 000000000..7e92243f6
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_with_heredoc.golden
@@ -0,0 +1,6 @@
+obj {
+ foo = [<<EOF
+ TEXT!
+EOF
+ ]
+}
diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_with_heredoc.input b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_with_heredoc.input
new file mode 100644
index 000000000..d70a05ac9
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl/hcl/printer/testdata/object_with_heredoc.input
@@ -0,0 +1,6 @@
+obj {
+ foo = [<<EOF
+ TEXT!
+EOF
+ ]
+}