github.com/hashicorp/hcl/v2@v2.20.0/hclsyntax/parser_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package hclsyntax
     5  
     6  import (
     7  	"fmt"
     8  	"testing"
     9  
    10  	"github.com/go-test/deep"
    11  	"github.com/google/go-cmp/cmp"
    12  	"github.com/google/go-cmp/cmp/cmpopts"
    13  	"github.com/hashicorp/hcl/v2"
    14  	"github.com/zclconf/go-cty/cty"
    15  )
    16  
    17  func init() {
    18  	deep.MaxDepth = 999
    19  }
    20  
    21  func TestParseConfig(t *testing.T) {
    22  	tests := []struct {
    23  		input     string
    24  		diagCount int
    25  		want      *Body
    26  	}{
    27  		{
    28  			``,
    29  			0,
    30  			&Body{
    31  				Attributes: Attributes{},
    32  				Blocks:     Blocks{},
    33  				SrcRange: hcl.Range{
    34  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
    35  					End:   hcl.Pos{Line: 1, Column: 1, Byte: 0},
    36  				},
    37  				EndRange: hcl.Range{
    38  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
    39  					End:   hcl.Pos{Line: 1, Column: 1, Byte: 0},
    40  				},
    41  			},
    42  		},
    43  
    44  		{
    45  			"block {}\n",
    46  			0,
    47  			&Body{
    48  				Attributes: Attributes{},
    49  				Blocks: Blocks{
    50  					&Block{
    51  						Type:   "block",
    52  						Labels: nil,
    53  						Body: &Body{
    54  							Attributes: Attributes{},
    55  							Blocks:     Blocks{},
    56  
    57  							SrcRange: hcl.Range{
    58  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
    59  								End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
    60  							},
    61  							EndRange: hcl.Range{
    62  								Start: hcl.Pos{Line: 1, Column: 9, Byte: 8},
    63  								End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
    64  							},
    65  						},
    66  
    67  						TypeRange: hcl.Range{
    68  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
    69  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
    70  						},
    71  						LabelRanges: nil,
    72  						OpenBraceRange: hcl.Range{
    73  							Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
    74  							End:   hcl.Pos{Line: 1, Column: 8, Byte: 7},
    75  						},
    76  						CloseBraceRange: hcl.Range{
    77  							Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
    78  							End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
    79  						},
    80  					},
    81  				},
    82  				SrcRange: hcl.Range{
    83  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
    84  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 9},
    85  				},
    86  				EndRange: hcl.Range{
    87  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 9},
    88  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 9},
    89  				},
    90  			},
    91  		},
    92  		{
    93  			"block {}",
    94  			0,
    95  			&Body{
    96  				Attributes: Attributes{},
    97  				Blocks: Blocks{
    98  					&Block{
    99  						Type:   "block",
   100  						Labels: nil,
   101  						Body: &Body{
   102  							Attributes: Attributes{},
   103  							Blocks:     Blocks{},
   104  
   105  							SrcRange: hcl.Range{
   106  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   107  								End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
   108  							},
   109  							EndRange: hcl.Range{
   110  								Start: hcl.Pos{Line: 1, Column: 9, Byte: 8},
   111  								End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
   112  							},
   113  						},
   114  
   115  						TypeRange: hcl.Range{
   116  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   117  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   118  						},
   119  						LabelRanges: nil,
   120  						OpenBraceRange: hcl.Range{
   121  							Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   122  							End:   hcl.Pos{Line: 1, Column: 8, Byte: 7},
   123  						},
   124  						CloseBraceRange: hcl.Range{
   125  							Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
   126  							End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
   127  						},
   128  					},
   129  				},
   130  				SrcRange: hcl.Range{
   131  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   132  					End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
   133  				},
   134  				EndRange: hcl.Range{
   135  					Start: hcl.Pos{Line: 1, Column: 9, Byte: 8},
   136  					End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
   137  				},
   138  			},
   139  		},
   140  		{
   141  			"block {}block {}\n",
   142  			1, // missing newline after block definition
   143  			&Body{
   144  				Attributes: Attributes{},
   145  				Blocks: Blocks{
   146  					&Block{
   147  						Type:   "block",
   148  						Labels: nil,
   149  						Body: &Body{
   150  							Attributes: Attributes{},
   151  							Blocks:     Blocks{},
   152  
   153  							SrcRange: hcl.Range{
   154  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   155  								End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
   156  							},
   157  							EndRange: hcl.Range{
   158  								Start: hcl.Pos{Line: 1, Column: 9, Byte: 8},
   159  								End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
   160  							},
   161  						},
   162  
   163  						TypeRange: hcl.Range{
   164  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   165  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   166  						},
   167  						LabelRanges: nil,
   168  						OpenBraceRange: hcl.Range{
   169  							Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   170  							End:   hcl.Pos{Line: 1, Column: 8, Byte: 7},
   171  						},
   172  						CloseBraceRange: hcl.Range{
   173  							Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
   174  							End:   hcl.Pos{Line: 1, Column: 9, Byte: 8},
   175  						},
   176  					},
   177  				},
   178  				SrcRange: hcl.Range{
   179  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   180  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 17},
   181  				},
   182  				EndRange: hcl.Range{
   183  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 17},
   184  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 17},
   185  				},
   186  			},
   187  		},
   188  		{
   189  			"block { block {} }\n",
   190  			1, // can't nest another block in the single-line block syntax
   191  			&Body{
   192  				Attributes: Attributes{},
   193  				Blocks: Blocks{
   194  					&Block{
   195  						Type:   "block",
   196  						Labels: nil,
   197  						Body: &Body{
   198  							SrcRange: hcl.Range{
   199  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   200  								End:   hcl.Pos{Line: 2, Column: 1, Byte: 19},
   201  							},
   202  							EndRange: hcl.Range{ // Parser recovery behavior leaves us after this whole construct, on the next line
   203  								Start: hcl.Pos{Line: 2, Column: 1, Byte: 19},
   204  								End:   hcl.Pos{Line: 2, Column: 1, Byte: 19},
   205  							},
   206  						},
   207  
   208  						TypeRange: hcl.Range{
   209  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   210  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   211  						},
   212  						LabelRanges: nil,
   213  						OpenBraceRange: hcl.Range{
   214  							Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   215  							End:   hcl.Pos{Line: 1, Column: 8, Byte: 7},
   216  						},
   217  						CloseBraceRange: hcl.Range{ // Parser recovery behavior leaves us after this whole construct, on the next line
   218  							Start: hcl.Pos{Line: 2, Column: 1, Byte: 19},
   219  							End:   hcl.Pos{Line: 2, Column: 1, Byte: 19},
   220  						},
   221  					},
   222  				},
   223  				SrcRange: hcl.Range{
   224  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   225  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 19},
   226  				},
   227  				EndRange: hcl.Range{
   228  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 19},
   229  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 19},
   230  				},
   231  			},
   232  		},
   233  		{
   234  			"block \"foo\" {}\n",
   235  			0,
   236  			&Body{
   237  				Attributes: Attributes{},
   238  				Blocks: Blocks{
   239  					&Block{
   240  						Type:   "block",
   241  						Labels: []string{"foo"},
   242  						Body: &Body{
   243  							Attributes: Attributes{},
   244  							Blocks:     Blocks{},
   245  
   246  							SrcRange: hcl.Range{
   247  								Start: hcl.Pos{Line: 1, Column: 13, Byte: 12},
   248  								End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   249  							},
   250  							EndRange: hcl.Range{
   251  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
   252  								End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   253  							},
   254  						},
   255  
   256  						TypeRange: hcl.Range{
   257  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   258  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   259  						},
   260  						LabelRanges: []hcl.Range{
   261  							{
   262  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   263  								End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
   264  							},
   265  						},
   266  						OpenBraceRange: hcl.Range{
   267  							Start: hcl.Pos{Line: 1, Column: 13, Byte: 12},
   268  							End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
   269  						},
   270  						CloseBraceRange: hcl.Range{
   271  							Start: hcl.Pos{Line: 1, Column: 14, Byte: 13},
   272  							End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   273  						},
   274  					},
   275  				},
   276  				SrcRange: hcl.Range{
   277  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   278  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 15},
   279  				},
   280  				EndRange: hcl.Range{
   281  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 15},
   282  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 15},
   283  				},
   284  			},
   285  		},
   286  		{
   287  			"block foo {}\n",
   288  			0,
   289  			&Body{
   290  				Attributes: Attributes{},
   291  				Blocks: Blocks{
   292  					&Block{
   293  						Type:   "block",
   294  						Labels: []string{"foo"},
   295  						Body: &Body{
   296  							Attributes: Attributes{},
   297  							Blocks:     Blocks{},
   298  
   299  							SrcRange: hcl.Range{
   300  								Start: hcl.Pos{Line: 1, Column: 11, Byte: 10},
   301  								End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
   302  							},
   303  							EndRange: hcl.Range{
   304  								Start: hcl.Pos{Line: 1, Column: 13, Byte: 12},
   305  								End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
   306  							},
   307  						},
   308  
   309  						TypeRange: hcl.Range{
   310  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   311  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   312  						},
   313  						LabelRanges: []hcl.Range{
   314  							{
   315  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   316  								End:   hcl.Pos{Line: 1, Column: 10, Byte: 9},
   317  							},
   318  						},
   319  						OpenBraceRange: hcl.Range{
   320  							Start: hcl.Pos{Line: 1, Column: 11, Byte: 10},
   321  							End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
   322  						},
   323  						CloseBraceRange: hcl.Range{
   324  							Start: hcl.Pos{Line: 1, Column: 12, Byte: 11},
   325  							End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
   326  						},
   327  					},
   328  				},
   329  				SrcRange: hcl.Range{
   330  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   331  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 13},
   332  				},
   333  				EndRange: hcl.Range{
   334  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 13},
   335  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 13},
   336  				},
   337  			},
   338  		},
   339  		{
   340  			"block \"invalid ${not_allowed_here} foo\" {}\n",
   341  			1, // Invalid string literal; Template sequences are not allowed in this string.
   342  			&Body{
   343  				Attributes: Attributes{},
   344  				Blocks: Blocks{
   345  					&Block{
   346  						Type:   "block",
   347  						Labels: []string{"invalid ${ ... } foo"}, // invalid interpolation gets replaced with a placeholder here
   348  						Body: &Body{
   349  							Attributes: Attributes{},
   350  							Blocks:     Blocks{},
   351  
   352  							SrcRange: hcl.Range{
   353  								Start: hcl.Pos{Line: 1, Column: 41, Byte: 40},
   354  								End:   hcl.Pos{Line: 1, Column: 43, Byte: 42},
   355  							},
   356  							EndRange: hcl.Range{
   357  								Start: hcl.Pos{Line: 1, Column: 43, Byte: 42},
   358  								End:   hcl.Pos{Line: 1, Column: 43, Byte: 42},
   359  							},
   360  						},
   361  
   362  						TypeRange: hcl.Range{
   363  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   364  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   365  						},
   366  						LabelRanges: []hcl.Range{
   367  							{
   368  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   369  								End:   hcl.Pos{Line: 1, Column: 40, Byte: 39},
   370  							},
   371  						},
   372  						OpenBraceRange: hcl.Range{
   373  							Start: hcl.Pos{Line: 1, Column: 41, Byte: 40},
   374  							End:   hcl.Pos{Line: 1, Column: 42, Byte: 41},
   375  						},
   376  						CloseBraceRange: hcl.Range{
   377  							Start: hcl.Pos{Line: 1, Column: 42, Byte: 41},
   378  							End:   hcl.Pos{Line: 1, Column: 43, Byte: 42},
   379  						},
   380  					},
   381  				},
   382  				SrcRange: hcl.Range{
   383  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   384  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 43},
   385  				},
   386  				EndRange: hcl.Range{
   387  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 43},
   388  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 43},
   389  				},
   390  			},
   391  		},
   392  		{
   393  			`
   394  block "invalid" 1.2 {}
   395  block "valid" {}
   396  `,
   397  			1,
   398  			&Body{
   399  				Attributes: Attributes{},
   400  				Blocks: Blocks{
   401  					&Block{
   402  						Type:   "block",
   403  						Labels: []string{"invalid"},
   404  						Body: &Body{
   405  							SrcRange: hcl.Range{
   406  								Start: hcl.Pos{Line: 2, Column: 1, Byte: 1},
   407  								End:   hcl.Pos{Line: 2, Column: 6, Byte: 6},
   408  							},
   409  							EndRange: hcl.Range{
   410  								Start: hcl.Pos{Line: 2, Column: 1, Byte: 1},
   411  								End:   hcl.Pos{Line: 2, Column: 6, Byte: 6},
   412  							},
   413  						},
   414  
   415  						TypeRange: hcl.Range{
   416  							Start: hcl.Pos{Line: 2, Column: 1, Byte: 1},
   417  							End:   hcl.Pos{Line: 2, Column: 6, Byte: 6},
   418  						},
   419  						LabelRanges: []hcl.Range{
   420  							{
   421  								Start: hcl.Pos{Line: 2, Column: 7, Byte: 7},
   422  								End:   hcl.Pos{Line: 2, Column: 16, Byte: 16},
   423  							},
   424  						},
   425  
   426  						// Since we failed parsing before we got to the
   427  						// braces, the type range is used as a placeholder
   428  						// for these.
   429  						OpenBraceRange: hcl.Range{
   430  							Start: hcl.Pos{Line: 2, Column: 1, Byte: 1},
   431  							End:   hcl.Pos{Line: 2, Column: 6, Byte: 6},
   432  						},
   433  						CloseBraceRange: hcl.Range{
   434  							Start: hcl.Pos{Line: 2, Column: 1, Byte: 1},
   435  							End:   hcl.Pos{Line: 2, Column: 6, Byte: 6},
   436  						},
   437  					},
   438  
   439  					// Recovery behavior should allow us to still see this
   440  					// second block, even though the first was invalid.
   441  					&Block{
   442  						Type:   "block",
   443  						Labels: []string{"valid"},
   444  						Body: &Body{
   445  							Attributes: Attributes{},
   446  							Blocks:     Blocks{},
   447  
   448  							SrcRange: hcl.Range{
   449  								Start: hcl.Pos{Line: 3, Column: 15, Byte: 38},
   450  								End:   hcl.Pos{Line: 3, Column: 17, Byte: 40},
   451  							},
   452  							EndRange: hcl.Range{
   453  								Start: hcl.Pos{Line: 3, Column: 17, Byte: 40},
   454  								End:   hcl.Pos{Line: 3, Column: 17, Byte: 40},
   455  							},
   456  						},
   457  
   458  						TypeRange: hcl.Range{
   459  							Start: hcl.Pos{Line: 3, Column: 1, Byte: 24},
   460  							End:   hcl.Pos{Line: 3, Column: 6, Byte: 29},
   461  						},
   462  						LabelRanges: []hcl.Range{
   463  							{
   464  								Start: hcl.Pos{Line: 3, Column: 7, Byte: 30},
   465  								End:   hcl.Pos{Line: 3, Column: 14, Byte: 37},
   466  							},
   467  						},
   468  						OpenBraceRange: hcl.Range{
   469  							Start: hcl.Pos{Line: 3, Column: 15, Byte: 38},
   470  							End:   hcl.Pos{Line: 3, Column: 16, Byte: 39},
   471  						},
   472  						CloseBraceRange: hcl.Range{
   473  							Start: hcl.Pos{Line: 3, Column: 16, Byte: 39},
   474  							End:   hcl.Pos{Line: 3, Column: 17, Byte: 40},
   475  						},
   476  					},
   477  				},
   478  				SrcRange: hcl.Range{
   479  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   480  					End:   hcl.Pos{Line: 4, Column: 1, Byte: 41},
   481  				},
   482  				EndRange: hcl.Range{
   483  					Start: hcl.Pos{Line: 4, Column: 1, Byte: 41},
   484  					End:   hcl.Pos{Line: 4, Column: 1, Byte: 41},
   485  				},
   486  			},
   487  		},
   488  		{
   489  			`block "f\o" {}
   490  `,
   491  			1, // "\o" is not a valid escape sequence
   492  			&Body{
   493  				Attributes: Attributes{},
   494  				Blocks: Blocks{
   495  					&Block{
   496  						Type:   "block",
   497  						Labels: []string{"fo"},
   498  						Body: &Body{
   499  							Attributes: map[string]*Attribute{},
   500  							Blocks:     []*Block{},
   501  
   502  							SrcRange: hcl.Range{
   503  								Start: hcl.Pos{Line: 1, Column: 13, Byte: 12},
   504  								End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   505  							},
   506  							EndRange: hcl.Range{
   507  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
   508  								End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   509  							},
   510  						},
   511  
   512  						TypeRange: hcl.Range{
   513  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   514  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   515  						},
   516  						LabelRanges: []hcl.Range{
   517  							{
   518  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   519  								End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
   520  							},
   521  						},
   522  						OpenBraceRange: hcl.Range{
   523  							Start: hcl.Pos{Line: 1, Column: 13, Byte: 12},
   524  							End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
   525  						},
   526  						CloseBraceRange: hcl.Range{
   527  							Start: hcl.Pos{Line: 1, Column: 14, Byte: 13},
   528  							End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   529  						},
   530  					},
   531  				},
   532  				SrcRange: hcl.Range{
   533  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   534  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 15},
   535  				},
   536  				EndRange: hcl.Range{
   537  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 15},
   538  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 15},
   539  				},
   540  			},
   541  		},
   542  		{
   543  			`block "f\n" {}
   544  `,
   545  			0,
   546  			&Body{
   547  				Attributes: Attributes{},
   548  				Blocks: Blocks{
   549  					&Block{
   550  						Type:   "block",
   551  						Labels: []string{"f\n"},
   552  						Body: &Body{
   553  							Attributes: Attributes{},
   554  							Blocks:     Blocks{},
   555  
   556  							SrcRange: hcl.Range{
   557  								Start: hcl.Pos{Line: 1, Column: 13, Byte: 12},
   558  								End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   559  							},
   560  							EndRange: hcl.Range{
   561  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
   562  								End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   563  							},
   564  						},
   565  
   566  						TypeRange: hcl.Range{
   567  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   568  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   569  						},
   570  						LabelRanges: []hcl.Range{
   571  							{
   572  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
   573  								End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
   574  							},
   575  						},
   576  						OpenBraceRange: hcl.Range{
   577  							Start: hcl.Pos{Line: 1, Column: 13, Byte: 12},
   578  							End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
   579  						},
   580  						CloseBraceRange: hcl.Range{
   581  							Start: hcl.Pos{Line: 1, Column: 14, Byte: 13},
   582  							End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   583  						},
   584  					},
   585  				},
   586  				SrcRange: hcl.Range{
   587  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   588  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 15},
   589  				},
   590  				EndRange: hcl.Range{
   591  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 15},
   592  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 15},
   593  				},
   594  			},
   595  		},
   596  
   597  		{
   598  			"a = 1\n",
   599  			0,
   600  			&Body{
   601  				Attributes: Attributes{
   602  					"a": {
   603  						Name: "a",
   604  						Expr: &LiteralValueExpr{
   605  							Val: cty.NumberIntVal(1),
   606  
   607  							SrcRange: hcl.Range{
   608  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
   609  								End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   610  							},
   611  						},
   612  
   613  						SrcRange: hcl.Range{
   614  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   615  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   616  						},
   617  						NameRange: hcl.Range{
   618  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   619  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
   620  						},
   621  						EqualsRange: hcl.Range{
   622  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
   623  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
   624  						},
   625  					},
   626  				},
   627  				Blocks: Blocks{},
   628  				SrcRange: hcl.Range{
   629  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   630  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 6},
   631  				},
   632  				EndRange: hcl.Range{
   633  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 6},
   634  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 6},
   635  				},
   636  			},
   637  		},
   638  		{
   639  			"a = 1",
   640  			0,
   641  			&Body{
   642  				Attributes: Attributes{
   643  					"a": {
   644  						Name: "a",
   645  						Expr: &LiteralValueExpr{
   646  							Val: cty.NumberIntVal(1),
   647  
   648  							SrcRange: hcl.Range{
   649  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
   650  								End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   651  							},
   652  						},
   653  
   654  						SrcRange: hcl.Range{
   655  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   656  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   657  						},
   658  						NameRange: hcl.Range{
   659  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   660  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
   661  						},
   662  						EqualsRange: hcl.Range{
   663  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
   664  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
   665  						},
   666  					},
   667  				},
   668  				Blocks: Blocks{},
   669  				SrcRange: hcl.Range{
   670  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   671  					End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   672  				},
   673  				EndRange: hcl.Range{
   674  					Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
   675  					End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
   676  				},
   677  			},
   678  		},
   679  		{
   680  			"a = \"hello ${true}\"\n",
   681  			0,
   682  			&Body{
   683  				Attributes: Attributes{
   684  					"a": {
   685  						Name: "a",
   686  						Expr: &TemplateExpr{
   687  							Parts: []Expression{
   688  								&LiteralValueExpr{
   689  									Val: cty.StringVal("hello "),
   690  
   691  									SrcRange: hcl.Range{
   692  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
   693  										End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
   694  									},
   695  								},
   696  								&LiteralValueExpr{
   697  									Val: cty.True,
   698  
   699  									SrcRange: hcl.Range{
   700  										Start: hcl.Pos{Line: 1, Column: 14, Byte: 13},
   701  										End:   hcl.Pos{Line: 1, Column: 18, Byte: 17},
   702  									},
   703  								},
   704  							},
   705  
   706  							SrcRange: hcl.Range{
   707  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
   708  								End:   hcl.Pos{Line: 1, Column: 20, Byte: 19},
   709  							},
   710  						},
   711  
   712  						SrcRange: hcl.Range{
   713  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   714  							End:   hcl.Pos{Line: 1, Column: 20, Byte: 19},
   715  						},
   716  						NameRange: hcl.Range{
   717  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   718  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
   719  						},
   720  						EqualsRange: hcl.Range{
   721  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
   722  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
   723  						},
   724  					},
   725  				},
   726  				Blocks: Blocks{},
   727  				SrcRange: hcl.Range{
   728  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   729  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 20},
   730  				},
   731  				EndRange: hcl.Range{
   732  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 20},
   733  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 20},
   734  				},
   735  			},
   736  		},
   737  		{
   738  			"a = \"hello $${true}\"\n",
   739  			0,
   740  			&Body{
   741  				Attributes: Attributes{
   742  					"a": {
   743  						Name: "a",
   744  						Expr: &TemplateExpr{
   745  							Parts: []Expression{
   746  								&LiteralValueExpr{
   747  									Val: cty.StringVal("hello ${true}"),
   748  
   749  									SrcRange: hcl.Range{
   750  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
   751  										End:   hcl.Pos{Line: 1, Column: 20, Byte: 19},
   752  									},
   753  								},
   754  							},
   755  
   756  							SrcRange: hcl.Range{
   757  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
   758  								End:   hcl.Pos{Line: 1, Column: 21, Byte: 20},
   759  							},
   760  						},
   761  
   762  						SrcRange: hcl.Range{
   763  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   764  							End:   hcl.Pos{Line: 1, Column: 21, Byte: 20},
   765  						},
   766  						NameRange: hcl.Range{
   767  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   768  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
   769  						},
   770  						EqualsRange: hcl.Range{
   771  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
   772  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
   773  						},
   774  					},
   775  				},
   776  				Blocks: Blocks{},
   777  				SrcRange: hcl.Range{
   778  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   779  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 21},
   780  				},
   781  				EndRange: hcl.Range{
   782  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 21},
   783  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 21},
   784  				},
   785  			},
   786  		},
   787  		{
   788  			"a = \"hello %%{true}\"\n",
   789  			0,
   790  			&Body{
   791  				Attributes: Attributes{
   792  					"a": {
   793  						Name: "a",
   794  						Expr: &TemplateExpr{
   795  							Parts: []Expression{
   796  								&LiteralValueExpr{
   797  									Val: cty.StringVal("hello %{true}"),
   798  
   799  									SrcRange: hcl.Range{
   800  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
   801  										End:   hcl.Pos{Line: 1, Column: 20, Byte: 19},
   802  									},
   803  								},
   804  							},
   805  
   806  							SrcRange: hcl.Range{
   807  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
   808  								End:   hcl.Pos{Line: 1, Column: 21, Byte: 20},
   809  							},
   810  						},
   811  
   812  						SrcRange: hcl.Range{
   813  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   814  							End:   hcl.Pos{Line: 1, Column: 21, Byte: 20},
   815  						},
   816  						NameRange: hcl.Range{
   817  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   818  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
   819  						},
   820  						EqualsRange: hcl.Range{
   821  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
   822  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
   823  						},
   824  					},
   825  				},
   826  				Blocks: Blocks{},
   827  				SrcRange: hcl.Range{
   828  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   829  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 21},
   830  				},
   831  				EndRange: hcl.Range{
   832  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 21},
   833  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 21},
   834  				},
   835  			},
   836  		},
   837  		{
   838  			"a = \"hello $$\"\n",
   839  			0,
   840  			&Body{
   841  				Attributes: Attributes{
   842  					"a": {
   843  						Name: "a",
   844  						Expr: &TemplateExpr{
   845  							Parts: []Expression{
   846  								&LiteralValueExpr{
   847  									Val: cty.StringVal("hello $$"),
   848  
   849  									SrcRange: hcl.Range{
   850  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
   851  										End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
   852  									},
   853  								},
   854  							},
   855  
   856  							SrcRange: hcl.Range{
   857  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
   858  								End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   859  							},
   860  						},
   861  
   862  						SrcRange: hcl.Range{
   863  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   864  							End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   865  						},
   866  						NameRange: hcl.Range{
   867  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   868  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
   869  						},
   870  						EqualsRange: hcl.Range{
   871  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
   872  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
   873  						},
   874  					},
   875  				},
   876  				Blocks: Blocks{},
   877  				SrcRange: hcl.Range{
   878  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   879  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 15},
   880  				},
   881  				EndRange: hcl.Range{
   882  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 15},
   883  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 15},
   884  				},
   885  			},
   886  		},
   887  		{
   888  			"a = \"hello $\"\n",
   889  			0, // unterminated template interpolation sequence
   890  			&Body{
   891  				Attributes: Attributes{
   892  					"a": {
   893  						Name: "a",
   894  						Expr: &TemplateExpr{
   895  							Parts: []Expression{
   896  								&LiteralValueExpr{
   897  									Val: cty.StringVal("hello $"),
   898  
   899  									SrcRange: hcl.Range{
   900  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
   901  										End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
   902  									},
   903  								},
   904  							},
   905  
   906  							SrcRange: hcl.Range{
   907  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
   908  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
   909  							},
   910  						},
   911  
   912  						SrcRange: hcl.Range{
   913  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   914  							End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
   915  						},
   916  						NameRange: hcl.Range{
   917  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   918  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
   919  						},
   920  						EqualsRange: hcl.Range{
   921  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
   922  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
   923  						},
   924  					},
   925  				},
   926  				Blocks: Blocks{},
   927  				SrcRange: hcl.Range{
   928  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   929  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 14},
   930  				},
   931  				EndRange: hcl.Range{
   932  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 14},
   933  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 14},
   934  				},
   935  			},
   936  		},
   937  		{
   938  			"a = \"hello %%\"\n",
   939  			0,
   940  			&Body{
   941  				Attributes: Attributes{
   942  					"a": {
   943  						Name: "a",
   944  						Expr: &TemplateExpr{
   945  							Parts: []Expression{
   946  								&LiteralValueExpr{
   947  									Val: cty.StringVal("hello %%"),
   948  
   949  									SrcRange: hcl.Range{
   950  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
   951  										End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
   952  									},
   953  								},
   954  							},
   955  
   956  							SrcRange: hcl.Range{
   957  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
   958  								End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   959  							},
   960  						},
   961  
   962  						SrcRange: hcl.Range{
   963  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   964  							End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
   965  						},
   966  						NameRange: hcl.Range{
   967  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   968  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
   969  						},
   970  						EqualsRange: hcl.Range{
   971  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
   972  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
   973  						},
   974  					},
   975  				},
   976  				Blocks: Blocks{},
   977  				SrcRange: hcl.Range{
   978  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
   979  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 15},
   980  				},
   981  				EndRange: hcl.Range{
   982  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 15},
   983  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 15},
   984  				},
   985  			},
   986  		},
   987  		{
   988  			"a = \"hello %\"\n",
   989  			0, // unterminated template control sequence
   990  			&Body{
   991  				Attributes: Attributes{
   992  					"a": {
   993  						Name: "a",
   994  						Expr: &TemplateExpr{
   995  							Parts: []Expression{
   996  								&LiteralValueExpr{
   997  									Val: cty.StringVal("hello %"),
   998  
   999  									SrcRange: hcl.Range{
  1000  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1001  										End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
  1002  									},
  1003  								},
  1004  							},
  1005  
  1006  							SrcRange: hcl.Range{
  1007  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1008  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  1009  							},
  1010  						},
  1011  
  1012  						SrcRange: hcl.Range{
  1013  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1014  							End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  1015  						},
  1016  						NameRange: hcl.Range{
  1017  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1018  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1019  						},
  1020  						EqualsRange: hcl.Range{
  1021  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1022  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1023  						},
  1024  					},
  1025  				},
  1026  				Blocks: Blocks{},
  1027  				SrcRange: hcl.Range{
  1028  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1029  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 14},
  1030  				},
  1031  				EndRange: hcl.Range{
  1032  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 14},
  1033  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 14},
  1034  				},
  1035  			},
  1036  		},
  1037  		{
  1038  			"a = \"hello!\"\n",
  1039  			0,
  1040  			&Body{
  1041  				Attributes: Attributes{
  1042  					"a": {
  1043  						Name: "a",
  1044  						Expr: &TemplateExpr{
  1045  							Parts: []Expression{
  1046  								&LiteralValueExpr{
  1047  									Val: cty.StringVal("hello!"),
  1048  
  1049  									SrcRange: hcl.Range{
  1050  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1051  										End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
  1052  									},
  1053  								},
  1054  							},
  1055  
  1056  							SrcRange: hcl.Range{
  1057  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1058  								End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
  1059  							},
  1060  						},
  1061  
  1062  						SrcRange: hcl.Range{
  1063  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1064  							End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
  1065  						},
  1066  						NameRange: hcl.Range{
  1067  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1068  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1069  						},
  1070  						EqualsRange: hcl.Range{
  1071  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1072  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1073  						},
  1074  					},
  1075  				},
  1076  				Blocks: Blocks{},
  1077  				SrcRange: hcl.Range{
  1078  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1079  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1080  				},
  1081  				EndRange: hcl.Range{
  1082  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1083  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1084  				},
  1085  			},
  1086  		},
  1087  		{
  1088  			"a = \"\\u2022\"\n",
  1089  			0,
  1090  			&Body{
  1091  				Attributes: Attributes{
  1092  					"a": {
  1093  						Name: "a",
  1094  						Expr: &TemplateExpr{
  1095  							Parts: []Expression{
  1096  								&LiteralValueExpr{
  1097  									Val: cty.StringVal("\u2022"),
  1098  
  1099  									SrcRange: hcl.Range{
  1100  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1101  										End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
  1102  									},
  1103  								},
  1104  							},
  1105  
  1106  							SrcRange: hcl.Range{
  1107  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1108  								End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
  1109  							},
  1110  						},
  1111  
  1112  						SrcRange: hcl.Range{
  1113  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1114  							End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
  1115  						},
  1116  						NameRange: hcl.Range{
  1117  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1118  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1119  						},
  1120  						EqualsRange: hcl.Range{
  1121  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1122  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1123  						},
  1124  					},
  1125  				},
  1126  				Blocks: Blocks{},
  1127  				SrcRange: hcl.Range{
  1128  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1129  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1130  				},
  1131  				EndRange: hcl.Range{
  1132  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1133  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1134  				},
  1135  			},
  1136  		},
  1137  		{
  1138  			"a = \"\\uu2022\"\n",
  1139  			1, // \u must be followed by four hex digits
  1140  			&Body{
  1141  				Attributes: Attributes{
  1142  					"a": {
  1143  						Name: "a",
  1144  						Expr: &TemplateExpr{
  1145  							Parts: []Expression{
  1146  								&LiteralValueExpr{
  1147  									Val: cty.StringVal("\\uu2022"),
  1148  
  1149  									SrcRange: hcl.Range{
  1150  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1151  										End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
  1152  									},
  1153  								},
  1154  							},
  1155  
  1156  							SrcRange: hcl.Range{
  1157  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1158  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  1159  							},
  1160  						},
  1161  
  1162  						SrcRange: hcl.Range{
  1163  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1164  							End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  1165  						},
  1166  						NameRange: hcl.Range{
  1167  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1168  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1169  						},
  1170  						EqualsRange: hcl.Range{
  1171  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1172  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1173  						},
  1174  					},
  1175  				},
  1176  				Blocks: Blocks{},
  1177  				SrcRange: hcl.Range{
  1178  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1179  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 14},
  1180  				},
  1181  				EndRange: hcl.Range{
  1182  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 14},
  1183  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 14},
  1184  				},
  1185  			},
  1186  		},
  1187  		{
  1188  			"a = \"\\U0001d11e\"\n",
  1189  			0,
  1190  			&Body{
  1191  				Attributes: Attributes{
  1192  					"a": {
  1193  						Name: "a",
  1194  						Expr: &TemplateExpr{
  1195  							Parts: []Expression{
  1196  								&LiteralValueExpr{
  1197  									Val: cty.StringVal("\U0001d11e"),
  1198  
  1199  									SrcRange: hcl.Range{
  1200  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1201  										End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  1202  									},
  1203  								},
  1204  							},
  1205  
  1206  							SrcRange: hcl.Range{
  1207  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1208  								End:   hcl.Pos{Line: 1, Column: 17, Byte: 16},
  1209  							},
  1210  						},
  1211  
  1212  						SrcRange: hcl.Range{
  1213  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1214  							End:   hcl.Pos{Line: 1, Column: 17, Byte: 16},
  1215  						},
  1216  						NameRange: hcl.Range{
  1217  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1218  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1219  						},
  1220  						EqualsRange: hcl.Range{
  1221  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1222  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1223  						},
  1224  					},
  1225  				},
  1226  				Blocks: Blocks{},
  1227  				SrcRange: hcl.Range{
  1228  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1229  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1230  				},
  1231  				EndRange: hcl.Range{
  1232  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1233  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1234  				},
  1235  			},
  1236  		},
  1237  		{
  1238  			"a = \"\\u0001d11e\"\n",
  1239  			0, // This is valid, but probably not what the user intended :(
  1240  			&Body{
  1241  				Attributes: Attributes{
  1242  					"a": {
  1243  						Name: "a",
  1244  						Expr: &TemplateExpr{
  1245  							Parts: []Expression{
  1246  								&LiteralValueExpr{
  1247  									// Only the first four digits were used for the
  1248  									// escape sequence, so the remaining four just
  1249  									// get echoed out literally.
  1250  									Val: cty.StringVal("\u0001d11e"),
  1251  
  1252  									SrcRange: hcl.Range{
  1253  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1254  										End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  1255  									},
  1256  								},
  1257  							},
  1258  
  1259  							SrcRange: hcl.Range{
  1260  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1261  								End:   hcl.Pos{Line: 1, Column: 17, Byte: 16},
  1262  							},
  1263  						},
  1264  
  1265  						SrcRange: hcl.Range{
  1266  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1267  							End:   hcl.Pos{Line: 1, Column: 17, Byte: 16},
  1268  						},
  1269  						NameRange: hcl.Range{
  1270  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1271  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1272  						},
  1273  						EqualsRange: hcl.Range{
  1274  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1275  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1276  						},
  1277  					},
  1278  				},
  1279  				Blocks: Blocks{},
  1280  				SrcRange: hcl.Range{
  1281  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1282  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1283  				},
  1284  				EndRange: hcl.Range{
  1285  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1286  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1287  				},
  1288  			},
  1289  		},
  1290  		{
  1291  			"a = \"\\U2022\"\n",
  1292  			1, // Invalid escape sequence, since we need eight hex digits for \U
  1293  			&Body{
  1294  				Attributes: Attributes{
  1295  					"a": {
  1296  						Name: "a",
  1297  						Expr: &TemplateExpr{
  1298  							Parts: []Expression{
  1299  								&LiteralValueExpr{
  1300  									Val: cty.StringVal("\\U2022"),
  1301  
  1302  									SrcRange: hcl.Range{
  1303  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1304  										End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
  1305  									},
  1306  								},
  1307  							},
  1308  
  1309  							SrcRange: hcl.Range{
  1310  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1311  								End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
  1312  							},
  1313  						},
  1314  
  1315  						SrcRange: hcl.Range{
  1316  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1317  							End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
  1318  						},
  1319  						NameRange: hcl.Range{
  1320  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1321  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1322  						},
  1323  						EqualsRange: hcl.Range{
  1324  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1325  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1326  						},
  1327  					},
  1328  				},
  1329  				Blocks: Blocks{},
  1330  				SrcRange: hcl.Range{
  1331  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1332  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1333  				},
  1334  				EndRange: hcl.Range{
  1335  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1336  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1337  				},
  1338  			},
  1339  		},
  1340  		{
  1341  			"a = \"\\u20m2\"\n",
  1342  			1, // Invalid escape sequence
  1343  			&Body{
  1344  				Attributes: Attributes{
  1345  					"a": {
  1346  						Name: "a",
  1347  						Expr: &TemplateExpr{
  1348  							Parts: []Expression{
  1349  								&LiteralValueExpr{
  1350  									Val: cty.StringVal("\\u20m2"),
  1351  
  1352  									SrcRange: hcl.Range{
  1353  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1354  										End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
  1355  									},
  1356  								},
  1357  							},
  1358  
  1359  							SrcRange: hcl.Range{
  1360  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1361  								End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
  1362  							},
  1363  						},
  1364  
  1365  						SrcRange: hcl.Range{
  1366  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1367  							End:   hcl.Pos{Line: 1, Column: 13, Byte: 12},
  1368  						},
  1369  						NameRange: hcl.Range{
  1370  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1371  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1372  						},
  1373  						EqualsRange: hcl.Range{
  1374  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1375  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1376  						},
  1377  					},
  1378  				},
  1379  				Blocks: Blocks{},
  1380  				SrcRange: hcl.Range{
  1381  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1382  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1383  				},
  1384  				EndRange: hcl.Range{
  1385  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1386  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 13},
  1387  				},
  1388  			},
  1389  		},
  1390  		{
  1391  			"a = \"\\U00300000\"\n",
  1392  			1, // Invalid unicode character (can't encode in UTF-8)
  1393  			&Body{
  1394  				Attributes: Attributes{
  1395  					"a": {
  1396  						Name: "a",
  1397  						Expr: &TemplateExpr{
  1398  							Parts: []Expression{
  1399  								&LiteralValueExpr{
  1400  									Val: cty.StringVal("\\U00300000"),
  1401  
  1402  									SrcRange: hcl.Range{
  1403  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1404  										End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  1405  									},
  1406  								},
  1407  							},
  1408  
  1409  							SrcRange: hcl.Range{
  1410  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1411  								End:   hcl.Pos{Line: 1, Column: 17, Byte: 16},
  1412  							},
  1413  						},
  1414  
  1415  						SrcRange: hcl.Range{
  1416  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1417  							End:   hcl.Pos{Line: 1, Column: 17, Byte: 16},
  1418  						},
  1419  						NameRange: hcl.Range{
  1420  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1421  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1422  						},
  1423  						EqualsRange: hcl.Range{
  1424  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1425  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1426  						},
  1427  					},
  1428  				},
  1429  				Blocks: Blocks{},
  1430  				SrcRange: hcl.Range{
  1431  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1432  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1433  				},
  1434  				EndRange: hcl.Range{
  1435  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1436  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1437  				},
  1438  			},
  1439  		},
  1440  		{
  1441  			"a = \"\\Ub2705550\"\n",
  1442  			1, // Invalid unicode character (can't encode in UTF-8)
  1443  			&Body{
  1444  				Attributes: Attributes{
  1445  					"a": {
  1446  						Name: "a",
  1447  						Expr: &TemplateExpr{
  1448  							Parts: []Expression{
  1449  								&LiteralValueExpr{
  1450  									Val: cty.StringVal("\\Ub2705550"),
  1451  
  1452  									SrcRange: hcl.Range{
  1453  										Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1454  										End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  1455  									},
  1456  								},
  1457  							},
  1458  
  1459  							SrcRange: hcl.Range{
  1460  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1461  								End:   hcl.Pos{Line: 1, Column: 17, Byte: 16},
  1462  							},
  1463  						},
  1464  
  1465  						SrcRange: hcl.Range{
  1466  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1467  							End:   hcl.Pos{Line: 1, Column: 17, Byte: 16},
  1468  						},
  1469  						NameRange: hcl.Range{
  1470  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1471  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1472  						},
  1473  						EqualsRange: hcl.Range{
  1474  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1475  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1476  						},
  1477  					},
  1478  				},
  1479  				Blocks: Blocks{},
  1480  				SrcRange: hcl.Range{
  1481  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1482  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1483  				},
  1484  				EndRange: hcl.Range{
  1485  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1486  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 17},
  1487  				},
  1488  			},
  1489  		},
  1490  		{
  1491  			"a = <<EOT\nHello\nEOT\nb = \"Hi\"",
  1492  			0,
  1493  			&Body{
  1494  				Attributes: Attributes{
  1495  					"a": {
  1496  						Name: "a",
  1497  						Expr: &TemplateExpr{
  1498  							Parts: []Expression{
  1499  								&LiteralValueExpr{
  1500  									Val: cty.StringVal("Hello\n"),
  1501  
  1502  									SrcRange: hcl.Range{
  1503  										Start: hcl.Pos{Line: 2, Column: 1, Byte: 10},
  1504  										End:   hcl.Pos{Line: 3, Column: 1, Byte: 16},
  1505  									},
  1506  								},
  1507  							},
  1508  
  1509  							SrcRange: hcl.Range{
  1510  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1511  								End:   hcl.Pos{Line: 3, Column: 4, Byte: 19},
  1512  							},
  1513  						},
  1514  
  1515  						SrcRange: hcl.Range{
  1516  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1517  							End:   hcl.Pos{Line: 3, Column: 4, Byte: 19},
  1518  						},
  1519  						NameRange: hcl.Range{
  1520  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1521  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1522  						},
  1523  						EqualsRange: hcl.Range{
  1524  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1525  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1526  						},
  1527  					},
  1528  					"b": {
  1529  						Name: "b",
  1530  						Expr: &TemplateExpr{
  1531  							Parts: []Expression{
  1532  								&LiteralValueExpr{
  1533  									Val: cty.StringVal("Hi"),
  1534  
  1535  									SrcRange: hcl.Range{
  1536  										Start: hcl.Pos{Line: 4, Column: 6, Byte: 25},
  1537  										End:   hcl.Pos{Line: 4, Column: 8, Byte: 27},
  1538  									},
  1539  								},
  1540  							},
  1541  
  1542  							SrcRange: hcl.Range{
  1543  								Start: hcl.Pos{Line: 4, Column: 5, Byte: 24},
  1544  								End:   hcl.Pos{Line: 4, Column: 9, Byte: 28},
  1545  							},
  1546  						},
  1547  
  1548  						SrcRange: hcl.Range{
  1549  							Start: hcl.Pos{Line: 4, Column: 1, Byte: 20},
  1550  							End:   hcl.Pos{Line: 4, Column: 9, Byte: 28},
  1551  						},
  1552  						NameRange: hcl.Range{
  1553  							Start: hcl.Pos{Line: 4, Column: 1, Byte: 20},
  1554  							End:   hcl.Pos{Line: 4, Column: 2, Byte: 21},
  1555  						},
  1556  						EqualsRange: hcl.Range{
  1557  							Start: hcl.Pos{Line: 4, Column: 3, Byte: 22},
  1558  							End:   hcl.Pos{Line: 4, Column: 4, Byte: 23},
  1559  						},
  1560  					},
  1561  				},
  1562  				Blocks: Blocks{},
  1563  				SrcRange: hcl.Range{
  1564  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1565  					End:   hcl.Pos{Line: 4, Column: 9, Byte: 28},
  1566  				},
  1567  				EndRange: hcl.Range{
  1568  					Start: hcl.Pos{Line: 4, Column: 9, Byte: 28},
  1569  					End:   hcl.Pos{Line: 4, Column: 9, Byte: 28},
  1570  				},
  1571  			},
  1572  		},
  1573  		{
  1574  			"a = foo.bar\n",
  1575  			0,
  1576  			&Body{
  1577  				Attributes: Attributes{
  1578  					"a": {
  1579  						Name: "a",
  1580  						Expr: &ScopeTraversalExpr{
  1581  							Traversal: hcl.Traversal{
  1582  								hcl.TraverseRoot{
  1583  									Name: "foo",
  1584  
  1585  									SrcRange: hcl.Range{
  1586  										Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1587  										End:   hcl.Pos{Line: 1, Column: 8, Byte: 7},
  1588  									},
  1589  								},
  1590  								hcl.TraverseAttr{
  1591  									Name: "bar",
  1592  
  1593  									SrcRange: hcl.Range{
  1594  										Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
  1595  										End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
  1596  									},
  1597  								},
  1598  							},
  1599  
  1600  							SrcRange: hcl.Range{
  1601  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1602  								End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
  1603  							},
  1604  						},
  1605  
  1606  						SrcRange: hcl.Range{
  1607  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1608  							End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
  1609  						},
  1610  						NameRange: hcl.Range{
  1611  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1612  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1613  						},
  1614  						EqualsRange: hcl.Range{
  1615  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1616  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1617  						},
  1618  					},
  1619  				},
  1620  				Blocks: Blocks{},
  1621  				SrcRange: hcl.Range{
  1622  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1623  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 12},
  1624  				},
  1625  				EndRange: hcl.Range{
  1626  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 12},
  1627  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 12},
  1628  				},
  1629  			},
  1630  		},
  1631  		{
  1632  			"a = foo.0.1.baz\n",
  1633  			1, // Chaining legacy index syntax is not supported
  1634  			&Body{
  1635  				Attributes: Attributes{
  1636  					"a": {
  1637  						Name: "a",
  1638  						Expr: &ScopeTraversalExpr{
  1639  							Traversal: hcl.Traversal{
  1640  								hcl.TraverseRoot{
  1641  									Name: "foo",
  1642  
  1643  									SrcRange: hcl.Range{
  1644  										Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1645  										End:   hcl.Pos{Line: 1, Column: 8, Byte: 7},
  1646  									},
  1647  								},
  1648  								hcl.TraverseIndex{
  1649  									Key: cty.DynamicVal,
  1650  
  1651  									SrcRange: hcl.Range{
  1652  										Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
  1653  										End:   hcl.Pos{Line: 1, Column: 12, Byte: 11},
  1654  									},
  1655  								},
  1656  								hcl.TraverseAttr{
  1657  									Name: "baz",
  1658  
  1659  									SrcRange: hcl.Range{
  1660  										Start: hcl.Pos{Line: 1, Column: 12, Byte: 11},
  1661  										End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  1662  									},
  1663  								},
  1664  							},
  1665  
  1666  							SrcRange: hcl.Range{
  1667  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1668  								End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  1669  							},
  1670  						},
  1671  
  1672  						SrcRange: hcl.Range{
  1673  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1674  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  1675  						},
  1676  						NameRange: hcl.Range{
  1677  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1678  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1679  						},
  1680  						EqualsRange: hcl.Range{
  1681  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1682  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1683  						},
  1684  					},
  1685  				},
  1686  				Blocks: Blocks{},
  1687  				SrcRange: hcl.Range{
  1688  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1689  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 16},
  1690  				},
  1691  				EndRange: hcl.Range{
  1692  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 16},
  1693  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 16},
  1694  				},
  1695  			},
  1696  		},
  1697  		{
  1698  			"a = \"${var.public_subnets[count.index]}\"\n",
  1699  			0,
  1700  			&Body{
  1701  				Attributes: Attributes{
  1702  					"a": {
  1703  						Name: "a",
  1704  						Expr: &TemplateWrapExpr{
  1705  							Wrapped: &IndexExpr{
  1706  								Collection: &ScopeTraversalExpr{
  1707  									Traversal: hcl.Traversal{
  1708  										hcl.TraverseRoot{
  1709  											Name: "var",
  1710  
  1711  											SrcRange: hcl.Range{
  1712  												Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
  1713  												End:   hcl.Pos{Line: 1, Column: 11, Byte: 10},
  1714  											},
  1715  										},
  1716  										hcl.TraverseAttr{
  1717  											Name: "public_subnets",
  1718  
  1719  											SrcRange: hcl.Range{
  1720  												Start: hcl.Pos{Line: 1, Column: 11, Byte: 10},
  1721  												End:   hcl.Pos{Line: 1, Column: 26, Byte: 25},
  1722  											},
  1723  										},
  1724  									},
  1725  
  1726  									SrcRange: hcl.Range{
  1727  										Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
  1728  										End:   hcl.Pos{Line: 1, Column: 26, Byte: 25},
  1729  									},
  1730  								},
  1731  								Key: &ScopeTraversalExpr{
  1732  									Traversal: hcl.Traversal{
  1733  										hcl.TraverseRoot{
  1734  											Name: "count",
  1735  
  1736  											SrcRange: hcl.Range{
  1737  												Start: hcl.Pos{Line: 1, Column: 27, Byte: 26},
  1738  												End:   hcl.Pos{Line: 1, Column: 32, Byte: 31},
  1739  											},
  1740  										},
  1741  										hcl.TraverseAttr{
  1742  											Name: "index",
  1743  
  1744  											SrcRange: hcl.Range{
  1745  												Start: hcl.Pos{Line: 1, Column: 32, Byte: 31},
  1746  												End:   hcl.Pos{Line: 1, Column: 38, Byte: 37},
  1747  											},
  1748  										},
  1749  									},
  1750  
  1751  									SrcRange: hcl.Range{
  1752  										Start: hcl.Pos{Line: 1, Column: 27, Byte: 26},
  1753  										End:   hcl.Pos{Line: 1, Column: 38, Byte: 37},
  1754  									},
  1755  								},
  1756  								SrcRange: hcl.Range{
  1757  									Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
  1758  									End:   hcl.Pos{Line: 1, Column: 39, Byte: 38},
  1759  								},
  1760  								OpenRange: hcl.Range{
  1761  									Start: hcl.Pos{Line: 1, Column: 26, Byte: 25},
  1762  									End:   hcl.Pos{Line: 1, Column: 27, Byte: 26},
  1763  								},
  1764  								BracketRange: hcl.Range{
  1765  									Start: hcl.Pos{Line: 1, Column: 26, Byte: 25},
  1766  									End:   hcl.Pos{Line: 1, Column: 39, Byte: 38},
  1767  								},
  1768  							},
  1769  							SrcRange: hcl.Range{
  1770  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1771  								End:   hcl.Pos{Line: 1, Column: 41, Byte: 40},
  1772  							},
  1773  						},
  1774  						SrcRange: hcl.Range{
  1775  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1776  							End:   hcl.Pos{Line: 1, Column: 41, Byte: 40},
  1777  						},
  1778  						NameRange: hcl.Range{
  1779  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1780  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1781  						},
  1782  						EqualsRange: hcl.Range{
  1783  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1784  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1785  						},
  1786  					},
  1787  				},
  1788  				Blocks: Blocks{},
  1789  				SrcRange: hcl.Range{
  1790  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1791  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 41},
  1792  				},
  1793  				EndRange: hcl.Range{
  1794  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 41},
  1795  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 41},
  1796  				},
  1797  			},
  1798  		},
  1799  		{
  1800  			"a = \"${var.public_subnets[*]}\"\n",
  1801  			0,
  1802  			&Body{
  1803  				Attributes: Attributes{
  1804  					"a": {
  1805  						Name: "a",
  1806  						Expr: &TemplateWrapExpr{
  1807  							Wrapped: &SplatExpr{
  1808  								Source: &ScopeTraversalExpr{
  1809  									Traversal: hcl.Traversal{
  1810  										hcl.TraverseRoot{
  1811  											Name: "var",
  1812  
  1813  											SrcRange: hcl.Range{
  1814  												Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
  1815  												End:   hcl.Pos{Line: 1, Column: 11, Byte: 10},
  1816  											},
  1817  										},
  1818  										hcl.TraverseAttr{
  1819  											Name: "public_subnets",
  1820  
  1821  											SrcRange: hcl.Range{
  1822  												Start: hcl.Pos{Line: 1, Column: 11, Byte: 10},
  1823  												End:   hcl.Pos{Line: 1, Column: 26, Byte: 25},
  1824  											},
  1825  										},
  1826  									},
  1827  
  1828  									SrcRange: hcl.Range{
  1829  										Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
  1830  										End:   hcl.Pos{Line: 1, Column: 26, Byte: 25},
  1831  									},
  1832  								},
  1833  								Each: &AnonSymbolExpr{
  1834  									SrcRange: hcl.Range{
  1835  										Start: hcl.Pos{Line: 1, Column: 26, Byte: 25},
  1836  										End:   hcl.Pos{Line: 1, Column: 29, Byte: 28},
  1837  									},
  1838  								},
  1839  								Item: &AnonSymbolExpr{
  1840  									SrcRange: hcl.Range{
  1841  										Start: hcl.Pos{Line: 1, Column: 26, Byte: 25},
  1842  										End:   hcl.Pos{Line: 1, Column: 29, Byte: 28},
  1843  									},
  1844  								},
  1845  								SrcRange: hcl.Range{
  1846  									Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
  1847  									End:   hcl.Pos{Line: 1, Column: 29, Byte: 28},
  1848  								},
  1849  								MarkerRange: hcl.Range{
  1850  									Start: hcl.Pos{Line: 1, Column: 26, Byte: 25},
  1851  									End:   hcl.Pos{Line: 1, Column: 29, Byte: 28},
  1852  								},
  1853  							},
  1854  							SrcRange: hcl.Range{
  1855  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1856  								End:   hcl.Pos{Line: 1, Column: 31, Byte: 30},
  1857  							},
  1858  						},
  1859  						SrcRange: hcl.Range{
  1860  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1861  							End:   hcl.Pos{Line: 1, Column: 31, Byte: 30},
  1862  						},
  1863  						NameRange: hcl.Range{
  1864  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1865  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1866  						},
  1867  						EqualsRange: hcl.Range{
  1868  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1869  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1870  						},
  1871  					},
  1872  				},
  1873  				Blocks: Blocks{},
  1874  				SrcRange: hcl.Range{
  1875  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1876  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 31},
  1877  				},
  1878  				EndRange: hcl.Range{
  1879  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 31},
  1880  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 31},
  1881  				},
  1882  			},
  1883  		},
  1884  		{
  1885  			"a = 1 # line comment\n",
  1886  			0,
  1887  			&Body{
  1888  				Attributes: Attributes{
  1889  					"a": {
  1890  						Name: "a",
  1891  						Expr: &LiteralValueExpr{
  1892  							Val: cty.NumberIntVal(1),
  1893  
  1894  							SrcRange: hcl.Range{
  1895  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1896  								End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1897  							},
  1898  						},
  1899  
  1900  						SrcRange: hcl.Range{
  1901  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1902  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1903  						},
  1904  						NameRange: hcl.Range{
  1905  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1906  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1907  						},
  1908  						EqualsRange: hcl.Range{
  1909  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1910  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  1911  						},
  1912  					},
  1913  				},
  1914  				Blocks: Blocks{},
  1915  				SrcRange: hcl.Range{
  1916  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1917  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 21},
  1918  				},
  1919  				EndRange: hcl.Range{
  1920  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 21},
  1921  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 21},
  1922  				},
  1923  			},
  1924  		},
  1925  
  1926  		{
  1927  			"a = [for k, v in foo: v if true]\n",
  1928  			0,
  1929  			&Body{
  1930  				Attributes: Attributes{
  1931  					"a": {
  1932  						Name: "a",
  1933  						Expr: &ForExpr{
  1934  							KeyVar: "k",
  1935  							ValVar: "v",
  1936  
  1937  							CollExpr: &ScopeTraversalExpr{
  1938  								Traversal: hcl.Traversal{
  1939  									hcl.TraverseRoot{
  1940  										Name: "foo",
  1941  										SrcRange: hcl.Range{
  1942  											Start: hcl.Pos{Line: 1, Column: 18, Byte: 17},
  1943  											End:   hcl.Pos{Line: 1, Column: 21, Byte: 20},
  1944  										},
  1945  									},
  1946  								},
  1947  								SrcRange: hcl.Range{
  1948  									Start: hcl.Pos{Line: 1, Column: 18, Byte: 17},
  1949  									End:   hcl.Pos{Line: 1, Column: 21, Byte: 20},
  1950  								},
  1951  							},
  1952  							ValExpr: &ScopeTraversalExpr{
  1953  								Traversal: hcl.Traversal{
  1954  									hcl.TraverseRoot{
  1955  										Name: "v",
  1956  										SrcRange: hcl.Range{
  1957  											Start: hcl.Pos{Line: 1, Column: 23, Byte: 22},
  1958  											End:   hcl.Pos{Line: 1, Column: 24, Byte: 23},
  1959  										},
  1960  									},
  1961  								},
  1962  								SrcRange: hcl.Range{
  1963  									Start: hcl.Pos{Line: 1, Column: 23, Byte: 22},
  1964  									End:   hcl.Pos{Line: 1, Column: 24, Byte: 23},
  1965  								},
  1966  							},
  1967  							CondExpr: &LiteralValueExpr{
  1968  								Val: cty.True,
  1969  								SrcRange: hcl.Range{
  1970  									Start: hcl.Pos{Line: 1, Column: 28, Byte: 27},
  1971  									End:   hcl.Pos{Line: 1, Column: 32, Byte: 31},
  1972  								},
  1973  							},
  1974  
  1975  							SrcRange: hcl.Range{
  1976  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1977  								End:   hcl.Pos{Line: 1, Column: 33, Byte: 32},
  1978  							},
  1979  							OpenRange: hcl.Range{
  1980  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  1981  								End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  1982  							},
  1983  							CloseRange: hcl.Range{
  1984  								Start: hcl.Pos{Line: 1, Column: 32, Byte: 31},
  1985  								End:   hcl.Pos{Line: 1, Column: 33, Byte: 32},
  1986  							},
  1987  						},
  1988  
  1989  						SrcRange: hcl.Range{
  1990  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1991  							End:   hcl.Pos{Line: 1, Column: 33, Byte: 32},
  1992  						},
  1993  						NameRange: hcl.Range{
  1994  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  1995  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  1996  						},
  1997  						EqualsRange: hcl.Range{
  1998  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  1999  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  2000  						},
  2001  					},
  2002  				},
  2003  				Blocks: Blocks{},
  2004  				SrcRange: hcl.Range{
  2005  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2006  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 33},
  2007  				},
  2008  				EndRange: hcl.Range{
  2009  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 33},
  2010  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 33},
  2011  				},
  2012  			},
  2013  		},
  2014  		{
  2015  			"a = [for k, v in foo: k => v... if true]\n",
  2016  			2, // can't use => or ... in a tuple for
  2017  			&Body{
  2018  				Attributes: Attributes{
  2019  					"a": {
  2020  						Name: "a",
  2021  						Expr: &ForExpr{
  2022  							KeyVar: "k",
  2023  							ValVar: "v",
  2024  
  2025  							CollExpr: &ScopeTraversalExpr{
  2026  								Traversal: hcl.Traversal{
  2027  									hcl.TraverseRoot{
  2028  										Name: "foo",
  2029  										SrcRange: hcl.Range{
  2030  											Start: hcl.Pos{Line: 1, Column: 18, Byte: 17},
  2031  											End:   hcl.Pos{Line: 1, Column: 21, Byte: 20},
  2032  										},
  2033  									},
  2034  								},
  2035  								SrcRange: hcl.Range{
  2036  									Start: hcl.Pos{Line: 1, Column: 18, Byte: 17},
  2037  									End:   hcl.Pos{Line: 1, Column: 21, Byte: 20},
  2038  								},
  2039  							},
  2040  							KeyExpr: &ScopeTraversalExpr{
  2041  								Traversal: hcl.Traversal{
  2042  									hcl.TraverseRoot{
  2043  										Name: "k",
  2044  										SrcRange: hcl.Range{
  2045  											Start: hcl.Pos{Line: 1, Column: 23, Byte: 22},
  2046  											End:   hcl.Pos{Line: 1, Column: 24, Byte: 23},
  2047  										},
  2048  									},
  2049  								},
  2050  								SrcRange: hcl.Range{
  2051  									Start: hcl.Pos{Line: 1, Column: 23, Byte: 22},
  2052  									End:   hcl.Pos{Line: 1, Column: 24, Byte: 23},
  2053  								},
  2054  							},
  2055  							ValExpr: &ScopeTraversalExpr{
  2056  								Traversal: hcl.Traversal{
  2057  									hcl.TraverseRoot{
  2058  										Name: "v",
  2059  										SrcRange: hcl.Range{
  2060  											Start: hcl.Pos{Line: 1, Column: 28, Byte: 27},
  2061  											End:   hcl.Pos{Line: 1, Column: 29, Byte: 28},
  2062  										},
  2063  									},
  2064  								},
  2065  								SrcRange: hcl.Range{
  2066  									Start: hcl.Pos{Line: 1, Column: 28, Byte: 27},
  2067  									End:   hcl.Pos{Line: 1, Column: 29, Byte: 28},
  2068  								},
  2069  							},
  2070  							CondExpr: &LiteralValueExpr{
  2071  								Val: cty.True,
  2072  								SrcRange: hcl.Range{
  2073  									Start: hcl.Pos{Line: 1, Column: 36, Byte: 35},
  2074  									End:   hcl.Pos{Line: 1, Column: 40, Byte: 39},
  2075  								},
  2076  							},
  2077  							Group: true,
  2078  
  2079  							SrcRange: hcl.Range{
  2080  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  2081  								End:   hcl.Pos{Line: 1, Column: 41, Byte: 40},
  2082  							},
  2083  							OpenRange: hcl.Range{
  2084  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  2085  								End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2086  							},
  2087  							CloseRange: hcl.Range{
  2088  								Start: hcl.Pos{Line: 1, Column: 40, Byte: 39},
  2089  								End:   hcl.Pos{Line: 1, Column: 41, Byte: 40},
  2090  							},
  2091  						},
  2092  
  2093  						SrcRange: hcl.Range{
  2094  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2095  							End:   hcl.Pos{Line: 1, Column: 41, Byte: 40},
  2096  						},
  2097  						NameRange: hcl.Range{
  2098  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2099  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2100  						},
  2101  						EqualsRange: hcl.Range{
  2102  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  2103  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  2104  						},
  2105  					},
  2106  				},
  2107  				Blocks: Blocks{},
  2108  				SrcRange: hcl.Range{
  2109  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2110  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 41},
  2111  				},
  2112  				EndRange: hcl.Range{
  2113  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 41},
  2114  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 41},
  2115  				},
  2116  			},
  2117  		},
  2118  
  2119  		{
  2120  			`	`,
  2121  			0, // the tab character is treated as a single whitespace character
  2122  			&Body{
  2123  				Attributes: Attributes{},
  2124  				Blocks:     Blocks{},
  2125  				SrcRange: hcl.Range{
  2126  					Start: hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2127  					End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2128  				},
  2129  				EndRange: hcl.Range{
  2130  					Start: hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2131  					End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2132  				},
  2133  			},
  2134  		},
  2135  		{
  2136  			`\x81`,
  2137  			2, // invalid UTF-8, and body item is required here
  2138  			&Body{
  2139  				Attributes: Attributes{},
  2140  				Blocks:     Blocks{},
  2141  				SrcRange: hcl.Range{
  2142  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2143  					End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2144  				},
  2145  				EndRange: hcl.Range{
  2146  					Start: hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2147  					End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2148  				},
  2149  			},
  2150  		},
  2151  		{
  2152  			"a = 1,",
  2153  			1,
  2154  			&Body{
  2155  				Attributes: Attributes{
  2156  					"a": {
  2157  						Name: "a",
  2158  						Expr: &LiteralValueExpr{
  2159  							Val: cty.NumberIntVal(1),
  2160  
  2161  							SrcRange: hcl.Range{
  2162  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  2163  								End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2164  							},
  2165  						},
  2166  
  2167  						SrcRange: hcl.Range{
  2168  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2169  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2170  						},
  2171  						NameRange: hcl.Range{
  2172  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2173  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2174  						},
  2175  						EqualsRange: hcl.Range{
  2176  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  2177  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  2178  						},
  2179  					},
  2180  				},
  2181  				Blocks: Blocks{},
  2182  				SrcRange: hcl.Range{
  2183  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2184  					End:   hcl.Pos{Line: 1, Column: 7, Byte: 6},
  2185  				},
  2186  				EndRange: hcl.Range{
  2187  					Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  2188  					End:   hcl.Pos{Line: 1, Column: 7, Byte: 6},
  2189  				},
  2190  			},
  2191  		},
  2192  		{
  2193  			"a = `str`",
  2194  			2, // Invalid character and expression
  2195  			&Body{
  2196  				Attributes: Attributes{
  2197  					"a": {
  2198  						Name: "a",
  2199  						Expr: &LiteralValueExpr{
  2200  							SrcRange: hcl.Range{
  2201  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  2202  								End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2203  							},
  2204  						},
  2205  						NameRange: hcl.Range{
  2206  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2207  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2208  						},
  2209  						EqualsRange: hcl.Range{
  2210  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  2211  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  2212  						},
  2213  						SrcRange: hcl.Range{
  2214  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2215  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  2216  						},
  2217  					},
  2218  				},
  2219  				Blocks: Blocks{},
  2220  				SrcRange: hcl.Range{
  2221  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2222  					End:   hcl.Pos{Line: 1, Column: 10, Byte: 9},
  2223  				},
  2224  				EndRange: hcl.Range{
  2225  					Start: hcl.Pos{Line: 1, Column: 10, Byte: 9},
  2226  					End:   hcl.Pos{Line: 1, Column: 10, Byte: 9},
  2227  				},
  2228  			},
  2229  		},
  2230  		{
  2231  			`a = 'str'`,
  2232  			2, // Invalid character and expression
  2233  			&Body{
  2234  				Attributes: Attributes{
  2235  					"a": {
  2236  						Name: "a",
  2237  						Expr: &LiteralValueExpr{
  2238  							SrcRange: hcl.Range{
  2239  								Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
  2240  								End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2241  							},
  2242  						},
  2243  						NameRange: hcl.Range{
  2244  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2245  							End:   hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2246  						},
  2247  						EqualsRange: hcl.Range{
  2248  							Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
  2249  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  2250  						},
  2251  						SrcRange: hcl.Range{
  2252  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2253  							End:   hcl.Pos{Line: 1, Column: 4, Byte: 3},
  2254  						},
  2255  					},
  2256  				},
  2257  				Blocks: Blocks{},
  2258  				SrcRange: hcl.Range{
  2259  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2260  					End:   hcl.Pos{Line: 1, Column: 10, Byte: 9},
  2261  				},
  2262  				EndRange: hcl.Range{
  2263  					Start: hcl.Pos{Line: 1, Column: 10, Byte: 9},
  2264  					End:   hcl.Pos{Line: 1, Column: 10, Byte: 9},
  2265  				},
  2266  			},
  2267  		},
  2268  		{
  2269  			"a = sort(data.first.ref.attr)[count.index]\n",
  2270  			0,
  2271  			&Body{
  2272  				Attributes: Attributes{
  2273  					"a": {
  2274  						Name: "a",
  2275  						Expr: &IndexExpr{
  2276  							Collection: &FunctionCallExpr{
  2277  								Name: "sort",
  2278  								Args: []Expression{
  2279  									&ScopeTraversalExpr{
  2280  										Traversal: hcl.Traversal{
  2281  											hcl.TraverseRoot{
  2282  												Name: "data",
  2283  												SrcRange: hcl.Range{
  2284  													Filename: "",
  2285  													Start:    hcl.Pos{Line: 1, Column: 10, Byte: 9},
  2286  													End:      hcl.Pos{Line: 1, Column: 14, Byte: 13},
  2287  												},
  2288  											},
  2289  											hcl.TraverseAttr{
  2290  												Name: "first",
  2291  												SrcRange: hcl.Range{
  2292  													Filename: "",
  2293  													Start:    hcl.Pos{Line: 1, Column: 14, Byte: 13},
  2294  													End:      hcl.Pos{Line: 1, Column: 20, Byte: 19},
  2295  												},
  2296  											},
  2297  											hcl.TraverseAttr{
  2298  												Name: "ref",
  2299  												SrcRange: hcl.Range{
  2300  													Filename: "",
  2301  													Start:    hcl.Pos{Line: 1, Column: 20, Byte: 19},
  2302  													End:      hcl.Pos{Line: 1, Column: 24, Byte: 23},
  2303  												},
  2304  											},
  2305  											hcl.TraverseAttr{
  2306  												Name: "attr",
  2307  												SrcRange: hcl.Range{
  2308  													Filename: "",
  2309  													Start:    hcl.Pos{Line: 1, Column: 24, Byte: 23},
  2310  													End:      hcl.Pos{Line: 1, Column: 29, Byte: 28},
  2311  												},
  2312  											},
  2313  										},
  2314  										SrcRange: hcl.Range{
  2315  											Filename: "",
  2316  											Start:    hcl.Pos{Line: 1, Column: 10, Byte: 9},
  2317  											End:      hcl.Pos{Line: 1, Column: 29, Byte: 28},
  2318  										},
  2319  									},
  2320  								},
  2321  								ExpandFinal: false,
  2322  								NameRange: hcl.Range{
  2323  									Filename: "",
  2324  									Start:    hcl.Pos{Line: 1, Column: 5, Byte: 4},
  2325  									End:      hcl.Pos{Line: 1, Column: 9, Byte: 8},
  2326  								},
  2327  								OpenParenRange: hcl.Range{
  2328  									Filename: "",
  2329  									Start:    hcl.Pos{Line: 1, Column: 9, Byte: 8},
  2330  									End:      hcl.Pos{Line: 1, Column: 10, Byte: 9},
  2331  								},
  2332  								CloseParenRange: hcl.Range{
  2333  									Filename: "",
  2334  									Start:    hcl.Pos{Line: 1, Column: 29, Byte: 28},
  2335  									End:      hcl.Pos{Line: 1, Column: 30, Byte: 29},
  2336  								},
  2337  							},
  2338  							Key: &ScopeTraversalExpr{
  2339  								Traversal: hcl.Traversal{
  2340  									hcl.TraverseRoot{
  2341  										Name: "count",
  2342  										SrcRange: hcl.Range{
  2343  											Filename: "",
  2344  											Start:    hcl.Pos{Line: 1, Column: 31, Byte: 30},
  2345  											End:      hcl.Pos{Line: 1, Column: 36, Byte: 35},
  2346  										},
  2347  									},
  2348  									hcl.TraverseAttr{
  2349  										Name: "index",
  2350  										SrcRange: hcl.Range{
  2351  											Filename: "",
  2352  											Start:    hcl.Pos{Line: 1, Column: 36, Byte: 35},
  2353  											End:      hcl.Pos{Line: 1, Column: 42, Byte: 41},
  2354  										},
  2355  									},
  2356  								},
  2357  								SrcRange: hcl.Range{
  2358  									Filename: "",
  2359  									Start:    hcl.Pos{Line: 1, Column: 31, Byte: 30},
  2360  									End:      hcl.Pos{Line: 1, Column: 42, Byte: 41},
  2361  								},
  2362  							},
  2363  							SrcRange: hcl.Range{
  2364  								Filename: "",
  2365  								Start:    hcl.Pos{Line: 1, Column: 5, Byte: 4},
  2366  								End:      hcl.Pos{Line: 1, Column: 43, Byte: 42},
  2367  							},
  2368  							OpenRange: hcl.Range{
  2369  								Filename: "",
  2370  								Start:    hcl.Pos{Line: 1, Column: 30, Byte: 29},
  2371  								End:      hcl.Pos{Line: 1, Column: 31, Byte: 30},
  2372  							},
  2373  							BracketRange: hcl.Range{
  2374  								Filename: "",
  2375  								Start:    hcl.Pos{Line: 1, Column: 30, Byte: 29},
  2376  								End:      hcl.Pos{Line: 1, Column: 43, Byte: 42},
  2377  							},
  2378  						},
  2379  						SrcRange: hcl.Range{
  2380  							Filename: "",
  2381  							Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2382  							End:      hcl.Pos{Line: 1, Column: 43, Byte: 42},
  2383  						},
  2384  						NameRange: hcl.Range{
  2385  							Filename: "",
  2386  							Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2387  							End:      hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2388  						},
  2389  						EqualsRange: hcl.Range{
  2390  							Filename: "",
  2391  							Start:    hcl.Pos{Line: 1, Column: 3, Byte: 2},
  2392  							End:      hcl.Pos{Line: 1, Column: 4, Byte: 3},
  2393  						},
  2394  					},
  2395  				},
  2396  				Blocks: Blocks{},
  2397  				SrcRange: hcl.Range{
  2398  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2399  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 43},
  2400  				},
  2401  				EndRange: hcl.Range{
  2402  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 43},
  2403  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 43},
  2404  				},
  2405  			},
  2406  		},
  2407  		{
  2408  			`block "unterminated_string "name" {}`,
  2409  			2, // "Invalid string literal" and "Invalid block definition"
  2410  			&Body{
  2411  				Attributes: Attributes{},
  2412  				Blocks: Blocks{
  2413  					&Block{
  2414  						Type:   "block",
  2415  						Labels: []string{"unterminated_string ", "name", " {}"},
  2416  						Body: &Body{
  2417  							SrcRange: hcl.Range{
  2418  								Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2419  								End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2420  							},
  2421  							EndRange: hcl.Range{
  2422  								Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2423  								End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2424  							},
  2425  						},
  2426  
  2427  						TypeRange: hcl.Range{
  2428  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2429  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2430  						},
  2431  						LabelRanges: []hcl.Range{
  2432  							{
  2433  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  2434  								End:   hcl.Pos{Line: 1, Column: 29, Byte: 28},
  2435  							},
  2436  							{
  2437  								Start: hcl.Pos{Line: 1, Column: 29, Byte: 28},
  2438  								End:   hcl.Pos{Line: 1, Column: 33, Byte: 32},
  2439  							},
  2440  							{
  2441  								Start: hcl.Pos{Line: 1, Column: 33, Byte: 32},
  2442  								End:   hcl.Pos{Line: 1, Column: 37, Byte: 36},
  2443  							},
  2444  						},
  2445  						OpenBraceRange: hcl.Range{
  2446  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2447  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2448  						},
  2449  						CloseBraceRange: hcl.Range{
  2450  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2451  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2452  						},
  2453  					},
  2454  				},
  2455  				SrcRange: hcl.Range{
  2456  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2457  					End:   hcl.Pos{Line: 1, Column: 37, Byte: 36},
  2458  				},
  2459  				EndRange: hcl.Range{
  2460  					Start: hcl.Pos{Line: 1, Column: 37, Byte: 36},
  2461  					End:   hcl.Pos{Line: 1, Column: 37, Byte: 36},
  2462  				},
  2463  			},
  2464  		},
  2465  		{
  2466  			"a = a::namespaced::func(data.first.ref.attr)\n",
  2467  			0,
  2468  			&Body{
  2469  				Attributes: Attributes{
  2470  					"a": {
  2471  						Name: "a",
  2472  						Expr: &FunctionCallExpr{
  2473  							Name: "a::namespaced::func",
  2474  							Args: []Expression{
  2475  								&ScopeTraversalExpr{
  2476  									Traversal: hcl.Traversal{
  2477  										hcl.TraverseRoot{
  2478  											Name: "data",
  2479  											SrcRange: hcl.Range{
  2480  												Filename: "",
  2481  												Start:    hcl.Pos{Line: 1, Column: 25, Byte: 24},
  2482  												End:      hcl.Pos{Line: 1, Column: 29, Byte: 28},
  2483  											},
  2484  										},
  2485  										hcl.TraverseAttr{
  2486  											Name: "first",
  2487  											SrcRange: hcl.Range{
  2488  												Filename: "",
  2489  												Start:    hcl.Pos{Line: 1, Column: 29, Byte: 28},
  2490  												End:      hcl.Pos{Line: 1, Column: 35, Byte: 34},
  2491  											},
  2492  										},
  2493  										hcl.TraverseAttr{
  2494  											Name: "ref",
  2495  											SrcRange: hcl.Range{
  2496  												Filename: "",
  2497  												Start:    hcl.Pos{Line: 1, Column: 35, Byte: 34},
  2498  												End:      hcl.Pos{Line: 1, Column: 39, Byte: 38},
  2499  											},
  2500  										},
  2501  										hcl.TraverseAttr{
  2502  											Name: "attr",
  2503  											SrcRange: hcl.Range{
  2504  												Filename: "",
  2505  												Start:    hcl.Pos{Line: 1, Column: 39, Byte: 38},
  2506  												End:      hcl.Pos{Line: 1, Column: 44, Byte: 43},
  2507  											},
  2508  										},
  2509  									},
  2510  									SrcRange: hcl.Range{
  2511  										Filename: "",
  2512  										Start:    hcl.Pos{Line: 1, Column: 25, Byte: 24},
  2513  										End:      hcl.Pos{Line: 1, Column: 44, Byte: 43},
  2514  									},
  2515  								},
  2516  							},
  2517  							ExpandFinal: false,
  2518  							NameRange: hcl.Range{
  2519  								Filename: "",
  2520  								Start:    hcl.Pos{Line: 1, Column: 5, Byte: 4},
  2521  								End:      hcl.Pos{Line: 1, Column: 24, Byte: 23},
  2522  							},
  2523  							OpenParenRange: hcl.Range{
  2524  								Filename: "",
  2525  								Start:    hcl.Pos{Line: 1, Column: 24, Byte: 23},
  2526  								End:      hcl.Pos{Line: 1, Column: 25, Byte: 24},
  2527  							},
  2528  							CloseParenRange: hcl.Range{
  2529  								Filename: "",
  2530  								Start:    hcl.Pos{Line: 1, Column: 44, Byte: 43},
  2531  								End:      hcl.Pos{Line: 1, Column: 45, Byte: 44},
  2532  							},
  2533  						},
  2534  						SrcRange: hcl.Range{
  2535  							Filename: "",
  2536  							Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2537  							End:      hcl.Pos{Line: 1, Column: 45, Byte: 44},
  2538  						},
  2539  						NameRange: hcl.Range{
  2540  							Filename: "",
  2541  							Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2542  							End:      hcl.Pos{Line: 1, Column: 2, Byte: 1},
  2543  						},
  2544  						EqualsRange: hcl.Range{
  2545  							Filename: "",
  2546  							Start:    hcl.Pos{Line: 1, Column: 3, Byte: 2},
  2547  							End:      hcl.Pos{Line: 1, Column: 4, Byte: 3},
  2548  						},
  2549  					},
  2550  				},
  2551  				Blocks: Blocks{},
  2552  				SrcRange: hcl.Range{
  2553  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2554  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 45},
  2555  				},
  2556  				EndRange: hcl.Range{
  2557  					Start: hcl.Pos{Line: 2, Column: 1, Byte: 45},
  2558  					End:   hcl.Pos{Line: 2, Column: 1, Byte: 45},
  2559  				},
  2560  			},
  2561  		},
  2562  	}
  2563  
  2564  	for _, test := range tests {
  2565  		t.Run(test.input, func(t *testing.T) {
  2566  			t.Logf("\n%s", test.input)
  2567  			file, diags := ParseConfig([]byte(test.input), "", hcl.Pos{Byte: 0, Line: 1, Column: 1})
  2568  			if len(diags) != test.diagCount {
  2569  				t.Errorf("wrong number of diagnostics %d; want %d", len(diags), test.diagCount)
  2570  				for _, diag := range diags {
  2571  					t.Logf(" - %s", diag.Error())
  2572  				}
  2573  			}
  2574  
  2575  			got := file.Body
  2576  
  2577  			if diff := deep.Equal(got, test.want); diff != nil {
  2578  				for _, problem := range diff {
  2579  					t.Errorf(problem)
  2580  				}
  2581  			}
  2582  		})
  2583  	}
  2584  }
  2585  
  2586  func TestParseConfig_incompleteFunctionCall(t *testing.T) {
  2587  	tests := []struct {
  2588  		input string
  2589  		want  *Body
  2590  	}{
  2591  		{
  2592  			`attr = object({ foo = })
  2593  attr2 = "foo"
  2594  `,
  2595  			&Body{
  2596  				Attributes: Attributes{
  2597  					"attr": {
  2598  						Name: "attr",
  2599  						Expr: &FunctionCallExpr{
  2600  							Name: "object",
  2601  							Args: []Expression{
  2602  								&ObjectConsExpr{
  2603  									SrcRange: hcl.Range{
  2604  										Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  2605  										End:   hcl.Pos{Line: 1, Column: 24, Byte: 23},
  2606  									},
  2607  									OpenRange: hcl.Range{
  2608  										Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  2609  										End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  2610  									},
  2611  								},
  2612  							},
  2613  							NameRange: hcl.Range{
  2614  								Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
  2615  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  2616  							},
  2617  							OpenParenRange: hcl.Range{
  2618  								Start: hcl.Pos{Line: 1, Column: 14, Byte: 13},
  2619  								End:   hcl.Pos{Line: 1, Column: 15, Byte: 14},
  2620  							},
  2621  							CloseParenRange: hcl.Range{
  2622  								Start: hcl.Pos{Line: 1, Column: 24, Byte: 23},
  2623  								End:   hcl.Pos{Line: 1, Column: 25, Byte: 24},
  2624  							},
  2625  						},
  2626  						SrcRange: hcl.Range{
  2627  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2628  							End:   hcl.Pos{Line: 1, Column: 25, Byte: 24},
  2629  						},
  2630  						NameRange: hcl.Range{
  2631  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2632  							End:   hcl.Pos{Line: 1, Column: 5, Byte: 4},
  2633  						},
  2634  						EqualsRange: hcl.Range{
  2635  							Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2636  							End:   hcl.Pos{Line: 1, Column: 7, Byte: 6},
  2637  						},
  2638  					},
  2639  					"attr2": {
  2640  						Name: "attr2",
  2641  						Expr: &TemplateExpr{
  2642  							Parts: []Expression{
  2643  								&LiteralValueExpr{
  2644  									Val: cty.StringVal("foo"),
  2645  									SrcRange: hcl.Range{
  2646  										Start: hcl.Pos{Line: 2, Column: 10, Byte: 34},
  2647  										End:   hcl.Pos{Line: 2, Column: 13, Byte: 37},
  2648  									},
  2649  								},
  2650  							},
  2651  							SrcRange: hcl.Range{
  2652  								Start: hcl.Pos{Line: 2, Column: 9, Byte: 33},
  2653  								End:   hcl.Pos{Line: 2, Column: 14, Byte: 38},
  2654  							},
  2655  						},
  2656  						SrcRange: hcl.Range{
  2657  							Start: hcl.Pos{Line: 2, Column: 1, Byte: 25},
  2658  							End:   hcl.Pos{Line: 2, Column: 14, Byte: 38},
  2659  						},
  2660  						NameRange: hcl.Range{
  2661  							Start: hcl.Pos{Line: 2, Column: 1, Byte: 25},
  2662  							End:   hcl.Pos{Line: 2, Column: 6, Byte: 30},
  2663  						},
  2664  						EqualsRange: hcl.Range{
  2665  							Start: hcl.Pos{Line: 2, Column: 7, Byte: 31},
  2666  							End:   hcl.Pos{Line: 2, Column: 8, Byte: 32},
  2667  						},
  2668  					},
  2669  				},
  2670  				Blocks: Blocks{},
  2671  				SrcRange: hcl.Range{
  2672  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2673  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 39},
  2674  				},
  2675  				EndRange: hcl.Range{
  2676  					Start: hcl.Pos{Line: 3, Column: 1, Byte: 39},
  2677  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 39},
  2678  				},
  2679  			},
  2680  		},
  2681  		{
  2682  			`block "label" {
  2683    attr = object(
  2684  `,
  2685  			&Body{
  2686  				Attributes: Attributes{},
  2687  				Blocks: Blocks{
  2688  					{
  2689  						Type:   "block",
  2690  						Labels: []string{"label"},
  2691  						Body: &Body{
  2692  							Attributes: Attributes{
  2693  								"attr": {
  2694  									Name: "attr",
  2695  									Expr: &FunctionCallExpr{
  2696  										Name: "object",
  2697  										Args: []Expression{
  2698  											&LiteralValueExpr{
  2699  												Val: cty.DynamicVal,
  2700  												SrcRange: hcl.Range{
  2701  													Start: hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2702  													End:   hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2703  												},
  2704  											},
  2705  										},
  2706  										NameRange: hcl.Range{
  2707  											Start: hcl.Pos{Line: 2, Column: 10, Byte: 25},
  2708  											End:   hcl.Pos{Line: 2, Column: 16, Byte: 31},
  2709  										},
  2710  										OpenParenRange: hcl.Range{
  2711  											Start: hcl.Pos{Line: 2, Column: 16, Byte: 31},
  2712  											End:   hcl.Pos{Line: 2, Column: 17, Byte: 32},
  2713  										},
  2714  										CloseParenRange: hcl.Range{},
  2715  									},
  2716  									SrcRange: hcl.Range{
  2717  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  2718  										End:   hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2719  									},
  2720  									NameRange: hcl.Range{
  2721  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  2722  										End:   hcl.Pos{Line: 2, Column: 7, Byte: 22},
  2723  									},
  2724  									EqualsRange: hcl.Range{
  2725  										Start: hcl.Pos{Line: 2, Column: 8, Byte: 23},
  2726  										End:   hcl.Pos{Line: 2, Column: 9, Byte: 24},
  2727  									},
  2728  								},
  2729  							},
  2730  							Blocks: Blocks{},
  2731  							SrcRange: hcl.Range{
  2732  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  2733  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2734  							},
  2735  							EndRange: hcl.Range{
  2736  								Start: hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2737  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2738  							},
  2739  						},
  2740  						TypeRange: hcl.Range{
  2741  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2742  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2743  						},
  2744  						LabelRanges: []hcl.Range{
  2745  							{
  2746  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  2747  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  2748  							},
  2749  						},
  2750  						OpenBraceRange: hcl.Range{
  2751  							Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  2752  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  2753  						},
  2754  						CloseBraceRange: hcl.Range{
  2755  							Start: hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2756  							End:   hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2757  						},
  2758  					},
  2759  				},
  2760  				SrcRange: hcl.Range{
  2761  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2762  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2763  				},
  2764  				EndRange: hcl.Range{
  2765  					Start: hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2766  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 33},
  2767  				},
  2768  			},
  2769  		},
  2770  		{
  2771  			`block "label" {
  2772  		  attr = object({
  2773  `,
  2774  			&Body{
  2775  				Attributes: Attributes{},
  2776  				Blocks: Blocks{
  2777  					{
  2778  						Type:   "block",
  2779  						Labels: []string{"label"},
  2780  						Body: &Body{
  2781  							Attributes: Attributes{
  2782  								"attr": {
  2783  									Name: "attr",
  2784  									Expr: &FunctionCallExpr{
  2785  										Name: "object",
  2786  										Args: []Expression{
  2787  											&ObjectConsExpr{
  2788  												SrcRange: hcl.Range{
  2789  													Start: hcl.Pos{Line: 2, Column: 19, Byte: 34},
  2790  													End:   hcl.Pos{Line: 3, Column: 1, Byte: 36},
  2791  												},
  2792  												OpenRange: hcl.Range{
  2793  													Start: hcl.Pos{Line: 2, Column: 19, Byte: 34},
  2794  													End:   hcl.Pos{Line: 2, Column: 20, Byte: 35},
  2795  												},
  2796  											},
  2797  										},
  2798  										NameRange: hcl.Range{
  2799  											Start: hcl.Pos{Line: 2, Column: 12, Byte: 27},
  2800  											End:   hcl.Pos{Line: 2, Column: 18, Byte: 33},
  2801  										},
  2802  										OpenParenRange: hcl.Range{
  2803  											Start: hcl.Pos{Line: 2, Column: 18, Byte: 33},
  2804  											End:   hcl.Pos{Line: 2, Column: 19, Byte: 34},
  2805  										},
  2806  										CloseParenRange: hcl.Range{},
  2807  									},
  2808  									SrcRange: hcl.Range{
  2809  										Start: hcl.Pos{Line: 2, Column: 5, Byte: 20},
  2810  										End:   hcl.Pos{Line: 3, Column: 1, Byte: 36},
  2811  									},
  2812  									NameRange: hcl.Range{
  2813  										Start: hcl.Pos{Line: 2, Column: 5, Byte: 20},
  2814  										End:   hcl.Pos{Line: 2, Column: 9, Byte: 24},
  2815  									},
  2816  									EqualsRange: hcl.Range{
  2817  										Start: hcl.Pos{Line: 2, Column: 10, Byte: 25},
  2818  										End:   hcl.Pos{Line: 2, Column: 11, Byte: 26},
  2819  									},
  2820  								},
  2821  							},
  2822  							Blocks: Blocks{},
  2823  							SrcRange: hcl.Range{
  2824  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  2825  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 36},
  2826  							},
  2827  							EndRange: hcl.Range{
  2828  								Start: hcl.Pos{Line: 3, Column: 1, Byte: 36},
  2829  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 36},
  2830  							},
  2831  						},
  2832  						TypeRange: hcl.Range{
  2833  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2834  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2835  						},
  2836  						LabelRanges: []hcl.Range{
  2837  							{
  2838  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  2839  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  2840  							},
  2841  						},
  2842  						OpenBraceRange: hcl.Range{
  2843  							Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  2844  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  2845  						},
  2846  						CloseBraceRange: hcl.Range{
  2847  							Start: hcl.Pos{Line: 3, Column: 1, Byte: 36},
  2848  							End:   hcl.Pos{Line: 3, Column: 1, Byte: 36},
  2849  						},
  2850  					},
  2851  				},
  2852  				SrcRange: hcl.Range{
  2853  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2854  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 36},
  2855  				},
  2856  				EndRange: hcl.Range{
  2857  					Start: hcl.Pos{Line: 3, Column: 1, Byte: 36},
  2858  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 36},
  2859  				},
  2860  			},
  2861  		},
  2862  		{
  2863  			`block "label" {
  2864    attr = object({ foo
  2865  `,
  2866  			&Body{
  2867  				Attributes: Attributes{},
  2868  				Blocks: Blocks{
  2869  					{
  2870  						Type:   "block",
  2871  						Labels: []string{"label"},
  2872  						Body: &Body{
  2873  							Attributes: Attributes{
  2874  								"attr": {
  2875  									Name: "attr",
  2876  									Expr: &FunctionCallExpr{
  2877  										Name: "object",
  2878  										Args: []Expression{
  2879  											&ObjectConsExpr{
  2880  												SrcRange: hcl.Range{
  2881  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  2882  													End:   hcl.Pos{Line: 3, Column: 1, Byte: 38},
  2883  												},
  2884  												OpenRange: hcl.Range{
  2885  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  2886  													End:   hcl.Pos{Line: 2, Column: 18, Byte: 33},
  2887  												},
  2888  											},
  2889  										},
  2890  										NameRange: hcl.Range{
  2891  											Start: hcl.Pos{Line: 2, Column: 10, Byte: 25},
  2892  											End:   hcl.Pos{Line: 2, Column: 16, Byte: 31},
  2893  										},
  2894  										OpenParenRange: hcl.Range{
  2895  											Start: hcl.Pos{Line: 2, Column: 16, Byte: 31},
  2896  											End:   hcl.Pos{Line: 2, Column: 17, Byte: 32},
  2897  										},
  2898  										CloseParenRange: hcl.Range{},
  2899  									},
  2900  									SrcRange: hcl.Range{
  2901  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  2902  										End:   hcl.Pos{Line: 3, Column: 1, Byte: 38},
  2903  									},
  2904  									NameRange: hcl.Range{
  2905  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  2906  										End:   hcl.Pos{Line: 2, Column: 7, Byte: 22},
  2907  									},
  2908  									EqualsRange: hcl.Range{
  2909  										Start: hcl.Pos{Line: 2, Column: 8, Byte: 23},
  2910  										End:   hcl.Pos{Line: 2, Column: 9, Byte: 24},
  2911  									},
  2912  								},
  2913  							},
  2914  							Blocks: Blocks{},
  2915  							SrcRange: hcl.Range{
  2916  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  2917  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 38},
  2918  							},
  2919  							EndRange: hcl.Range{
  2920  								Start: hcl.Pos{Line: 3, Column: 1, Byte: 38},
  2921  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 38},
  2922  							},
  2923  						},
  2924  						TypeRange: hcl.Range{
  2925  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2926  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  2927  						},
  2928  						LabelRanges: []hcl.Range{
  2929  							{
  2930  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  2931  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  2932  							},
  2933  						},
  2934  						OpenBraceRange: hcl.Range{
  2935  							Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  2936  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  2937  						},
  2938  						CloseBraceRange: hcl.Range{
  2939  							Start: hcl.Pos{Line: 3, Column: 1, Byte: 38},
  2940  							End:   hcl.Pos{Line: 3, Column: 1, Byte: 38},
  2941  						},
  2942  					},
  2943  				},
  2944  				SrcRange: hcl.Range{
  2945  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  2946  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 38},
  2947  				},
  2948  				EndRange: hcl.Range{
  2949  					Start: hcl.Pos{Line: 3, Column: 1, Byte: 38},
  2950  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 38},
  2951  				},
  2952  			},
  2953  		},
  2954  		{
  2955  			`block "label" {
  2956    attr = object({ foo =
  2957  `,
  2958  			&Body{
  2959  				Attributes: Attributes{},
  2960  				Blocks: Blocks{
  2961  					{
  2962  						Type:   "block",
  2963  						Labels: []string{"label"},
  2964  						Body: &Body{
  2965  							Attributes: Attributes{
  2966  								"attr": {
  2967  									Name: "attr",
  2968  									Expr: &FunctionCallExpr{
  2969  										Name: "object",
  2970  										Args: []Expression{
  2971  											&ObjectConsExpr{
  2972  												SrcRange: hcl.Range{
  2973  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  2974  													End:   hcl.Pos{Line: 3, Column: 1, Byte: 40},
  2975  												},
  2976  												OpenRange: hcl.Range{
  2977  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  2978  													End:   hcl.Pos{Line: 2, Column: 18, Byte: 33},
  2979  												},
  2980  											},
  2981  										},
  2982  										NameRange: hcl.Range{
  2983  											Start: hcl.Pos{Line: 2, Column: 10, Byte: 25},
  2984  											End:   hcl.Pos{Line: 2, Column: 16, Byte: 31},
  2985  										},
  2986  										OpenParenRange: hcl.Range{
  2987  											Start: hcl.Pos{Line: 2, Column: 16, Byte: 31},
  2988  											End:   hcl.Pos{Line: 2, Column: 17, Byte: 32},
  2989  										},
  2990  										CloseParenRange: hcl.Range{},
  2991  									},
  2992  									SrcRange: hcl.Range{
  2993  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  2994  										End:   hcl.Pos{Line: 3, Column: 1, Byte: 40},
  2995  									},
  2996  									NameRange: hcl.Range{
  2997  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  2998  										End:   hcl.Pos{Line: 2, Column: 7, Byte: 22},
  2999  									},
  3000  									EqualsRange: hcl.Range{
  3001  										Start: hcl.Pos{Line: 2, Column: 8, Byte: 23},
  3002  										End:   hcl.Pos{Line: 2, Column: 9, Byte: 24},
  3003  									},
  3004  								},
  3005  							},
  3006  							Blocks: Blocks{},
  3007  							SrcRange: hcl.Range{
  3008  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3009  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 40},
  3010  							},
  3011  							EndRange: hcl.Range{
  3012  								Start: hcl.Pos{Line: 3, Column: 1, Byte: 40},
  3013  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 40},
  3014  							},
  3015  						},
  3016  						TypeRange: hcl.Range{
  3017  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3018  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3019  						},
  3020  						LabelRanges: []hcl.Range{
  3021  							{
  3022  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3023  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  3024  							},
  3025  						},
  3026  						OpenBraceRange: hcl.Range{
  3027  							Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3028  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  3029  						},
  3030  						CloseBraceRange: hcl.Range{
  3031  							Start: hcl.Pos{Line: 3, Column: 1, Byte: 40},
  3032  							End:   hcl.Pos{Line: 3, Column: 1, Byte: 40},
  3033  						},
  3034  					},
  3035  				},
  3036  				SrcRange: hcl.Range{
  3037  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3038  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 40},
  3039  				},
  3040  				EndRange: hcl.Range{
  3041  					Start: hcl.Pos{Line: 3, Column: 1, Byte: 40},
  3042  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 40},
  3043  				},
  3044  			},
  3045  		},
  3046  		{
  3047  			`block "label" {
  3048    attr = object({ foo = }
  3049  `,
  3050  			&Body{
  3051  				Attributes: Attributes{},
  3052  				Blocks: Blocks{
  3053  					{
  3054  						Type:   "block",
  3055  						Labels: []string{"label"},
  3056  						Body: &Body{
  3057  							Attributes: Attributes{
  3058  								"attr": {
  3059  									Name: "attr",
  3060  									Expr: &FunctionCallExpr{
  3061  										Name: "object",
  3062  										Args: []Expression{
  3063  											&ObjectConsExpr{
  3064  												SrcRange: hcl.Range{
  3065  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3066  													End:   hcl.Pos{Line: 2, Column: 26, Byte: 41},
  3067  												},
  3068  												OpenRange: hcl.Range{
  3069  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3070  													End:   hcl.Pos{Line: 2, Column: 18, Byte: 33},
  3071  												},
  3072  											},
  3073  										},
  3074  										NameRange: hcl.Range{
  3075  											Start: hcl.Pos{Line: 2, Column: 10, Byte: 25},
  3076  											End:   hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3077  										},
  3078  										OpenParenRange: hcl.Range{
  3079  											Start: hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3080  											End:   hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3081  										},
  3082  										CloseParenRange: hcl.Range{},
  3083  									},
  3084  									SrcRange: hcl.Range{
  3085  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3086  										End:   hcl.Pos{Line: 3, Column: 1, Byte: 42},
  3087  									},
  3088  									NameRange: hcl.Range{
  3089  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3090  										End:   hcl.Pos{Line: 2, Column: 7, Byte: 22},
  3091  									},
  3092  									EqualsRange: hcl.Range{
  3093  										Start: hcl.Pos{Line: 2, Column: 8, Byte: 23},
  3094  										End:   hcl.Pos{Line: 2, Column: 9, Byte: 24},
  3095  									},
  3096  								},
  3097  							},
  3098  							Blocks: Blocks{},
  3099  							SrcRange: hcl.Range{
  3100  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3101  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 42},
  3102  							},
  3103  							EndRange: hcl.Range{
  3104  								Start: hcl.Pos{Line: 3, Column: 1, Byte: 42},
  3105  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 42},
  3106  							},
  3107  						},
  3108  						TypeRange: hcl.Range{
  3109  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3110  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3111  						},
  3112  						LabelRanges: []hcl.Range{
  3113  							{
  3114  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3115  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  3116  							},
  3117  						},
  3118  						OpenBraceRange: hcl.Range{
  3119  							Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3120  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  3121  						},
  3122  						CloseBraceRange: hcl.Range{
  3123  							Start: hcl.Pos{Line: 3, Column: 1, Byte: 42},
  3124  							End:   hcl.Pos{Line: 3, Column: 1, Byte: 42},
  3125  						},
  3126  					},
  3127  				},
  3128  				SrcRange: hcl.Range{
  3129  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3130  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 42},
  3131  				},
  3132  				EndRange: hcl.Range{
  3133  					Start: hcl.Pos{Line: 3, Column: 1, Byte: 42},
  3134  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 42},
  3135  				},
  3136  			},
  3137  		},
  3138  		{
  3139  			`block "label" {
  3140    attr = object({ foo = })
  3141  `,
  3142  			&Body{
  3143  				Attributes: Attributes{},
  3144  				Blocks: Blocks{
  3145  					{
  3146  						Type:   "block",
  3147  						Labels: []string{"label"},
  3148  						Body: &Body{
  3149  							Attributes: Attributes{
  3150  								"attr": {
  3151  									Name: "attr",
  3152  									Expr: &FunctionCallExpr{
  3153  										Name: "object",
  3154  										Args: []Expression{
  3155  											&ObjectConsExpr{
  3156  												SrcRange: hcl.Range{
  3157  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3158  													End:   hcl.Pos{Line: 2, Column: 26, Byte: 41},
  3159  												},
  3160  												OpenRange: hcl.Range{
  3161  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3162  													End:   hcl.Pos{Line: 2, Column: 18, Byte: 33},
  3163  												},
  3164  											},
  3165  										},
  3166  										NameRange: hcl.Range{
  3167  											Start: hcl.Pos{Line: 2, Column: 10, Byte: 25},
  3168  											End:   hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3169  										},
  3170  										OpenParenRange: hcl.Range{
  3171  											Start: hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3172  											End:   hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3173  										},
  3174  										CloseParenRange: hcl.Range{
  3175  											Start: hcl.Pos{Line: 2, Column: 26, Byte: 41},
  3176  											End:   hcl.Pos{Line: 2, Column: 27, Byte: 42},
  3177  										},
  3178  									},
  3179  									SrcRange: hcl.Range{
  3180  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3181  										End:   hcl.Pos{Line: 2, Column: 27, Byte: 42},
  3182  									},
  3183  									NameRange: hcl.Range{
  3184  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3185  										End:   hcl.Pos{Line: 2, Column: 7, Byte: 22},
  3186  									},
  3187  									EqualsRange: hcl.Range{
  3188  										Start: hcl.Pos{Line: 2, Column: 8, Byte: 23},
  3189  										End:   hcl.Pos{Line: 2, Column: 9, Byte: 24},
  3190  									},
  3191  								},
  3192  							},
  3193  							Blocks: Blocks{},
  3194  							SrcRange: hcl.Range{
  3195  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3196  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 43},
  3197  							},
  3198  							EndRange: hcl.Range{
  3199  								Start: hcl.Pos{Line: 3, Column: 1, Byte: 43},
  3200  								End:   hcl.Pos{Line: 3, Column: 1, Byte: 43},
  3201  							},
  3202  						},
  3203  						TypeRange: hcl.Range{
  3204  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3205  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3206  						},
  3207  						LabelRanges: []hcl.Range{
  3208  							{
  3209  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3210  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  3211  							},
  3212  						},
  3213  						OpenBraceRange: hcl.Range{
  3214  							Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3215  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  3216  						},
  3217  						CloseBraceRange: hcl.Range{
  3218  							Start: hcl.Pos{Line: 3, Column: 1, Byte: 43},
  3219  							End:   hcl.Pos{Line: 3, Column: 1, Byte: 43},
  3220  						},
  3221  					},
  3222  				},
  3223  				SrcRange: hcl.Range{
  3224  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3225  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 43},
  3226  				},
  3227  				EndRange: hcl.Range{
  3228  					Start: hcl.Pos{Line: 3, Column: 1, Byte: 43},
  3229  					End:   hcl.Pos{Line: 3, Column: 1, Byte: 43},
  3230  				},
  3231  			},
  3232  		},
  3233  		{
  3234  			`block "label" {
  3235    attr = object({
  3236      foo =
  3237  
  3238  `,
  3239  			&Body{
  3240  				Attributes: Attributes{},
  3241  				Blocks: Blocks{
  3242  					{
  3243  						Type:   "block",
  3244  						Labels: []string{"label"},
  3245  						Body: &Body{
  3246  							Attributes: Attributes{
  3247  								"attr": {
  3248  									Name: "attr",
  3249  									Expr: &FunctionCallExpr{
  3250  										Name: "object",
  3251  										Args: []Expression{
  3252  											&ObjectConsExpr{
  3253  												SrcRange: hcl.Range{
  3254  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3255  													End:   hcl.Pos{Line: 5, Column: 1, Byte: 45},
  3256  												},
  3257  												OpenRange: hcl.Range{
  3258  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3259  													End:   hcl.Pos{Line: 2, Column: 18, Byte: 33},
  3260  												},
  3261  											},
  3262  										},
  3263  										NameRange: hcl.Range{
  3264  											Start: hcl.Pos{Line: 2, Column: 10, Byte: 25},
  3265  											End:   hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3266  										},
  3267  										OpenParenRange: hcl.Range{
  3268  											Start: hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3269  											End:   hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3270  										},
  3271  										CloseParenRange: hcl.Range{},
  3272  									},
  3273  									SrcRange: hcl.Range{
  3274  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3275  										End:   hcl.Pos{Line: 5, Column: 1, Byte: 45},
  3276  									},
  3277  									NameRange: hcl.Range{
  3278  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3279  										End:   hcl.Pos{Line: 2, Column: 7, Byte: 22},
  3280  									},
  3281  									EqualsRange: hcl.Range{
  3282  										Start: hcl.Pos{Line: 2, Column: 8, Byte: 23},
  3283  										End:   hcl.Pos{Line: 2, Column: 9, Byte: 24},
  3284  									},
  3285  								},
  3286  							},
  3287  							Blocks: Blocks{},
  3288  							SrcRange: hcl.Range{
  3289  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3290  								End:   hcl.Pos{Line: 5, Column: 1, Byte: 45},
  3291  							},
  3292  							EndRange: hcl.Range{
  3293  								Start: hcl.Pos{Line: 5, Column: 1, Byte: 45},
  3294  								End:   hcl.Pos{Line: 5, Column: 1, Byte: 45},
  3295  							},
  3296  						},
  3297  						TypeRange: hcl.Range{
  3298  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3299  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3300  						},
  3301  						LabelRanges: []hcl.Range{
  3302  							{
  3303  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3304  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  3305  							},
  3306  						},
  3307  						OpenBraceRange: hcl.Range{
  3308  							Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3309  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  3310  						},
  3311  						CloseBraceRange: hcl.Range{
  3312  							Start: hcl.Pos{Line: 5, Column: 1, Byte: 45},
  3313  							End:   hcl.Pos{Line: 5, Column: 1, Byte: 45},
  3314  						},
  3315  					},
  3316  				},
  3317  				SrcRange: hcl.Range{
  3318  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3319  					End:   hcl.Pos{Line: 5, Column: 1, Byte: 45},
  3320  				},
  3321  				EndRange: hcl.Range{
  3322  					Start: hcl.Pos{Line: 5, Column: 1, Byte: 45},
  3323  					End:   hcl.Pos{Line: 5, Column: 1, Byte: 45},
  3324  				},
  3325  			},
  3326  		},
  3327  		{
  3328  			`block "label" {
  3329    attr = object({
  3330      foo =
  3331  
  3332  another_block {
  3333  
  3334  }
  3335  `,
  3336  			&Body{
  3337  				Attributes: Attributes{},
  3338  				Blocks: Blocks{
  3339  					{
  3340  						Type:   "block",
  3341  						Labels: []string{"label"},
  3342  						Body: &Body{
  3343  							Attributes: Attributes{
  3344  								"attr": {
  3345  									Name: "attr",
  3346  									Expr: &FunctionCallExpr{
  3347  										Name: "object",
  3348  										Args: []Expression{
  3349  											&ObjectConsExpr{
  3350  												SrcRange: hcl.Range{
  3351  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3352  													End:   hcl.Pos{Line: 8, Column: 1, Byte: 64},
  3353  												},
  3354  												OpenRange: hcl.Range{
  3355  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3356  													End:   hcl.Pos{Line: 2, Column: 18, Byte: 33},
  3357  												},
  3358  											},
  3359  										},
  3360  										NameRange: hcl.Range{
  3361  											Start: hcl.Pos{Line: 2, Column: 10, Byte: 25},
  3362  											End:   hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3363  										},
  3364  										OpenParenRange: hcl.Range{
  3365  											Start: hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3366  											End:   hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3367  										},
  3368  										CloseParenRange: hcl.Range{},
  3369  									},
  3370  									SrcRange: hcl.Range{
  3371  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3372  										End:   hcl.Pos{Line: 8, Column: 1, Byte: 64},
  3373  									},
  3374  									NameRange: hcl.Range{
  3375  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3376  										End:   hcl.Pos{Line: 2, Column: 7, Byte: 22},
  3377  									},
  3378  									EqualsRange: hcl.Range{
  3379  										Start: hcl.Pos{Line: 2, Column: 8, Byte: 23},
  3380  										End:   hcl.Pos{Line: 2, Column: 9, Byte: 24},
  3381  									},
  3382  								},
  3383  							},
  3384  							Blocks: Blocks{},
  3385  							SrcRange: hcl.Range{
  3386  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3387  								End:   hcl.Pos{Line: 8, Column: 1, Byte: 64},
  3388  							},
  3389  							EndRange: hcl.Range{
  3390  								Start: hcl.Pos{Line: 8, Column: 1, Byte: 64},
  3391  								End:   hcl.Pos{Line: 8, Column: 1, Byte: 64},
  3392  							},
  3393  						},
  3394  						TypeRange: hcl.Range{
  3395  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3396  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3397  						},
  3398  						LabelRanges: []hcl.Range{
  3399  							{
  3400  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3401  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  3402  							},
  3403  						},
  3404  						OpenBraceRange: hcl.Range{
  3405  							Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3406  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  3407  						},
  3408  						CloseBraceRange: hcl.Range{
  3409  							Start: hcl.Pos{Line: 8, Column: 1, Byte: 64},
  3410  							End:   hcl.Pos{Line: 8, Column: 1, Byte: 64},
  3411  						},
  3412  					},
  3413  				},
  3414  				SrcRange: hcl.Range{
  3415  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3416  					End:   hcl.Pos{Line: 8, Column: 1, Byte: 64},
  3417  				},
  3418  				EndRange: hcl.Range{
  3419  					Start: hcl.Pos{Line: 8, Column: 1, Byte: 64},
  3420  					End:   hcl.Pos{Line: 8, Column: 1, Byte: 64},
  3421  				},
  3422  			},
  3423  		},
  3424  		{
  3425  			`block "label" {
  3426    attr = object({
  3427      foo =
  3428    }
  3429  `,
  3430  			&Body{
  3431  				Attributes: Attributes{},
  3432  				Blocks: Blocks{
  3433  					{
  3434  						Type:   "block",
  3435  						Labels: []string{"label"},
  3436  						Body: &Body{
  3437  							Attributes: Attributes{
  3438  								"attr": {
  3439  									Name: "attr",
  3440  									Expr: &FunctionCallExpr{
  3441  										Name: "object",
  3442  										Args: []Expression{
  3443  											&ObjectConsExpr{
  3444  												SrcRange: hcl.Range{
  3445  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3446  													End:   hcl.Pos{Line: 4, Column: 4, Byte: 47},
  3447  												},
  3448  												OpenRange: hcl.Range{
  3449  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3450  													End:   hcl.Pos{Line: 2, Column: 18, Byte: 33},
  3451  												},
  3452  											},
  3453  										},
  3454  										NameRange: hcl.Range{
  3455  											Start: hcl.Pos{Line: 2, Column: 10, Byte: 25},
  3456  											End:   hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3457  										},
  3458  										OpenParenRange: hcl.Range{
  3459  											Start: hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3460  											End:   hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3461  										},
  3462  										CloseParenRange: hcl.Range{},
  3463  									},
  3464  									SrcRange: hcl.Range{
  3465  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3466  										End:   hcl.Pos{Line: 5, Column: 1, Byte: 48},
  3467  									},
  3468  									NameRange: hcl.Range{
  3469  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3470  										End:   hcl.Pos{Line: 2, Column: 7, Byte: 22},
  3471  									},
  3472  									EqualsRange: hcl.Range{
  3473  										Start: hcl.Pos{Line: 2, Column: 8, Byte: 23},
  3474  										End:   hcl.Pos{Line: 2, Column: 9, Byte: 24},
  3475  									},
  3476  								},
  3477  							},
  3478  							Blocks: Blocks{},
  3479  							SrcRange: hcl.Range{
  3480  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3481  								End:   hcl.Pos{Line: 5, Column: 1, Byte: 48},
  3482  							},
  3483  							EndRange: hcl.Range{
  3484  								Start: hcl.Pos{Line: 5, Column: 1, Byte: 48},
  3485  								End:   hcl.Pos{Line: 5, Column: 1, Byte: 48},
  3486  							},
  3487  						},
  3488  						TypeRange: hcl.Range{
  3489  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3490  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3491  						},
  3492  						LabelRanges: []hcl.Range{
  3493  							{
  3494  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3495  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  3496  							},
  3497  						},
  3498  						OpenBraceRange: hcl.Range{
  3499  							Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3500  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  3501  						},
  3502  						CloseBraceRange: hcl.Range{
  3503  							Start: hcl.Pos{Line: 5, Column: 1, Byte: 48},
  3504  							End:   hcl.Pos{Line: 5, Column: 1, Byte: 48},
  3505  						},
  3506  					},
  3507  				},
  3508  				SrcRange: hcl.Range{
  3509  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3510  					End:   hcl.Pos{Line: 5, Column: 1, Byte: 48},
  3511  				},
  3512  				EndRange: hcl.Range{
  3513  					Start: hcl.Pos{Line: 5, Column: 1, Byte: 48},
  3514  					End:   hcl.Pos{Line: 5, Column: 1, Byte: 48},
  3515  				},
  3516  			},
  3517  		},
  3518  		{
  3519  			`block "label" {
  3520    attr = object({
  3521      foo =
  3522    })
  3523  `,
  3524  			&Body{
  3525  				Attributes: Attributes{},
  3526  				Blocks: Blocks{
  3527  					{
  3528  						Type:   "block",
  3529  						Labels: []string{"label"},
  3530  						Body: &Body{
  3531  							Attributes: Attributes{
  3532  								"attr": {
  3533  									Name: "attr",
  3534  									Expr: &FunctionCallExpr{
  3535  										Name: "object",
  3536  										Args: []Expression{
  3537  											&ObjectConsExpr{
  3538  												SrcRange: hcl.Range{
  3539  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3540  													End:   hcl.Pos{Line: 4, Column: 4, Byte: 47},
  3541  												},
  3542  												OpenRange: hcl.Range{
  3543  													Start: hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3544  													End:   hcl.Pos{Line: 2, Column: 18, Byte: 33},
  3545  												},
  3546  											},
  3547  										},
  3548  										NameRange: hcl.Range{
  3549  											Start: hcl.Pos{Line: 2, Column: 10, Byte: 25},
  3550  											End:   hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3551  										},
  3552  										OpenParenRange: hcl.Range{
  3553  											Start: hcl.Pos{Line: 2, Column: 16, Byte: 31},
  3554  											End:   hcl.Pos{Line: 2, Column: 17, Byte: 32},
  3555  										},
  3556  										CloseParenRange: hcl.Range{
  3557  											Start: hcl.Pos{Line: 4, Column: 4, Byte: 47},
  3558  											End:   hcl.Pos{Line: 4, Column: 5, Byte: 48},
  3559  										},
  3560  									},
  3561  									SrcRange: hcl.Range{
  3562  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3563  										End:   hcl.Pos{Line: 4, Column: 5, Byte: 48},
  3564  									},
  3565  									NameRange: hcl.Range{
  3566  										Start: hcl.Pos{Line: 2, Column: 3, Byte: 18},
  3567  										End:   hcl.Pos{Line: 2, Column: 7, Byte: 22},
  3568  									},
  3569  									EqualsRange: hcl.Range{
  3570  										Start: hcl.Pos{Line: 2, Column: 8, Byte: 23},
  3571  										End:   hcl.Pos{Line: 2, Column: 9, Byte: 24},
  3572  									},
  3573  								},
  3574  							},
  3575  							Blocks: Blocks{},
  3576  							SrcRange: hcl.Range{
  3577  								Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3578  								End:   hcl.Pos{Line: 5, Column: 1, Byte: 49},
  3579  							},
  3580  							EndRange: hcl.Range{
  3581  								Start: hcl.Pos{Line: 5, Column: 1, Byte: 49},
  3582  								End:   hcl.Pos{Line: 5, Column: 1, Byte: 49},
  3583  							},
  3584  						},
  3585  						TypeRange: hcl.Range{
  3586  							Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3587  							End:   hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3588  						},
  3589  						LabelRanges: []hcl.Range{
  3590  							{
  3591  								Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3592  								End:   hcl.Pos{Line: 1, Column: 14, Byte: 13},
  3593  							},
  3594  						},
  3595  						OpenBraceRange: hcl.Range{
  3596  							Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
  3597  							End:   hcl.Pos{Line: 1, Column: 16, Byte: 15},
  3598  						},
  3599  						CloseBraceRange: hcl.Range{
  3600  							Start: hcl.Pos{Line: 5, Column: 1, Byte: 49},
  3601  							End:   hcl.Pos{Line: 5, Column: 1, Byte: 49},
  3602  						},
  3603  					},
  3604  				},
  3605  				SrcRange: hcl.Range{
  3606  					Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3607  					End:   hcl.Pos{Line: 5, Column: 1, Byte: 49},
  3608  				},
  3609  				EndRange: hcl.Range{
  3610  					Start: hcl.Pos{Line: 5, Column: 1, Byte: 49},
  3611  					End:   hcl.Pos{Line: 5, Column: 1, Byte: 49},
  3612  				},
  3613  			},
  3614  		},
  3615  	}
  3616  	opts := cmp.Options{
  3617  		cmpopts.IgnoreUnexported(FunctionCallExpr{}),
  3618  		cmpopts.IgnoreUnexported(Body{}),
  3619  		cmpopts.IgnoreUnexported(cty.Value{}),
  3620  	}
  3621  	for i, test := range tests {
  3622  		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
  3623  			t.Logf("\n%s", test.input)
  3624  			file, _ := ParseConfig([]byte(test.input), "", hcl.InitialPos)
  3625  
  3626  			got := file.Body
  3627  
  3628  			if diff := cmp.Diff(got, test.want, opts); diff != "" {
  3629  				t.Errorf(diff)
  3630  			}
  3631  		})
  3632  	}
  3633  }
  3634  
  3635  func TestParseConfigDiagnostics(t *testing.T) {
  3636  	// This test function is a variant of TestParseConfig which tests for
  3637  	// specific error messages for certain kinds of invalid input where we
  3638  	// intend to produce a particular helpful error message.
  3639  
  3640  	tests := map[string]struct {
  3641  		input string
  3642  		want  hcl.Diagnostics
  3643  	}{
  3644  		"unclosed multi-line block (no contents)": {
  3645  			"blah {\n",
  3646  			hcl.Diagnostics{
  3647  				{
  3648  					Severity: hcl.DiagError,
  3649  					Summary:  "Unclosed configuration block",
  3650  					Detail:   "There is no closing brace for this block before the end of the file. This may be caused by incorrect brace nesting elsewhere in this file.",
  3651  					Subject: &hcl.Range{
  3652  						Filename: "test.hcl",
  3653  						Start:    hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3654  						End:      hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3655  					},
  3656  				},
  3657  			},
  3658  		},
  3659  		"unclosed multi-line block (after one argument)": {
  3660  			"blah {\n  a = 1\n",
  3661  			hcl.Diagnostics{
  3662  				{
  3663  					Severity: hcl.DiagError,
  3664  					Summary:  "Unclosed configuration block",
  3665  					Detail:   "There is no closing brace for this block before the end of the file. This may be caused by incorrect brace nesting elsewhere in this file.",
  3666  					Subject: &hcl.Range{
  3667  						Filename: "test.hcl",
  3668  						Start:    hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3669  						End:      hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3670  					},
  3671  				},
  3672  			},
  3673  		},
  3674  		"unclosed single-line block (no contents)": {
  3675  			"blah {",
  3676  			hcl.Diagnostics{
  3677  				{
  3678  					Severity: hcl.DiagError,
  3679  					Summary:  "Unclosed configuration block",
  3680  					Detail:   "There is no closing brace for this block before the end of the file. This may be caused by incorrect brace nesting elsewhere in this file.",
  3681  					Subject: &hcl.Range{
  3682  						Filename: "test.hcl",
  3683  						Start:    hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3684  						End:      hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3685  					},
  3686  				},
  3687  			},
  3688  		},
  3689  		"unclosed single-line block (after its argument)": {
  3690  			"blah { a = 1",
  3691  			hcl.Diagnostics{
  3692  				{
  3693  					Severity: hcl.DiagError,
  3694  					Summary:  "Unclosed configuration block",
  3695  					Detail:   "There is no closing brace for this block before the end of the file. This may be caused by incorrect brace nesting elsewhere in this file.",
  3696  					Subject: &hcl.Range{
  3697  						Filename: "test.hcl",
  3698  						Start:    hcl.Pos{Line: 1, Column: 6, Byte: 5},
  3699  						End:      hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3700  					},
  3701  					Context: &hcl.Range{ // In this case we can also report a context because we detect this error in a more convenient place in the parser
  3702  						Filename: "test.hcl",
  3703  						Start:    hcl.Pos{Line: 1, Column: 1, Byte: 0},
  3704  						End:      hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3705  					},
  3706  				},
  3707  			},
  3708  		},
  3709  		"unclosed object constructor (before element separator)": {
  3710  			`foo = { a = 1`,
  3711  			hcl.Diagnostics{
  3712  				{
  3713  					Severity: hcl.DiagError,
  3714  					Summary:  "Unterminated object constructor expression",
  3715  					Detail:   "There is no corresponding closing brace before the end of the file. This may be caused by incorrect brace nesting elsewhere in this file.",
  3716  					Subject: &hcl.Range{
  3717  						Filename: "test.hcl",
  3718  						Start:    hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3719  						End:      hcl.Pos{Line: 1, Column: 8, Byte: 7},
  3720  					},
  3721  				},
  3722  			},
  3723  		},
  3724  		"unclosed object constructor (before equals)": {
  3725  			`foo = { a `,
  3726  			hcl.Diagnostics{
  3727  				{
  3728  					Severity: hcl.DiagError,
  3729  					Summary:  "Unterminated object constructor expression",
  3730  					Detail:   "There is no corresponding closing brace before the end of the file. This may be caused by incorrect brace nesting elsewhere in this file.",
  3731  					Subject: &hcl.Range{
  3732  						Filename: "test.hcl",
  3733  						Start:    hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3734  						End:      hcl.Pos{Line: 1, Column: 8, Byte: 7},
  3735  					},
  3736  				},
  3737  			},
  3738  		},
  3739  		"unclosed tuple constructor (before element separator)": {
  3740  			`foo = [ a`,
  3741  			hcl.Diagnostics{
  3742  				{
  3743  					Severity: hcl.DiagError,
  3744  					Summary:  "Unterminated tuple constructor expression",
  3745  					Detail:   "There is no corresponding closing bracket before the end of the file. This may be caused by incorrect bracket nesting elsewhere in this file.",
  3746  					Subject: &hcl.Range{
  3747  						Filename: "test.hcl",
  3748  						Start:    hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3749  						End:      hcl.Pos{Line: 1, Column: 8, Byte: 7},
  3750  					},
  3751  				},
  3752  			},
  3753  		},
  3754  		"unclosed function call": {
  3755  			`foo = boop("a"`,
  3756  			hcl.Diagnostics{
  3757  				{
  3758  					Severity: hcl.DiagError,
  3759  					Summary:  "Unterminated function call",
  3760  					Detail:   "There is no closing parenthesis for this function call before the end of the file. This may be caused by incorrect parenthesis nesting elsewhere in this file.",
  3761  					Subject: &hcl.Range{
  3762  						Filename: "test.hcl",
  3763  						Start:    hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3764  						End:      hcl.Pos{Line: 1, Column: 12, Byte: 11},
  3765  					},
  3766  				},
  3767  			},
  3768  		},
  3769  		"unclosed grouping parentheses": {
  3770  			`foo = (1`,
  3771  			hcl.Diagnostics{
  3772  				{
  3773  					Severity: hcl.DiagError,
  3774  					Summary:  "Unbalanced parentheses",
  3775  					Detail:   "Expected a closing parenthesis to terminate the expression.",
  3776  					Subject: &hcl.Range{
  3777  						Filename: "test.hcl",
  3778  						Start:    hcl.Pos{Line: 1, Column: 9, Byte: 8},
  3779  						End:      hcl.Pos{Line: 1, Column: 9, Byte: 8},
  3780  					},
  3781  					Context: &hcl.Range{
  3782  						Filename: "test.hcl",
  3783  						Start:    hcl.Pos{Line: 1, Column: 7, Byte: 6},
  3784  						End:      hcl.Pos{Line: 1, Column: 9, Byte: 8},
  3785  					},
  3786  				},
  3787  			},
  3788  		},
  3789  		"unclosed template interpolation at EOF": {
  3790  			`foo = "${a`,
  3791  			hcl.Diagnostics{
  3792  				{
  3793  					Severity: hcl.DiagError,
  3794  					Summary:  "Unclosed template interpolation sequence",
  3795  					Detail:   "There is no closing brace for this interpolation sequence before the end of the file. This might be caused by incorrect nesting inside the given expression.",
  3796  					Subject: &hcl.Range{
  3797  						Filename: "test.hcl",
  3798  						Start:    hcl.Pos{Line: 1, Column: 8, Byte: 7},
  3799  						End:      hcl.Pos{Line: 1, Column: 10, Byte: 9},
  3800  					},
  3801  				},
  3802  			},
  3803  		},
  3804  		"unclosed quoted template interpolation at closing quote": {
  3805  			`foo = "${a"`,
  3806  			hcl.Diagnostics{
  3807  				{
  3808  					Severity: hcl.DiagError,
  3809  					Summary:  "Unclosed template interpolation sequence",
  3810  					Detail:   "There is no closing brace for this interpolation sequence before the end of the quoted template. This might be caused by incorrect nesting inside the given expression.",
  3811  					Subject: &hcl.Range{
  3812  						Filename: "test.hcl",
  3813  						Start:    hcl.Pos{Line: 1, Column: 8, Byte: 7},
  3814  						End:      hcl.Pos{Line: 1, Column: 10, Byte: 9},
  3815  					},
  3816  				},
  3817  			},
  3818  		},
  3819  		"unclosed quoted template at literal part": {
  3820  			`foo = "${a}`,
  3821  			hcl.Diagnostics{
  3822  				{
  3823  					Severity: hcl.DiagError,
  3824  					Summary:  "Unterminated template string",
  3825  					Detail:   "No closing marker was found for the string.",
  3826  					Subject: &hcl.Range{
  3827  						Filename: "test.hcl",
  3828  						Start:    hcl.Pos{Line: 1, Column: 12, Byte: 11},
  3829  						End:      hcl.Pos{Line: 1, Column: 12, Byte: 11},
  3830  					},
  3831  					Context: &hcl.Range{
  3832  						Filename: "test.hcl",
  3833  						Start:    hcl.Pos{Line: 1, Column: 8, Byte: 7},
  3834  						End:      hcl.Pos{Line: 1, Column: 12, Byte: 11},
  3835  					},
  3836  				},
  3837  			},
  3838  		},
  3839  
  3840  		// Some of our "unclosed" situations happen at a less convenient time
  3841  		// when we only know we're waiting for an expression, so those get
  3842  		// an error message with much less context.
  3843  		"unclosed object constructor (before any expression)": {
  3844  			`foo = {`,
  3845  			hcl.Diagnostics{
  3846  				{
  3847  					Severity: hcl.DiagError,
  3848  					Summary:  "Missing expression",
  3849  					Detail:   "Expected the start of an expression, but found the end of the file.",
  3850  					Subject: &hcl.Range{
  3851  						Filename: "test.hcl",
  3852  						Start:    hcl.Pos{Line: 1, Column: 8, Byte: 7},
  3853  						End:      hcl.Pos{Line: 1, Column: 8, Byte: 7},
  3854  					},
  3855  				},
  3856  			},
  3857  		},
  3858  		"unclosed tuple constructor (before any expression)": {
  3859  			`foo = [`,
  3860  			hcl.Diagnostics{
  3861  				{
  3862  					Severity: hcl.DiagError,
  3863  					Summary:  "Missing expression",
  3864  					Detail:   "Expected the start of an expression, but found the end of the file.",
  3865  					Subject: &hcl.Range{
  3866  						Filename: "test.hcl",
  3867  						Start:    hcl.Pos{Line: 1, Column: 8, Byte: 7},
  3868  						End:      hcl.Pos{Line: 1, Column: 8, Byte: 7},
  3869  					},
  3870  				},
  3871  			},
  3872  		},
  3873  		"unclosed function call (before any argument)": {
  3874  			`foo = foo(`,
  3875  			hcl.Diagnostics{
  3876  				{
  3877  					Severity: hcl.DiagError,
  3878  					Summary:  "Missing expression",
  3879  					Detail:   "Expected the start of an expression, but found the end of the file.",
  3880  					Subject: &hcl.Range{
  3881  						Filename: "test.hcl",
  3882  						Start:    hcl.Pos{Line: 1, Column: 11, Byte: 10},
  3883  						End:      hcl.Pos{Line: 1, Column: 11, Byte: 10},
  3884  					},
  3885  				},
  3886  			},
  3887  		},
  3888  	}
  3889  
  3890  	for name, test := range tests {
  3891  		t.Run(name, func(t *testing.T) {
  3892  			t.Logf("\n%s", test.input)
  3893  			_, diags := ParseConfig([]byte(test.input), "test.hcl", hcl.InitialPos)
  3894  
  3895  			if diff := deep.Equal(diags, test.want); diff != nil {
  3896  				for _, problem := range diff {
  3897  					t.Errorf(problem)
  3898  				}
  3899  			}
  3900  		})
  3901  	}
  3902  }