-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfmt.go
91 lines (71 loc) · 1.65 KB
/
fmt.go
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
package fmt
import (
"github.com/MontFerret/ferret/pkg/parser/fql"
"github.com/MontFerret/fmt/internal"
"github.com/antlr/antlr4/runtime/Go/antlr"
"github.com/pkg/errors"
"unicode"
)
type (
normalizer struct {
antlr.CharStream
}
Formatter struct {
opts *Options
}
)
func newNormalizer(in antlr.CharStream) *normalizer {
return &normalizer{in}
}
func (is *normalizer) LA(offset int) int {
in := is.CharStream.LA(offset)
if in < 0 {
// Such as antlr.TokenEOF which is -1
return in
}
return int(unicode.ToUpper(rune(in)))
}
func New(setters ...Option) *Formatter {
opts := DefaultOptions()
for _, setter := range setters {
setter(opts)
}
return &Formatter{opts}
}
func (fmt *Formatter) Format(query string) (output string, err error) {
if query == "" {
return "", nil
}
defer func() {
if r := recover(); r != nil {
// find out exactly what the error was and set err
switch x := r.(type) {
case string:
err = errors.New(x)
case error:
err = x
default:
err = errors.New("unknown panic")
}
output = ""
}
}()
input := antlr.NewInputStream(query)
lexer := fql.NewFqlLexer(newNormalizer(input))
stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
p := fql.NewFqlParser(stream)
p.BuildParseTrees = true
p.AddErrorListener(antlr.NewDiagnosticErrorListener(true))
p.AddErrorListener(&internal.ErrorListener{})
w := internal.NewWriter(*fmt.opts)
l := internal.NewVisitor(w)
antlr.ParseTreeWalkerDefault.Walk(l, p.Program())
return w.String(), nil
}
func (fmt *Formatter) MustFormat(query string) string {
out, err := fmt.Format(query)
if err != nil {
panic(err)
}
return out
}