aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/hcl2/hclparse/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/hcl2/hclparse/parser.go')
-rw-r--r--vendor/github.com/hashicorp/hcl2/hclparse/parser.go123
1 files changed, 123 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hcl2/hclparse/parser.go b/vendor/github.com/hashicorp/hcl2/hclparse/parser.go
new file mode 100644
index 0000000..6d47f12
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl2/hclparse/parser.go
@@ -0,0 +1,123 @@
1package hclparse
2
3import (
4 "fmt"
5 "io/ioutil"
6
7 "github.com/hashicorp/hcl2/hcl"
8 "github.com/hashicorp/hcl2/hcl/hclsyntax"
9 "github.com/hashicorp/hcl2/hcl/json"
10)
11
12// NOTE: This is the public interface for parsing. The actual parsers are
13// in other packages alongside this one, with this package just wrapping them
14// to provide a unified interface for the caller across all supported formats.
15
16// Parser is the main interface for parsing configuration files. As well as
17// parsing files, a parser also retains a registry of all of the files it
18// has parsed so that multiple attempts to parse the same file will return
19// the same object and so the collected files can be used when printing
20// diagnostics.
21//
22// Any diagnostics for parsing a file are only returned once on the first
23// call to parse that file. Callers are expected to collect up diagnostics
24// and present them together, so returning diagnostics for the same file
25// multiple times would create a confusing result.
26type Parser struct {
27 files map[string]*hcl.File
28}
29
30// NewParser creates a new parser, ready to parse configuration files.
31func NewParser() *Parser {
32 return &Parser{
33 files: map[string]*hcl.File{},
34 }
35}
36
37// ParseHCL parses the given buffer (which is assumed to have been loaded from
38// the given filename) as a native-syntax configuration file and returns the
39// hcl.File object representing it.
40func (p *Parser) ParseHCL(src []byte, filename string) (*hcl.File, hcl.Diagnostics) {
41 if existing := p.files[filename]; existing != nil {
42 return existing, nil
43 }
44
45 file, diags := hclsyntax.ParseConfig(src, filename, hcl.Pos{Byte: 0, Line: 1, Column: 1})
46 p.files[filename] = file
47 return file, diags
48}
49
50// ParseHCLFile reads the given filename and parses it as a native-syntax HCL
51// configuration file. An error diagnostic is returned if the given file
52// cannot be read.
53func (p *Parser) ParseHCLFile(filename string) (*hcl.File, hcl.Diagnostics) {
54 if existing := p.files[filename]; existing != nil {
55 return existing, nil
56 }
57
58 src, err := ioutil.ReadFile(filename)
59 if err != nil {
60 return nil, hcl.Diagnostics{
61 {
62 Severity: hcl.DiagError,
63 Summary: "Failed to read file",
64 Detail: fmt.Sprintf("The configuration file %q could not be read.", filename),
65 },
66 }
67 }
68
69 return p.ParseHCL(src, filename)
70}
71
72// ParseJSON parses the given JSON buffer (which is assumed to have been loaded
73// from the given filename) and returns the hcl.File object representing it.
74func (p *Parser) ParseJSON(src []byte, filename string) (*hcl.File, hcl.Diagnostics) {
75 if existing := p.files[filename]; existing != nil {
76 return existing, nil
77 }
78
79 file, diags := json.Parse(src, filename)
80 p.files[filename] = file
81 return file, diags
82}
83
84// ParseJSONFile reads the given filename and parses it as JSON, similarly to
85// ParseJSON. An error diagnostic is returned if the given file cannot be read.
86func (p *Parser) ParseJSONFile(filename string) (*hcl.File, hcl.Diagnostics) {
87 if existing := p.files[filename]; existing != nil {
88 return existing, nil
89 }
90
91 file, diags := json.ParseFile(filename)
92 p.files[filename] = file
93 return file, diags
94}
95
96// AddFile allows a caller to record in a parser a file that was parsed some
97// other way, thus allowing it to be included in the registry of sources.
98func (p *Parser) AddFile(filename string, file *hcl.File) {
99 p.files[filename] = file
100}
101
102// Sources returns a map from filenames to the raw source code that was
103// read from them. This is intended to be used, for example, to print
104// diagnostics with contextual information.
105//
106// The arrays underlying the returned slices should not be modified.
107func (p *Parser) Sources() map[string][]byte {
108 ret := make(map[string][]byte)
109 for fn, f := range p.files {
110 ret[fn] = f.Bytes
111 }
112 return ret
113}
114
115// Files returns a map from filenames to the File objects produced from them.
116// This is intended to be used, for example, to print diagnostics with
117// contextual information.
118//
119// The returned map and all of the objects it refers to directly or indirectly
120// must not be modified.
121func (p *Parser) Files() map[string]*hcl.File {
122 return p.files
123}