aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/hcl2/hcl/json/public.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/hcl2/hcl/json/public.go')
-rw-r--r--vendor/github.com/hashicorp/hcl2/hcl/json/public.go94
1 files changed, 94 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hcl2/hcl/json/public.go b/vendor/github.com/hashicorp/hcl2/hcl/json/public.go
new file mode 100644
index 0000000..2728aa1
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl2/hcl/json/public.go
@@ -0,0 +1,94 @@
1package json
2
3import (
4 "fmt"
5 "io/ioutil"
6 "os"
7
8 "github.com/hashicorp/hcl2/hcl"
9)
10
11// Parse attempts to parse the given buffer as JSON and, if successful, returns
12// a hcl.File for the HCL configuration represented by it.
13//
14// This is not a generic JSON parser. Instead, it deals only with the profile
15// of JSON used to express HCL configuration.
16//
17// The returned file is valid only if the returned diagnostics returns false
18// from its HasErrors method. If HasErrors returns true, the file represents
19// the subset of data that was able to be parsed, which may be none.
20func Parse(src []byte, filename string) (*hcl.File, hcl.Diagnostics) {
21 rootNode, diags := parseFileContent(src, filename)
22
23 switch rootNode.(type) {
24 case *objectVal, *arrayVal:
25 // okay
26 default:
27 diags = diags.Append(&hcl.Diagnostic{
28 Severity: hcl.DiagError,
29 Summary: "Root value must be object",
30 Detail: "The root value in a JSON-based configuration must be either a JSON object or a JSON array of objects.",
31 Subject: rootNode.StartRange().Ptr(),
32 })
33
34 // Since we've already produced an error message for this being
35 // invalid, we'll return an empty placeholder here so that trying to
36 // extract content from our root body won't produce a redundant
37 // error saying the same thing again in more general terms.
38 fakePos := hcl.Pos{
39 Byte: 0,
40 Line: 1,
41 Column: 1,
42 }
43 fakeRange := hcl.Range{
44 Filename: filename,
45 Start: fakePos,
46 End: fakePos,
47 }
48 rootNode = &objectVal{
49 Attrs: []*objectAttr{},
50 SrcRange: fakeRange,
51 OpenRange: fakeRange,
52 }
53 }
54
55 file := &hcl.File{
56 Body: &body{
57 val: rootNode,
58 },
59 Bytes: src,
60 Nav: navigation{rootNode},
61 }
62 return file, diags
63}
64
65// ParseFile is a convenience wrapper around Parse that first attempts to load
66// data from the given filename, passing the result to Parse if successful.
67//
68// If the file cannot be read, an error diagnostic with nil context is returned.
69func ParseFile(filename string) (*hcl.File, hcl.Diagnostics) {
70 f, err := os.Open(filename)
71 if err != nil {
72 return nil, hcl.Diagnostics{
73 {
74 Severity: hcl.DiagError,
75 Summary: "Failed to open file",
76 Detail: fmt.Sprintf("The file %q could not be opened.", filename),
77 },
78 }
79 }
80 defer f.Close()
81
82 src, err := ioutil.ReadAll(f)
83 if err != nil {
84 return nil, hcl.Diagnostics{
85 {
86 Severity: hcl.DiagError,
87 Summary: "Failed to read file",
88 Detail: fmt.Sprintf("The file %q was opened, but an error occured while reading it.", filename),
89 },
90 }
91 }
92
93 return Parse(src, filename)
94}