Exemplo n.º 1
0
        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, "}");
        }
Exemplo n.º 2
0
        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, "}");
        }
Exemplo n.º 3
0
        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, "}");
        }