@@ -149,8 +149,9 @@ func (s *SeenTracker) setExplicitFlag(parentIdx int) {
149
149
150
150
// CheckExpression takes a top-level node and checks that it does not contain
151
151
// keys that have been seen in previous calls, and validates that types are
152
- // consistent.
153
- func (s * SeenTracker ) CheckExpression (node * unstable.Node ) error {
152
+ // consistent. It returns true if it is the first time this node's key is seen.
153
+ // Useful to clear array tables on first use.
154
+ func (s * SeenTracker ) CheckExpression (node * unstable.Node ) (bool , error ) {
154
155
if s .entries == nil {
155
156
s .reset ()
156
157
}
@@ -166,7 +167,7 @@ func (s *SeenTracker) CheckExpression(node *unstable.Node) error {
166
167
}
167
168
}
168
169
169
- func (s * SeenTracker ) checkTable (node * unstable.Node ) error {
170
+ func (s * SeenTracker ) checkTable (node * unstable.Node ) ( bool , error ) {
170
171
if s .currentIdx >= 0 {
171
172
s .setExplicitFlag (s .currentIdx )
172
173
}
@@ -192,7 +193,7 @@ func (s *SeenTracker) checkTable(node *unstable.Node) error {
192
193
} else {
193
194
entry := s .entries [idx ]
194
195
if entry .kind == valueKind {
195
- return fmt .Errorf ("toml: expected %s to be a table, not a %s" , string (k ), entry .kind )
196
+ return false , fmt .Errorf ("toml: expected %s to be a table, not a %s" , string (k ), entry .kind )
196
197
}
197
198
}
198
199
parentIdx = idx
@@ -201,25 +202,27 @@ func (s *SeenTracker) checkTable(node *unstable.Node) error {
201
202
k := it .Node ().Data
202
203
idx := s .find (parentIdx , k )
203
204
205
+ first := false
204
206
if idx >= 0 {
205
207
kind := s .entries [idx ].kind
206
208
if kind != tableKind {
207
- return fmt .Errorf ("toml: key %s should be a table, not a %s" , string (k ), kind )
209
+ return false , fmt .Errorf ("toml: key %s should be a table, not a %s" , string (k ), kind )
208
210
}
209
211
if s .entries [idx ].explicit {
210
- return fmt .Errorf ("toml: table %s already exists" , string (k ))
212
+ return false , fmt .Errorf ("toml: table %s already exists" , string (k ))
211
213
}
212
214
s .entries [idx ].explicit = true
213
215
} else {
214
216
idx = s .create (parentIdx , k , tableKind , true , false )
217
+ first = true
215
218
}
216
219
217
220
s .currentIdx = idx
218
221
219
- return nil
222
+ return first , nil
220
223
}
221
224
222
- func (s * SeenTracker ) checkArrayTable (node * unstable.Node ) error {
225
+ func (s * SeenTracker ) checkArrayTable (node * unstable.Node ) ( bool , error ) {
223
226
if s .currentIdx >= 0 {
224
227
s .setExplicitFlag (s .currentIdx )
225
228
}
@@ -242,7 +245,7 @@ func (s *SeenTracker) checkArrayTable(node *unstable.Node) error {
242
245
} else {
243
246
entry := s .entries [idx ]
244
247
if entry .kind == valueKind {
245
- return fmt .Errorf ("toml: expected %s to be a table, not a %s" , string (k ), entry .kind )
248
+ return false , fmt .Errorf ("toml: expected %s to be a table, not a %s" , string (k ), entry .kind )
246
249
}
247
250
}
248
251
@@ -252,22 +255,23 @@ func (s *SeenTracker) checkArrayTable(node *unstable.Node) error {
252
255
k := it .Node ().Data
253
256
idx := s .find (parentIdx , k )
254
257
255
- if idx >= 0 {
258
+ firstTime := idx < 0
259
+ if firstTime {
260
+ idx = s .create (parentIdx , k , arrayTableKind , true , false )
261
+ } else {
256
262
kind := s .entries [idx ].kind
257
263
if kind != arrayTableKind {
258
- return fmt .Errorf ("toml: key %s already exists as a %s, but should be an array table" , kind , string (k ))
264
+ return false , fmt .Errorf ("toml: key %s already exists as a %s, but should be an array table" , kind , string (k ))
259
265
}
260
266
s .clear (idx )
261
- } else {
262
- idx = s .create (parentIdx , k , arrayTableKind , true , false )
263
267
}
264
268
265
269
s .currentIdx = idx
266
270
267
- return nil
271
+ return firstTime , nil
268
272
}
269
273
270
- func (s * SeenTracker ) checkKeyValue (node * unstable.Node ) error {
274
+ func (s * SeenTracker ) checkKeyValue (node * unstable.Node ) ( bool , error ) {
271
275
parentIdx := s .currentIdx
272
276
it := node .Key ()
273
277
@@ -281,11 +285,11 @@ func (s *SeenTracker) checkKeyValue(node *unstable.Node) error {
281
285
} else {
282
286
entry := s .entries [idx ]
283
287
if it .IsLast () {
284
- return fmt .Errorf ("toml: key %s is already defined" , string (k ))
288
+ return false , fmt .Errorf ("toml: key %s is already defined" , string (k ))
285
289
} else if entry .kind != tableKind {
286
- return fmt .Errorf ("toml: expected %s to be a table, not a %s" , string (k ), entry .kind )
290
+ return false , fmt .Errorf ("toml: expected %s to be a table, not a %s" , string (k ), entry .kind )
287
291
} else if entry .explicit {
288
- return fmt .Errorf ("toml: cannot redefine table %s that has already been explicitly defined" , string (k ))
292
+ return false , fmt .Errorf ("toml: cannot redefine table %s that has already been explicitly defined" , string (k ))
289
293
}
290
294
}
291
295
@@ -303,30 +307,30 @@ func (s *SeenTracker) checkKeyValue(node *unstable.Node) error {
303
307
return s .checkArray (value )
304
308
}
305
309
306
- return nil
310
+ return false , nil
307
311
}
308
312
309
- func (s * SeenTracker ) checkArray (node * unstable.Node ) error {
313
+ func (s * SeenTracker ) checkArray (node * unstable.Node ) ( first bool , err error ) {
310
314
it := node .Children ()
311
315
for it .Next () {
312
316
n := it .Node ()
313
317
switch n .Kind {
314
318
case unstable .InlineTable :
315
- err : = s .checkInlineTable (n )
319
+ first , err = s .checkInlineTable (n )
316
320
if err != nil {
317
- return err
321
+ return false , err
318
322
}
319
323
case unstable .Array :
320
- err : = s .checkArray (n )
324
+ first , err = s .checkArray (n )
321
325
if err != nil {
322
- return err
326
+ return false , err
323
327
}
324
328
}
325
329
}
326
- return nil
330
+ return first , nil
327
331
}
328
332
329
- func (s * SeenTracker ) checkInlineTable (node * unstable.Node ) error {
333
+ func (s * SeenTracker ) checkInlineTable (node * unstable.Node ) ( first bool , err error ) {
330
334
if pool .New == nil {
331
335
pool .New = func () interface {} {
332
336
return & SeenTracker {}
@@ -339,9 +343,9 @@ func (s *SeenTracker) checkInlineTable(node *unstable.Node) error {
339
343
it := node .Children ()
340
344
for it .Next () {
341
345
n := it .Node ()
342
- err : = s .checkKeyValue (n )
346
+ first , err = s .checkKeyValue (n )
343
347
if err != nil {
344
- return err
348
+ return false , err
345
349
}
346
350
}
347
351
@@ -352,5 +356,5 @@ func (s *SeenTracker) checkInlineTable(node *unstable.Node) error {
352
356
// redefinition of its keys: check* functions cannot walk into
353
357
// a value.
354
358
pool .Put (s )
355
- return nil
359
+ return first , nil
356
360
}
0 commit comments