forked from schemalex/schemalex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherrors.go
96 lines (82 loc) · 2.26 KB
/
errors.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
92
93
94
95
96
package schemalex
import (
"bytes"
"fmt"
"strconv"
)
// ParseError is returned from the various `Parse` methods when an
// invalid or unsupported SQL is found. When stringified, the result
// will look something like this:
//
// parse error: expected RPAREN at line 3 column 14
// "CREATE TABLE foo " <---- AROUND HERE
type ParseError interface {
error
File() string
Line() int
Col() int
Message() string
EOF() bool
}
type parseError struct {
file string
context string
line int
col int
message string
eof bool
}
// File returns the file name (if applicable) where the error was encountered
func (e parseError) File() string { return e.file }
// Line returns the line number where the error was encountered
func (e parseError) Line() int { return e.line }
// Col returns the column number where the error was encountered
func (e parseError) Col() int { return e.col }
// EOF returns true if the error was encountered at EOF
func (e parseError) EOF() bool { return e.eof }
// Message returns the actual error message
func (e parseError) Message() string { return e.message }
// Error returns the formatted string representation of this parse error.
func (e parseError) Error() string {
var buf bytes.Buffer
buf.WriteString("parse error: ")
buf.WriteString(e.message)
if f := e.file; len(f) > 0 {
buf.WriteString(" in file ")
buf.WriteString(f)
}
buf.WriteString(" at line ")
buf.WriteString(strconv.Itoa(e.line))
buf.WriteString(" column ")
buf.WriteString(strconv.Itoa(e.col))
if e.eof {
buf.WriteString(" (at EOF)")
}
buf.WriteString("\n ")
buf.WriteString(e.context)
return buf.String()
}
func newParseError(ctx *parseCtx, t *Token, msg string, args ...interface{}) error {
if len(args) > 0 {
msg = fmt.Sprintf(msg, args...)
}
// find the closest newline before t.Pos
var ctxbegin int
if i := bytes.LastIndexByte(ctx.input[:t.Pos], '\n'); i > 0 {
if len(ctx.input)-1 > i {
ctxbegin = i + 1
}
}
// if this is more than 40 chars from t.Pos, truncate it
if t.Pos-ctxbegin > 40 {
ctxbegin = t.Pos - 40
}
// We're going to append a marker here
return &parseError{
context: fmt.Sprintf(`"%s" <---- AROUND HERE`, ctx.input[ctxbegin:t.Pos]),
line: t.Line,
col: t.Col,
eof: t.EOF,
message: msg,
}
}