@@ -149,8 +149,9 @@ func (s *SeenTracker) setExplicitFlag(parentIdx int) {
149149
150150// CheckExpression takes a top-level node and checks that it does not contain
151151// 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 ) {
154155 if s .entries == nil {
155156 s .reset ()
156157 }
@@ -166,7 +167,7 @@ func (s *SeenTracker) CheckExpression(node *unstable.Node) error {
166167 }
167168}
168169
169- func (s * SeenTracker ) checkTable (node * unstable.Node ) error {
170+ func (s * SeenTracker ) checkTable (node * unstable.Node ) ( bool , error ) {
170171 if s .currentIdx >= 0 {
171172 s .setExplicitFlag (s .currentIdx )
172173 }
@@ -192,7 +193,7 @@ func (s *SeenTracker) checkTable(node *unstable.Node) error {
192193 } else {
193194 entry := s .entries [idx ]
194195 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 )
196197 }
197198 }
198199 parentIdx = idx
@@ -201,25 +202,27 @@ func (s *SeenTracker) checkTable(node *unstable.Node) error {
201202 k := it .Node ().Data
202203 idx := s .find (parentIdx , k )
203204
205+ first := false
204206 if idx >= 0 {
205207 kind := s .entries [idx ].kind
206208 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 )
208210 }
209211 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 ))
211213 }
212214 s .entries [idx ].explicit = true
213215 } else {
214216 idx = s .create (parentIdx , k , tableKind , true , false )
217+ first = true
215218 }
216219
217220 s .currentIdx = idx
218221
219- return nil
222+ return first , nil
220223}
221224
222- func (s * SeenTracker ) checkArrayTable (node * unstable.Node ) error {
225+ func (s * SeenTracker ) checkArrayTable (node * unstable.Node ) ( bool , error ) {
223226 if s .currentIdx >= 0 {
224227 s .setExplicitFlag (s .currentIdx )
225228 }
@@ -242,7 +245,7 @@ func (s *SeenTracker) checkArrayTable(node *unstable.Node) error {
242245 } else {
243246 entry := s .entries [idx ]
244247 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 )
246249 }
247250 }
248251
@@ -252,22 +255,23 @@ func (s *SeenTracker) checkArrayTable(node *unstable.Node) error {
252255 k := it .Node ().Data
253256 idx := s .find (parentIdx , k )
254257
255- if idx >= 0 {
258+ firstTime := idx < 0
259+ if firstTime {
260+ idx = s .create (parentIdx , k , arrayTableKind , true , false )
261+ } else {
256262 kind := s .entries [idx ].kind
257263 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 ))
259265 }
260266 s .clear (idx )
261- } else {
262- idx = s .create (parentIdx , k , arrayTableKind , true , false )
263267 }
264268
265269 s .currentIdx = idx
266270
267- return nil
271+ return firstTime , nil
268272}
269273
270- func (s * SeenTracker ) checkKeyValue (node * unstable.Node ) error {
274+ func (s * SeenTracker ) checkKeyValue (node * unstable.Node ) ( bool , error ) {
271275 parentIdx := s .currentIdx
272276 it := node .Key ()
273277
@@ -281,11 +285,11 @@ func (s *SeenTracker) checkKeyValue(node *unstable.Node) error {
281285 } else {
282286 entry := s .entries [idx ]
283287 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 ))
285289 } 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 )
287291 } 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 ))
289293 }
290294 }
291295
@@ -303,30 +307,30 @@ func (s *SeenTracker) checkKeyValue(node *unstable.Node) error {
303307 return s .checkArray (value )
304308 }
305309
306- return nil
310+ return false , nil
307311}
308312
309- func (s * SeenTracker ) checkArray (node * unstable.Node ) error {
313+ func (s * SeenTracker ) checkArray (node * unstable.Node ) ( first bool , err error ) {
310314 it := node .Children ()
311315 for it .Next () {
312316 n := it .Node ()
313317 switch n .Kind {
314318 case unstable .InlineTable :
315- err : = s .checkInlineTable (n )
319+ first , err = s .checkInlineTable (n )
316320 if err != nil {
317- return err
321+ return false , err
318322 }
319323 case unstable .Array :
320- err : = s .checkArray (n )
324+ first , err = s .checkArray (n )
321325 if err != nil {
322- return err
326+ return false , err
323327 }
324328 }
325329 }
326- return nil
330+ return first , nil
327331}
328332
329- func (s * SeenTracker ) checkInlineTable (node * unstable.Node ) error {
333+ func (s * SeenTracker ) checkInlineTable (node * unstable.Node ) ( first bool , err error ) {
330334 if pool .New == nil {
331335 pool .New = func () interface {} {
332336 return & SeenTracker {}
@@ -339,9 +343,9 @@ func (s *SeenTracker) checkInlineTable(node *unstable.Node) error {
339343 it := node .Children ()
340344 for it .Next () {
341345 n := it .Node ()
342- err : = s .checkKeyValue (n )
346+ first , err = s .checkKeyValue (n )
343347 if err != nil {
344- return err
348+ return false , err
345349 }
346350 }
347351
@@ -352,5 +356,5 @@ func (s *SeenTracker) checkInlineTable(node *unstable.Node) error {
352356 // redefinition of its keys: check* functions cannot walk into
353357 // a value.
354358 pool .Put (s )
355- return nil
359+ return first , nil
356360}
0 commit comments