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