public void Generate(JsonClass jsonClass, CodeBuilder codeBuilder) { if (jsonClass.ReadOnly) { return; } if (jsonClass.StructRef) { codeBuilder.AppendLine(2, $"public ReadOnlySpan<char> FromJson(ref {jsonClass.FullName} value, ReadOnlySpan<char> json)"); } else { codeBuilder.AppendLine(2, $"public ReadOnlySpan<char> FromJson({jsonClass.FullName} value, ReadOnlySpan<char> json)"); } codeBuilder.AppendLine(2, "{"); codeBuilder.AppendLine(3, "json = json.SkipWhitespaceTo('{');"); var properties = new List <JsonPropertyInstance>(); foreach (var property in jsonClass.Properties) { string wasSetVariable = null; if (property.Optional) { var generator = _getGeneratorForType(property.Type); wasSetVariable = generator.OnNewObject(codeBuilder, 3, propertyValue => $"value.{property.CodeName} = {propertyValue};"); } properties.Add(new JsonPropertyInstance(property.Type, property.JsonName, property.CodeName, property.Optional, wasSetVariable)); } codeBuilder.AppendLine(3, "while(true)"); codeBuilder.AppendLine(3, "{"); codeBuilder.AppendLine(4, "json = json.SkipWhitespace();"); string valueVariable = $"value{UniqueNumberGenerator.UniqueNumber}"; codeBuilder.AppendLine(4, $"char {valueVariable} = json[0];"); codeBuilder.AppendLine(4, $"if({valueVariable} == '\\\"')"); codeBuilder.AppendLine(4, "{"); codeBuilder.AppendLine(5, "json = json.Slice(1);"); codeBuilder.AppendLine(4, "}"); codeBuilder.AppendLine(4, $"else if({valueVariable} == '}}')"); codeBuilder.AppendLine(4, "{"); foreach (var property in properties) { if (property.Optional) { var generator = _getGeneratorForType(property.Type); generator.OnObjectFinished(codeBuilder, 5, propertyValue => $"value.{property.CodeName} = {propertyValue};", property.WasSetVariable); } } codeBuilder.AppendLine(5, "return json.Slice(1);"); codeBuilder.AppendLine(4, "}"); codeBuilder.AppendLine(4, "else"); codeBuilder.AppendLine(4, "{"); codeBuilder.AppendLine(5, $"throw new InvalidJsonException($\"Unexpected character! expected '}}}}' or '\\\"' but got '{{{valueVariable}}}'\", json);"); codeBuilder.AppendLine(4, "}"); codeBuilder.AppendLine(4, "var propertyName = json.ReadTo('\\\"');"); codeBuilder.AppendLine(4, "json = json.Slice(propertyName.Length + 1);"); codeBuilder.AppendLine(4, "json = json.SkipWhitespaceTo(':');"); GenerateProperties(properties, 4, codeBuilder); codeBuilder.AppendLine(4, "json = json.SkipWhitespace();"); codeBuilder.AppendLine(4, "if(json[0] == ',')"); codeBuilder.AppendLine(4, "{"); codeBuilder.AppendLine(5, "json = json.Slice(1);"); codeBuilder.AppendLine(4, "}"); codeBuilder.AppendLine(3, "}"); codeBuilder.AppendLine(2, "}"); }
public void GenerateUtf8(JsonClass jsonClass, CodeBuilder codeBuilder) { if (jsonClass.ReadOnly) { return; } if (jsonClass.StructRef) { codeBuilder.AppendLine(2, $"public ReadOnlySpan<byte> FromJson(ref {jsonClass.FullName} value, ReadOnlySpan<byte> json)"); } else { codeBuilder.AppendLine(2, $"public ReadOnlySpan<byte> FromJson({jsonClass.FullName} value, ReadOnlySpan<byte> json)"); } codeBuilder.AppendLine(2, "{"); codeBuilder.AppendLine(3, "json = json.SkipToOpenCurlyBracket();"); var properties = new List <JsonPropertyInstance>(); foreach (var property in jsonClass.Properties) { string wasSetVariable = null; if (property.Optional) { var generator = _getGeneratorForType(property.Type); wasSetVariable = generator.OnNewObject(codeBuilder, 3, propertyValue => $"value.{property.CodeName} = {propertyValue};"); } properties.Add(new JsonPropertyInstance(property.Type, property.JsonName, property.CodeName, property.Optional, wasSetVariable)); } codeBuilder.AppendLine(3, "while(true)"); codeBuilder.AppendLine(3, "{"); codeBuilder.AppendLine(4, "int jsonIndex = 0;"); codeBuilder.AppendLine(4, "for (; jsonIndex < json.Length; jsonIndex++)"); codeBuilder.AppendLine(4, "{"); codeBuilder.AppendLine(4, " switch (json[jsonIndex])"); codeBuilder.AppendLine(4, " {"); codeBuilder.AppendLine(4, " case (byte)'\"':"); codeBuilder.AppendLine(4, " jsonIndex++;"); codeBuilder.AppendLine(4, " goto after;"); codeBuilder.AppendLine(4, " case (byte)'}':"); foreach (var property in properties) { if (property.Optional) { var generator = _getGeneratorForType(property.Type); generator.OnObjectFinished(codeBuilder, 7, propertyValue => $"value.{property.CodeName} = {propertyValue};", property.WasSetVariable); } } codeBuilder.AppendLine(4, " return json.Slice(jsonIndex + 1);"); codeBuilder.AppendLine(4, " default:"); codeBuilder.AppendLine(4, " continue;"); codeBuilder.AppendLine(4, " }"); codeBuilder.AppendLine(4, "}"); codeBuilder.AppendLine(4, "throw new InvalidJsonException($\"Unexpected character! expected '}}' or '\\\"' but got '{(char)json[jsonIndex]}'\", Encoding.UTF8.GetString(json));"); codeBuilder.AppendLine(4, "after:"); codeBuilder.AppendLine(4, "json = json.Slice(jsonIndex);"); codeBuilder.AppendLine(4, "var propertyName = json.ReadToQuote();"); codeBuilder.AppendLine(4, "json = json.Slice(propertyName.Length + 1);"); codeBuilder.AppendLine(4, "json = json.SkipToColon();"); GenerateProperties(properties, 4, codeBuilder, JsonFormat.UTF8); codeBuilder.AppendLine(3, "}"); codeBuilder.AppendLine(2, "}"); }
public void Generate(JsonClass jsonClass, CodeBuilder classBuilder) { if (jsonClass.StructRef) { classBuilder.AppendLine(2, $"public ReadOnlySpan<char> ToJson(ref {jsonClass.FullName} value)"); } else { classBuilder.AppendLine(2, $"public ReadOnlySpan<char> ToJson({jsonClass.FullName} value)"); } classBuilder.AppendLine(2, "{"); classBuilder.AppendLine(0, BuilderText); if (jsonClass.StructRef) { classBuilder.AppendLine(3, "ToJson(ref value, builder);"); } else { classBuilder.AppendLine(3, "ToJson(value, builder);"); } classBuilder.AppendLine(3, "return builder.AsSpan();"); classBuilder.AppendLine(2, "}"); if (jsonClass.StructRef) { classBuilder.AppendLine(2, $"public void ToJson(ref {jsonClass.FullName} value, JsonStringBuilder builder)"); } else { classBuilder.AppendLine(2, $"public void ToJson({jsonClass.FullName} value, JsonStringBuilder builder)"); } classBuilder.AppendLine(2, "{"); var appendBuilder = new StringBuilder(); appendBuilder.Append("{"); bool isFirst = true; foreach (var property in jsonClass.Properties.OrderBy(p => p.JsonName)) { int indent = 3; if (jsonClass.IgnoreNull && property.Type.CanBeNull) { classBuilder.MakeAppend(indent, appendBuilder, JsonFormat.String); classBuilder.AppendLine(indent, $"if(value.{property.CodeName} != null)"); classBuilder.AppendLine(indent, "{"); indent++; } if (!isFirst) { appendBuilder.Append(","); } appendBuilder.Append($"\\\""); appendBuilder.AppendDoubleEscaped(property.JsonName); appendBuilder.Append($"\\\":"); var generator = GetGeneratorForType(property.Type); bool canBeNull = jsonClass.IgnoreNull ? false : property.Type.CanBeNull; generator.GenerateToJson(classBuilder, indent, appendBuilder, property.Type, $"value.{property.CodeName}", canBeNull, JsonFormat.String); if (jsonClass.IgnoreNull && property.Type.CanBeNull) { indent--; classBuilder.AppendLine(indent, "}"); } if (isFirst) { isFirst = false; } } appendBuilder.Append("}"); classBuilder.MakeAppend(3, appendBuilder, JsonFormat.String); classBuilder.AppendLine(2, "}"); }