...
1 package sourcemap
2
3 import (
4 "errors"
5 "io"
6 "strings"
7
8 "github.com/go-sourcemap/sourcemap/internal/base64vlq"
9 )
10
11 type fn func(m *mappings) (fn, error)
12
13 type mapping struct {
14 genLine int32
15 genColumn int32
16 sourcesInd int32
17 sourceLine int32
18 sourceColumn int32
19 namesInd int32
20 }
21
22 type mappings struct {
23 rd *strings.Reader
24 dec base64vlq.Decoder
25
26 hasName bool
27 value mapping
28
29 values []mapping
30 }
31
32 func parseMappings(s string) ([]mapping, error) {
33 if s == "" {
34 return nil, errors.New("sourcemap: mappings are empty")
35 }
36
37 rd := strings.NewReader(s)
38 m := &mappings{
39 rd: rd,
40 dec: base64vlq.NewDecoder(rd),
41
42 values: make([]mapping, 0, mappingsNumber(s)),
43 }
44 m.value.genLine = 1
45 m.value.sourceLine = 1
46
47 err := m.parse()
48 if err != nil {
49 return nil, err
50 }
51
52 values := m.values
53 m.values = nil
54 return values, nil
55 }
56
57 func mappingsNumber(s string) int {
58 return strings.Count(s, ",") + strings.Count(s, ";")
59 }
60
61 func (m *mappings) parse() error {
62 next := parseGenCol
63 for {
64 c, err := m.rd.ReadByte()
65 if err == io.EOF {
66 m.pushValue()
67 return nil
68 }
69 if err != nil {
70 return err
71 }
72
73 switch c {
74 case ',':
75 m.pushValue()
76 next = parseGenCol
77 case ';':
78 m.pushValue()
79
80 m.value.genLine++
81 m.value.genColumn = 0
82
83 next = parseGenCol
84 default:
85 err := m.rd.UnreadByte()
86 if err != nil {
87 return err
88 }
89
90 next, err = next(m)
91 if err != nil {
92 return err
93 }
94 }
95 }
96 }
97
98 func parseGenCol(m *mappings) (fn, error) {
99 n, err := m.dec.Decode()
100 if err != nil {
101 return nil, err
102 }
103 m.value.genColumn += n
104 return parseSourcesInd, nil
105 }
106
107 func parseSourcesInd(m *mappings) (fn, error) {
108 n, err := m.dec.Decode()
109 if err != nil {
110 return nil, err
111 }
112 m.value.sourcesInd += n
113 return parseSourceLine, nil
114 }
115
116 func parseSourceLine(m *mappings) (fn, error) {
117 n, err := m.dec.Decode()
118 if err != nil {
119 return nil, err
120 }
121 m.value.sourceLine += n
122 return parseSourceCol, nil
123 }
124
125 func parseSourceCol(m *mappings) (fn, error) {
126 n, err := m.dec.Decode()
127 if err != nil {
128 return nil, err
129 }
130 m.value.sourceColumn += n
131 return parseNamesInd, nil
132 }
133
134 func parseNamesInd(m *mappings) (fn, error) {
135 n, err := m.dec.Decode()
136 if err != nil {
137 return nil, err
138 }
139 m.hasName = true
140 m.value.namesInd += n
141 return parseGenCol, nil
142 }
143
144 func (m *mappings) pushValue() {
145 if m.value.sourceLine == 1 && m.value.sourceColumn == 0 {
146 return
147 }
148
149 if m.hasName {
150 m.values = append(m.values, m.value)
151 m.hasName = false
152 } else {
153 m.values = append(m.values, mapping{
154 genLine: m.value.genLine,
155 genColumn: m.value.genColumn,
156 sourcesInd: m.value.sourcesInd,
157 sourceLine: m.value.sourceLine,
158 sourceColumn: m.value.sourceColumn,
159 namesInd: -1,
160 })
161 }
162 }
163
View as plain text