@@ -207,82 +207,52 @@ func (o *CandidateNode) goccyProcessMappingValueNode(mappingEntry *ast.MappingVa
207
207
return nil
208
208
}
209
209
210
- func (o * CandidateNode ) goccyMarshalChild (path string ) (ast.Node , error ) {
211
- var node ast.Node
212
- switch o .Kind {
213
- case SequenceNode :
214
- values := make ([]ast.Node , len (o .Content ))
215
- for i , content := range o .Content {
216
- childNode , err := content .goccyMarshalChild (path + "[" + strconv .Itoa (i ) + "]" )
217
- if err != nil {
218
- return nil , err
219
- }
220
-
221
- values [i ] = childNode
222
- }
223
-
224
- seq := ast .Sequence (
225
- goccyToken .SequenceStart (o .Value , & goccyToken.Position {}),
226
- o .Style == FlowStyle ,
227
- )
228
-
229
- seq .Values = values
230
- seq .ValueHeadComments = []* ast.CommentGroupNode {ast .CommentGroup ([]* goccyToken.Token {goccyToken .Comment (o .HeadComment , o .HeadComment , & goccyToken.Position {})})}
231
- seq .FootComment = goccyMarshalFootComment (o .FootComment )
232
- node = seq
233
- case MappingNode :
234
- values := make ([]* ast.MappingValueNode , len (o .Content )/ 2 )
235
- for i := 0 ; i < len (o .Content ); i += 2 {
236
- key , err := o .Content [i ].goccyMarshalMapKeyNode (path )
237
- if err != nil {
238
- return nil , err
239
- }
210
+ func (o * CandidateNode ) MarshalGoccyYAML () (ast.Node , error ) {
211
+ marshaller := & goccyMarshaller {}
212
+ return marshaller .Marshal ("$" , o )
213
+ }
240
214
241
- value , err := o .Content [i + 1 ].goccyMarshalChild (key .GetPath ())
242
- if err != nil {
243
- return nil , err
244
- }
215
+ type goccyMarshaller struct {
216
+ currentToken * goccyToken.Token
217
+ }
245
218
246
- childNode := ast .MappingValue (
247
- goccyToken .MappingValue (& goccyToken.Position {}),
248
- key ,
249
- value ,
250
- )
251
- childNode .SetPath (key .GetPath ())
252
- if o .Content [i ].FootComment != "" {
253
- childNode .FootComment = goccyMarshalFootComment (o .Content [i ].FootComment )
254
- }
219
+ func (m * goccyMarshaller ) PushToken (t * goccyToken.Token ) * goccyToken.Token {
220
+ if m .currentToken == nil {
221
+ m .currentToken = t
222
+ return m .currentToken
223
+ }
255
224
256
- values [i / 2 ] = childNode
257
- }
225
+ m .currentToken .Next = t
226
+ t .Prev = m .currentToken
227
+ m .currentToken = t
258
228
259
- mapping := ast .Mapping (goccyToken .MappingStart ("" , & goccyToken.Position {}), o .Style == FlowStyle , values ... )
260
- if o .FootComment != "" {
261
- mapping .FootComment = goccyMarshalFootComment (o .FootComment )
262
- }
229
+ return m .currentToken
230
+ }
263
231
264
- node = mapping
265
- case ScalarNode :
266
- v , err := o .GetValueRep ()
232
+ func (m * goccyMarshaller ) Marshal (path string , o * CandidateNode ) (ast.Node , error ) {
233
+ var node ast.Node
234
+ var err error
235
+ switch o .Kind {
236
+ case AliasNode :
237
+ node , err = m .marshalAlias (path , o )
267
238
if err != nil {
268
239
return nil , err
269
240
}
270
-
271
- node , err = o . goccyMarshalScalar (path , v )
241
+ case ScalarNode :
242
+ node , err = m . marshalScalar (path , o )
272
243
if err != nil {
273
244
return nil , err
274
245
}
275
- case AliasNode :
276
- value , err := o . Content [ 0 ]. goccyMarshalChild (path )
246
+ case SequenceNode :
247
+ node , err = m . marshalSequence (path , o )
277
248
if err != nil {
278
249
return nil , err
279
250
}
280
-
281
- alias := ast .Alias (goccyToken .Alias (o .Value , & goccyToken.Position {}))
282
- alias .Value = value
283
- node = alias
251
+ case MappingNode :
252
+ node , err = m .marshalMapping (path , o )
284
253
}
285
254
255
+ // TODO: Fix Tag and Anchor tokens
286
256
if o .Tag != "" && ! strings .HasPrefix (o .Tag , "!!" ) {
287
257
tag := ast .Tag (goccyToken .Tag (o .Tag , o .Tag , & goccyToken.Position {}))
288
258
tag .Value = node
@@ -300,25 +270,136 @@ func (o *CandidateNode) goccyMarshalChild(path string) (ast.Node, error) {
300
270
return node , nil
301
271
}
302
272
303
- func (o * CandidateNode ) MarshalGoccyYAML () (ast.Node , error ) {
304
- return o .goccyMarshalChild ("$" )
273
+ func (m * goccyMarshaller ) marshalAlias (path string , o * CandidateNode ) (ast.Node , error ) {
274
+ t := m .PushToken (goccyToken .Alias (o .Value , & goccyToken.Position {}))
275
+ var value ast.Node
276
+ var err error
277
+ value , err = m .Marshal (path , o .Content [0 ])
278
+ if err != nil {
279
+ return nil , err
280
+ }
281
+
282
+ alias := ast .Alias (t )
283
+ alias .Value = value
284
+ return alias , nil
305
285
}
306
286
307
- func goccyMarshalFootComment (comment string ) * ast.CommentGroupNode {
308
- return ast .CommentGroup ([]* goccyToken.Token {goccyToken .Comment (comment , comment , & goccyToken.Position {})})
287
+ func (m * goccyMarshaller ) marshalSequence (path string , o * CandidateNode ) (ast.Node , error ) {
288
+ isFlowStyle := o .Style == FlowStyle
289
+ seq := ast .Sequence (
290
+ nil ,
291
+ isFlowStyle ,
292
+ )
293
+
294
+ if isFlowStyle {
295
+ seq .Start = m .PushToken (goccyToken .SequenceStart ("[" , & goccyToken.Position {}))
296
+ }
297
+
298
+ var err error
299
+ values := make ([]ast.Node , len (o .Content ))
300
+ for i , content := range o .Content {
301
+ m .PushToken (goccyToken .SequenceEntry ("-" , & goccyToken.Position {}))
302
+ values [i ], err = m .Marshal (path + "[" + strconv .Itoa (i )+ "]" , content )
303
+ if err != nil {
304
+ return nil , err
305
+ }
306
+
307
+ if isFlowStyle && i < len (o .Content )- 1 {
308
+ m .PushToken (goccyToken .CollectEntry ("," , & goccyToken.Position {}))
309
+ }
310
+ }
311
+
312
+ if isFlowStyle {
313
+ seq .End = m .PushToken (goccyToken .SequenceEnd ("]" , & goccyToken.Position {}))
314
+ }
315
+
316
+ seq .Values = values
317
+ seq .ValueHeadComments = []* ast.CommentGroupNode {ast .CommentGroup ([]* goccyToken.Token {goccyToken .Comment (o .HeadComment , o .HeadComment , & goccyToken.Position {})})}
318
+ seq .FootComment = goccyMarshalFootComment (o .FootComment )
319
+
320
+ return seq , nil
309
321
}
310
322
311
- func (o * CandidateNode ) goccyMarshalMapKeyNode (path string ) (ast.MapKeyNode , error ) {
312
- if o .Kind != ScalarNode {
313
- return nil , fmt .Errorf ("cannot unmarshal non-scalar node to MapKeyNode" )
323
+ func (m * goccyMarshaller ) marshalMapping (path string , o * CandidateNode ) (ast.Node , error ) {
324
+ isFlowStyle := o .Style == FlowStyle
325
+ mapping := ast .Mapping (nil , isFlowStyle )
326
+
327
+ if isFlowStyle {
328
+ mapping .Start = m .PushToken (goccyToken .MappingStart ("{" , & goccyToken.Position {}))
314
329
}
315
330
316
- v , err := o .GetValueRep ()
331
+ values := make ([]* ast.MappingValueNode , len (o .Content )/ 2 )
332
+ var err error
333
+ for i := 0 ; i < len (o .Content ); i += 2 {
334
+ var childNode * ast.MappingValueNode
335
+ childNode , err = m .marshalMappingValueNode (path , o .Content [i ], o .Content [i + 1 ])
336
+ if err != nil {
337
+ return nil , err
338
+ }
339
+
340
+ if o .Content [i ].FootComment != "" {
341
+ childNode .FootComment = goccyMarshalFootComment (o .Content [i ].FootComment )
342
+ }
343
+
344
+ values [i / 2 ] = childNode
345
+ if isFlowStyle && i < len (o .Content )/ 2 - 1 {
346
+ m .PushToken (goccyToken .CollectEntry ("," , & goccyToken.Position {}))
347
+ }
348
+ }
349
+
350
+ mapping .Values = values
351
+
352
+ if ! isFlowStyle && len (values ) > 0 {
353
+ mapping .Start = values [0 ].Start
354
+ }
355
+
356
+ if isFlowStyle {
357
+ mapping .End = m .PushToken (goccyToken .MappingEnd ("}" , & goccyToken.Position {}))
358
+ }
359
+
360
+ if o .FootComment != "" {
361
+ mapping .FootComment = goccyMarshalFootComment (o .FootComment )
362
+ }
363
+
364
+ return mapping , nil
365
+ }
366
+
367
+ func (m * goccyMarshaller ) marshalMappingValueNode (path string , keyNode , valueNode * CandidateNode ) (* ast.MappingValueNode , error ) {
368
+ var key ast.MapKeyNode
369
+ var err error
370
+ key , err = m .marshalMapKeyNode (path , keyNode )
317
371
if err != nil {
318
372
return nil , err
319
373
}
320
374
321
- key , err := o .goccyMarshalScalar (path , v )
375
+ separatorToken := m .PushToken (goccyToken .MappingValue (& goccyToken.Position {}))
376
+
377
+ value , err := m .Marshal (key .GetPath (), valueNode )
378
+ if err != nil {
379
+ return nil , err
380
+ }
381
+
382
+ childNode := ast .MappingValue (
383
+ separatorToken ,
384
+ key ,
385
+ value ,
386
+ )
387
+ childNode .SetPath (key .GetPath ())
388
+
389
+ return childNode , nil
390
+ }
391
+
392
+ func goccyMarshalFootComment (comment string ) * ast.CommentGroupNode {
393
+ // TODO: Fix Tokens
394
+ return ast .CommentGroup ([]* goccyToken.Token {goccyToken .Comment (comment , comment , & goccyToken.Position {})})
395
+ }
396
+
397
+ func (m * goccyMarshaller ) marshalMapKeyNode (path string , o * CandidateNode ) (ast.MapKeyNode , error ) {
398
+ if o .Kind != ScalarNode {
399
+ return nil , fmt .Errorf ("cannot unmarshal non-scalar node to MapKeyNode" )
400
+ }
401
+
402
+ key , err := m .marshalScalar (path , o )
322
403
if err != nil {
323
404
return nil , err
324
405
}
@@ -327,30 +408,35 @@ func (o *CandidateNode) goccyMarshalMapKeyNode(path string) (ast.MapKeyNode, err
327
408
return key , nil
328
409
}
329
410
330
- func (o * CandidateNode ) goccyMarshalScalar (path string , v any ) (ast.ScalarNode , error ) {
331
- t := goccyToken .Literal (o .Value , o .Value , & goccyToken.Position {})
411
+ func (m * goccyMarshaller ) marshalScalar (path string , o * CandidateNode ) (ast.ScalarNode , error ) {
412
+ v , err := o .GetValueRep ()
413
+ if err != nil {
414
+ return nil , err
415
+ }
416
+
417
+ scalarToken := m .PushToken (goccyToken .Literal (o .Value , o .Value , & goccyToken.Position {}))
332
418
333
419
if v == nil {
334
- n := ast .Null (t )
420
+ n := ast .Null (scalarToken )
335
421
n .SetPath (path )
336
422
return n , nil
337
423
}
338
424
339
425
switch av := v .(type ) {
340
426
case float64 :
341
- n := ast .Float (t )
427
+ n := ast .Float (scalarToken )
342
428
n .Value = av
343
429
return n , nil
344
430
case int64 :
345
- n := ast .Integer (t )
431
+ n := ast .Integer (scalarToken )
346
432
n .Value = av
347
433
return n , nil
348
434
case bool :
349
- n := ast .Bool (t )
435
+ n := ast .Bool (scalarToken )
350
436
n .Value = av
351
437
return n , nil
352
438
case string :
353
- n := ast .String (t )
439
+ n := ast .String (scalarToken )
354
440
n .SetPath (path )
355
441
return n , nil
356
442
}
0 commit comments