Skip to content

Commit 7c7b879

Browse files
committed
done SimpleObjectConverter source generator
1 parent e251e1f commit 7c7b879

File tree

2 files changed

+82
-42
lines changed

2 files changed

+82
-42
lines changed

sandbox/ConsoleApp1/Program.cs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,28 @@
99
using System.Text.Json.Serialization;
1010
using System.Xml.Linq;
1111

12-
var arrayBufferWriter = new ArrayBufferWriter<byte>();
13-
var toonWriter = ToonWriter.Create(ref arrayBufferWriter);
1412

15-
// write as NonUniform Array
16-
toonWriter.WriteStartNonUniformArray(2);
17-
18-
toonWriter.WriteNextRowOfNonUniformArray();
19-
toonWriter.WriteNumber(1);
20-
21-
toonWriter.WriteNextRowOfNonUniformArray();
22-
toonWriter.WriteString(MyEnum.Orange);
23-
24-
toonWriter.WriteEndNonUniformArray();
25-
26-
toonWriter.Flush();
27-
28-
// toonWriter.WritePropertyName("
13+
var str = Cysharp.AI.Converters.SimpleClassSimpleObjectConverter.Encode(new SimpleClass
14+
{
15+
Id = 1,
16+
Name = "Test",
17+
NotMyUser = new[]
18+
{
19+
new User(1, "User1", "Admin", DateTime.Now, DateTimeOffset.Now, TimeSpan.FromHours(1), MyEnum.Fruit),
20+
new User(2, "User2", "User", DateTime.Now, DateTimeOffset.Now, TimeSpan.FromHours(2), MyEnum.Orange),
21+
},
22+
Me = MyEnum.Apple,
23+
MyProperty = new[] { 1, 2, 3, 4, 5 },
24+
MyUser = new[]
25+
{
26+
new User(1, "User1", "Admin", DateTime.Now, DateTimeOffset.Now, TimeSpan.FromHours(1), MyEnum.Fruit),
27+
new User(2, "User2", "User", DateTime.Now, DateTimeOffset.Now, TimeSpan.FromHours(2), MyEnum.Orange),
28+
}
29+
});
2930

30-
var str = Encoding.UTF8.GetString(arrayBufferWriter.WrittenSpan);
3131
Console.WriteLine(str);
3232

3333

34-
var array = new byte[] { 1, 2, 3 };
35-
36-
toonWriter.WriteStartInlineArray(19);
37-
foreach (var item in array)
38-
{
39-
toonWriter.WriteNumber(item);
40-
}
41-
42-
toonWriter.WriteEndInlineArray();
43-
4434

4535
[GenerateToonTabularArrayConverter]
4636
public record User(int Id, string Name, string Role, DateTime dt, DateTimeOffset dt2, TimeSpan ts, MyEnum me);
@@ -51,9 +41,11 @@ public class SimpleClass
5141
{
5242
public int Id { get; set; }
5343
public string? Name { get; set; }
44+
public User[]? NotMyUser { get; set; }
5445
public MyEnum Me { get; set; }
5546
public int[]? MyProperty { get; set; }
56-
// public User[]? MyUser { get; set; }
47+
public User[]? MyUser { get; set; }
48+
// public User2 MyProperty1000 { get; set; }
5749
}
5850

5951

@@ -62,3 +54,7 @@ public enum MyEnum
6254
Fruit, Orange, Apple
6355
}
6456

57+
public class User2
58+
{
59+
public List<int>? MyProperty2 { get; set; }
60+
}

src/ToonEncoder.Generator/ToonEncoderGenerator.cs

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,23 @@ static void EmitSimpleObjectConverter(SourceProductionContext sourceProductionCo
216216
}
217217

218218
var converterName = $"{objectInfo.ElementFullName.Replace("global::", "").Replace(".", "_")}SimpleObjectConverter";
219-
var objectType = $"{objectInfo.ElementFullName}"; // TODO: nullable check
219+
var objectType = $"{objectInfo.ElementFullName}" + (objectInfo.IsReferenceType ? "?" : "");
220220

221-
// TODO: utf8Fields
222-
// var utf8FieldNames = string.Join(", ", objectInfo.PropertyNames.Select(n => $"\"{n}\"u8.ToArray()"));
221+
List<(string PropName, string Utf8FieldNames)> nestedUtf8FieldNames = new();
222+
for (int i = 0; i < objectInfo.PropertyKinds!.Length; i++)
223+
{
224+
if (objectInfo.PropertyKinds[i] == ToonPrimitiveKind.Array)
225+
{
226+
var arrayInfo = objectInfo.NestedArrayInfos![i]!;
227+
if (arrayInfo.PrimitiveKind == ToonPrimitiveKind.Object)
228+
{
229+
var utf8FieldNames = string.Join(", ", arrayInfo.PropertyNames.Select(n => $"\"{n}\"u8.ToArray()"));
230+
nestedUtf8FieldNames.Add((objectInfo.PropertyNames![i], utf8FieldNames));
231+
}
232+
}
233+
}
234+
235+
var utf8FieldNamesDeclaration = string.Join("\n", nestedUtf8FieldNames.Select(x => $" static readonly ReadOnlyMemory<byte>[] {x.PropName}_utf8FieldNames = [{x.Utf8FieldNames}];"));
223236

224237
const string defaultIndent = " ";
225238
var encodeRow = new StringBuilder();
@@ -258,23 +271,46 @@ void EmitValueLine(string instanceName, string propertyName, ToonPrimitiveKind k
258271
case ToonPrimitiveKind.Array:
259272
if (arrayInfo!.IsPrimitiveOrArray) // verified, it is not array.
260273
{
274+
// InlineArray
261275
encodeRow.AppendLine(indent + $"if ({name} == null)");
262276
encodeRow.AppendLine(indent + "{");
263277
encodeRow.AppendLine(indent + " toonWriter.WriteNull();");
264278
encodeRow.AppendLine(indent + "}");
265279
encodeRow.AppendLine(indent + "else");
266280
encodeRow.AppendLine(indent + "{");
267-
encodeRow.AppendLine(indent + $" toonWriter.WriteStartInlineArray({name}.Length)");
281+
encodeRow.AppendLine(indent + $" toonWriter.WriteStartInlineArray({name}.Length);");
268282
encodeRow.AppendLine(indent + $" foreach (var item in {name})");
269283
encodeRow.AppendLine(indent + " {");
270284
EmitValueLine("item", "", arrayInfo.PrimitiveKind, null, indent + " ");
271285
encodeRow.AppendLine(indent + " }");
272-
encodeRow.AppendLine(indent + " toonWriter.WriteEndInlineArray()");
286+
encodeRow.AppendLine(indent + " toonWriter.WriteEndInlineArray();");
273287
encodeRow.AppendLine(indent + "}");
274288
}
275289
else
276290
{
277-
// TODO: TabularArray
291+
// TabularArray
292+
encodeRow.AppendLine(indent + $"if ({name} == null)");
293+
encodeRow.AppendLine(indent + "{");
294+
encodeRow.AppendLine(indent + " toonWriter.WriteNull();");
295+
encodeRow.AppendLine(indent + "}");
296+
encodeRow.AppendLine(indent + "else");
297+
encodeRow.AppendLine(indent + "{");
298+
encodeRow.AppendLine(indent + $" toonWriter.WriteStartTabularArray({name}.Length, {propertyName}_utf8FieldNames, escaped: true);");
299+
encodeRow.AppendLine(indent + $" foreach (var item in {name})");
300+
encodeRow.AppendLine(indent + " {");
301+
encodeRow.AppendLine(indent + " toonWriter.WriteNextRowOfTabularArray();");
302+
303+
for (var j = 0; j < arrayInfo.PropertyNames!.Length; j++)
304+
{
305+
var propName = arrayInfo.PropertyNames[j];
306+
var propKind = arrayInfo.PropertyKinds![j];
307+
var propArrayInfo = arrayInfo.NestedArrayInfos![j];
308+
EmitValueLine("item", propName, propKind, propArrayInfo, indent + " ");
309+
}
310+
311+
encodeRow.AppendLine(indent + " }");
312+
encodeRow.AppendLine(indent + " toonWriter.WriteEndTabularArray();");
313+
encodeRow.AppendLine(indent + "}");
278314
}
279315
break;
280316
case ToonPrimitiveKind.Object: // already verified, not come here.
@@ -284,6 +320,18 @@ void EmitValueLine(string instanceName, string propertyName, ToonPrimitiveKind k
284320
}
285321
}
286322

323+
var emitWriteNull = """
324+
if (value == null)
325+
{
326+
toonWriter.WriteNull();
327+
return;
328+
}
329+
""";
330+
if (!objectInfo.IsReferenceType)
331+
{
332+
emitWriteNull = "";
333+
}
334+
287335
var source = $$"""
288336
// <auto-generated/>
289337
#pragma warning disable
@@ -304,8 +352,7 @@ namespace Cysharp.AI.Converters
304352
{
305353
public class {{converterName}} : JsonConverter<{{objectType}}>
306354
{
307-
// fieldNames for tabular-array
308-
//static readonly ReadOnlyMemory<byte>[] utf8FieldNames = ["Id"u8.ToArray(), "Name"u8.ToArray(), "Role"u8.ToArray(), "dt"u8.ToArray(), "dt2"u8.ToArray(), "ts"u8.ToArray(), "me"u8.ToArray()];
355+
{{utf8FieldNamesDeclaration}}
309356
310357
public static string Encode({{objectType}} value)
311358
{
@@ -353,11 +400,7 @@ public static void Encode<TBufferWriter>(ref TBufferWriter bufferWriter, {{objec
353400
public static void Encode<TBufferWriter>(ref ToonWriter<TBufferWriter> toonWriter, {{objectType}} value)
354401
where TBufferWriter : IBufferWriter<byte>
355402
{
356-
if (value == null)
357-
{
358-
toonWriter.WriteNull();
359-
return;
360-
}
403+
{{emitWriteNull}}
361404
362405
toonWriter.WriteStartObject();
363406
@@ -403,8 +446,8 @@ public Location CreateLocation()
403446
public record ToonObjectInfo
404447
{
405448
public string ElementFullName { get; }
449+
public bool IsReferenceType { get; }
406450
public LocationSlim Location { get; }
407-
408451
public ToonPrimitiveKind PrimitiveKind { get; }
409452

410453
[MemberNotNullWhen(false, nameof(PropertyNames), nameof(PropertyKinds), nameof(NestedArrayInfos))]
@@ -420,6 +463,7 @@ public record ToonObjectInfo
420463
public ToonObjectInfo(ITypeSymbol symbol)
421464
{
422465
ElementFullName = symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
466+
IsReferenceType = symbol.IsReferenceType;
423467

424468
var location = symbol.Locations.FirstOrDefault();
425469
if (location != null)

0 commit comments

Comments
 (0)