From 93ad16b0794b53c076e253d57806d2fc91a7a387 Mon Sep 17 00:00:00 2001 From: tdakkota Date: Tue, 5 Jul 2022 07:02:23 +0300 Subject: [PATCH] refactor(json): compute line and column during parsing --- json/location.go | 30 ++++++++++++++++++------------ parse_error.go | 2 +- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/json/location.go b/json/location.go index 267f40e00..68cb5e4d1 100644 --- a/json/location.go +++ b/json/location.go @@ -2,6 +2,8 @@ package json import ( "bytes" + "fmt" + "strconv" "github.com/go-json-experiment/json" ) @@ -34,18 +36,17 @@ func LineColumn(offset int64, data []byte) (line, column int64, ok bool) { // Location is a JSON value location. type Location struct { - JSONPointer string `json:"-"` - Offset int64 `json:"-"` + JSONPointer string `json:"-"` + Offset int64 `json:"-"` + Line, Column int64 `json:"-"` } -// IsZero implements the json. interface. -func (l Location) IsZero() bool { - return true // always zero, do not marshal it. -} - -// LineColumn returns the line and column of the location. -func (l Location) LineColumn(data []byte) (line, column int64, ok bool) { - return LineColumn(l.Offset, data) +// String implements fmt.Stringer. +func (l Location) String() string { + if l.Line == 0 { + return strconv.Quote(l.JSONPointer) + } + return fmt.Sprintf("line %d:%d", l.Line, l.Column) } // Locatable is an interface for JSON value location store. @@ -71,14 +72,19 @@ func (l Locator) Location() (Location, bool) { } // LocationUnmarshaler is json.Unmarshalers that sets the location. -func LocationUnmarshaler() *json.Unmarshalers { +func LocationUnmarshaler(data []byte) *json.Unmarshalers { return json.UnmarshalFuncV2(func(opts json.UnmarshalOptions, d *json.Decoder, l Locatable) error { if _, ok := l.(*Locator); ok { return nil } + + offset := d.InputOffset() + line, column, _ := LineColumn(offset, data) l.setLocation(Location{ JSONPointer: d.StackPointer(), - Offset: d.InputOffset(), + Offset: offset, + Line: line, + Column: column, }) return json.SkipFunc }) diff --git a/parse_error.go b/parse_error.go index 8590d5ca8..8bfe5955d 100644 --- a/parse_error.go +++ b/parse_error.go @@ -15,7 +15,7 @@ func unmarshal(data []byte, out any) error { begin = d.InputOffset() return json.SkipFunc }), - ogenjson.LocationUnmarshaler(), + ogenjson.LocationUnmarshaler(data), ), }