File: public.go

package info (click to toggle)
golang-github-hashicorp-hcl-v2 2.14.1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid, trixie
  • size: 3,120 kB
  • sloc: ruby: 205; makefile: 72; python: 43; sh: 11
file content (117 lines) | stat: -rw-r--r-- 3,718 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package json

import (
	"fmt"
	"io/ioutil"
	"os"

	"github.com/hashicorp/hcl/v2"
)

// Parse attempts to parse the given buffer as JSON and, if successful, returns
// a hcl.File for the HCL configuration represented by it.
//
// This is not a generic JSON parser. Instead, it deals only with the profile
// of JSON used to express HCL configuration.
//
// The returned file is valid only if the returned diagnostics returns false
// from its HasErrors method. If HasErrors returns true, the file represents
// the subset of data that was able to be parsed, which may be none.
func Parse(src []byte, filename string) (*hcl.File, hcl.Diagnostics) {
	return ParseWithStartPos(src, filename, hcl.Pos{Byte: 0, Line: 1, Column: 1})
}

// ParseWithStartPos attempts to parse like json.Parse, but unlike json.Parse
// you can pass a start position of the given JSON as a hcl.Pos.
//
// In most cases json.Parse should be sufficient, but it can be useful for parsing
// a part of JSON with correct positions.
func ParseWithStartPos(src []byte, filename string, start hcl.Pos) (*hcl.File, hcl.Diagnostics) {
	rootNode, diags := parseFileContent(src, filename, start)

	switch rootNode.(type) {
	case *objectVal, *arrayVal:
		// okay
	default:
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Root value must be object",
			Detail:   "The root value in a JSON-based configuration must be either a JSON object or a JSON array of objects.",
			Subject:  rootNode.StartRange().Ptr(),
		})

		// Since we've already produced an error message for this being
		// invalid, we'll return an empty placeholder here so that trying to
		// extract content from our root body won't produce a redundant
		// error saying the same thing again in more general terms.
		fakePos := hcl.Pos{
			Byte:   0,
			Line:   1,
			Column: 1,
		}
		fakeRange := hcl.Range{
			Filename: filename,
			Start:    fakePos,
			End:      fakePos,
		}
		rootNode = &objectVal{
			Attrs:     []*objectAttr{},
			SrcRange:  fakeRange,
			OpenRange: fakeRange,
		}
	}

	file := &hcl.File{
		Body: &body{
			val: rootNode,
		},
		Bytes: src,
		Nav:   navigation{rootNode},
	}
	return file, diags
}

// ParseExpression parses the given buffer as a standalone JSON expression,
// returning it as an instance of Expression.
func ParseExpression(src []byte, filename string) (hcl.Expression, hcl.Diagnostics) {
	return ParseExpressionWithStartPos(src, filename, hcl.Pos{Byte: 0, Line: 1, Column: 1})
}

// ParseExpressionWithStartPos parses like json.ParseExpression, but unlike
// json.ParseExpression you can pass a start position of the given JSON
// expression as a hcl.Pos.
func ParseExpressionWithStartPos(src []byte, filename string, start hcl.Pos) (hcl.Expression, hcl.Diagnostics) {
	node, diags := parseExpression(src, filename, start)
	return &expression{src: node}, diags
}

// ParseFile is a convenience wrapper around Parse that first attempts to load
// data from the given filename, passing the result to Parse if successful.
//
// If the file cannot be read, an error diagnostic with nil context is returned.
func ParseFile(filename string) (*hcl.File, hcl.Diagnostics) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, hcl.Diagnostics{
			{
				Severity: hcl.DiagError,
				Summary:  "Failed to open file",
				Detail:   fmt.Sprintf("The file %q could not be opened.", filename),
			},
		}
	}
	defer f.Close()

	src, err := ioutil.ReadAll(f)
	if err != nil {
		return nil, hcl.Diagnostics{
			{
				Severity: hcl.DiagError,
				Summary:  "Failed to read file",
				Detail:   fmt.Sprintf("The file %q was opened, but an error occured while reading it.", filename),
			},
		}
	}

	return Parse(src, filename)
}