snapshot of https://github.com/ory/keto.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
129
schema/parse_errors.go
Normal file
129
schema/parse_errors.go
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
opl "github.com/ory/keto/gen/go/ory/keto/opl/v1alpha1"
|
||||
"github.com/ory/keto/ketoapi"
|
||||
)
|
||||
|
||||
type (
|
||||
ParseError struct {
|
||||
msg string
|
||||
item item
|
||||
p *parser
|
||||
}
|
||||
)
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (e *ParseError) Error() string {
|
||||
var s strings.Builder
|
||||
start := e.toSrcPos(e.item.Start)
|
||||
end := e.toSrcPos(e.item.End)
|
||||
rows := e.rows()
|
||||
startLineIdx := max(start.Line-2, 0)
|
||||
errorLineIdx := max(start.Line-1, 0)
|
||||
|
||||
_, _ = fmt.Fprintf(&s, "error from %d:%d to %d:%d: %s\n\n",
|
||||
start.Line, start.Col,
|
||||
end.Line, end.Col,
|
||||
e.msg)
|
||||
|
||||
if len(rows) < start.Line {
|
||||
s.WriteString("meta error: could not find source position in input\n")
|
||||
return s.String()
|
||||
}
|
||||
|
||||
for line := startLineIdx; line <= errorLineIdx; line++ {
|
||||
_, _ = fmt.Fprintf(&s, "%4d | %s\n", line, rows[line])
|
||||
}
|
||||
s.WriteString(" | ")
|
||||
for i, r := range rows[errorLineIdx] {
|
||||
switch {
|
||||
case start.Col == i:
|
||||
s.WriteRune('^')
|
||||
case start.Col <= i && i <= end.Col-1:
|
||||
s.WriteRune('~')
|
||||
case unicode.IsSpace(r):
|
||||
s.WriteRune(r)
|
||||
default:
|
||||
s.WriteRune(' ')
|
||||
}
|
||||
}
|
||||
s.WriteRune('\n')
|
||||
|
||||
if errorLineIdx+1 < len(rows) {
|
||||
_, _ = fmt.Fprintf(&s, "%4d | %s\n", errorLineIdx+1, rows[errorLineIdx+1])
|
||||
s.WriteRune('\n')
|
||||
}
|
||||
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func (e *ParseError) ToAPI() *ketoapi.ParseError {
|
||||
return &ketoapi.ParseError{
|
||||
Message: e.msg,
|
||||
Start: e.toSrcPos(e.item.Start),
|
||||
End: e.toSrcPos(e.item.End),
|
||||
}
|
||||
}
|
||||
func (e *ParseError) ToProto() *opl.ParseError {
|
||||
start := e.toSrcPos(e.item.Start)
|
||||
end := e.toSrcPos(e.item.End)
|
||||
return &opl.ParseError{
|
||||
Message: e.msg,
|
||||
Start: &opl.SourcePosition{
|
||||
Line: clampUint32(start.Line),
|
||||
Column: clampUint32(start.Col),
|
||||
},
|
||||
End: &opl.SourcePosition{
|
||||
Line: clampUint32(end.Line),
|
||||
Column: clampUint32(end.Col),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// toSrcPos converts the given position in the input to a Line and column
|
||||
// number.
|
||||
func (e *ParseError) toSrcPos(pos int) (srcPos ketoapi.SourcePosition) {
|
||||
srcPos.Line = 1
|
||||
for _, c := range e.p.lexer.input {
|
||||
srcPos.Col++
|
||||
pos--
|
||||
if pos <= 0 {
|
||||
break
|
||||
}
|
||||
if c == '\n' {
|
||||
srcPos.Line++
|
||||
srcPos.Col = 0
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func clampUint32(v int) uint32 {
|
||||
switch {
|
||||
case v < 0:
|
||||
return 0
|
||||
case uint64(v) > math.MaxUint32:
|
||||
return math.MaxUint32
|
||||
default:
|
||||
return uint32(v)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ParseError) rows() []string {
|
||||
return strings.Split(e.p.lexer.input, "\n")
|
||||
}
|
||||
Reference in New Issue
Block a user