private void AppendDeserializeLeaf(
            StringBuilder body,
            ResultParserDeserializerMethodDescriptor methodDescriptor,
            ResultTypeComponentDescriptor type,
            string indent)
        {
            AppendNullHandling(
                body,
                "obj",
                "value",
                IsNullable(type),
                indent,
                string.Empty);

            body.AppendLine();
            body.AppendLine();

            body.Append($"return ");

            AppendDeserializeLeafValue(
                body,
                methodDescriptor.Serializer.FieldName,
                "value",
                methodDescriptor.SerializationType,
                methodDescriptor.RuntimeType,
                IsNullable(type));

            body.Append(";");
        }
        private void AddDeserializeMethod(
            ClassBuilder classBuilder,
            ResultParserDeserializerMethodDescriptor methodDescriptor,
            string indent)
        {
            ImmutableQueue <ResultTypeComponentDescriptor> runtimeTypeComponents =
                ImmutableQueue.CreateRange <ResultTypeComponentDescriptor>(
                    methodDescriptor.RuntimeTypeComponents);

            classBuilder.AddMethod(
                MethodBuilder.New()
                .SetAccessModifier(AccessModifier.Private)
                .SetInheritance(Inheritance.Override)
                .SetReturnType(
                    $"{methodDescriptor.RuntimeType}?",
                    IsNullable(methodDescriptor.RuntimeTypeComponents))
                .SetReturnType(
                    $"{methodDescriptor.RuntimeType}",
                    !IsNullable(methodDescriptor.RuntimeTypeComponents))
                .SetName(methodDescriptor.Name)
                .AddParameter(ParameterBuilder.New()
                              .SetType(Types.JsonElement)
                              .SetName("obj"))
                .AddParameter(ParameterBuilder.New()
                              .SetType("string")
                              .SetName("field"))
                .AddCode(CreateDeserializeMethodBody(
                             methodDescriptor, runtimeTypeComponents, indent)));
        }
        private void AppendDeserializeLeafList(
            StringBuilder body,
            ResultParserDeserializerMethodDescriptor methodDescriptor,
            ResultTypeComponentDescriptor type,
            ImmutableQueue <ResultTypeComponentDescriptor> runtimeTypeComponents,
            string indent)
        {
            AppendNullHandling(
                body,
                "obj",
                "value",
                IsNullable(type),
                indent,
                string.Empty);

            body.AppendLine();
            body.AppendLine();

            AppendList(
                body,
                new ListInfo(
                    "value",
                    "i",
                    "count",
                    "element",
                    "result",
                    type.Name),
                IsNullable(runtimeTypeComponents.Peek()),
                initialIndent => AppendSetLeafElement(
                    body,
                    "result",
                    "i",
                    methodDescriptor.Serializer.FieldName,
                    "element",
                    methodDescriptor.SerializationType,
                    runtimeTypeComponents.Peek().Name,
                    IsNullable(runtimeTypeComponents.Peek()),
                    initialIndent),
                indent, string.Empty);

            body.AppendLine();
            body.AppendLine();
            body.AppendLine("return result;");
        }
        private CodeBlockBuilder CreateDeserializeMethodBody(
            ResultParserDeserializerMethodDescriptor methodDescriptor,
            ImmutableQueue <ResultTypeComponentDescriptor> runtimeTypeComponents,
            string indent)
        {
            var body = new StringBuilder();

            ImmutableQueue <ResultTypeComponentDescriptor> next =
                runtimeTypeComponents.Dequeue(out ResultTypeComponentDescriptor type);

            if (type.IsList && next.Peek().IsList)
            {
            }
            else if (type.IsList)
            {
                AppendDeserializeLeafList(body, methodDescriptor, type, next, indent);
            }
            else
            {
                AppendDeserializeLeaf(body, methodDescriptor, type, indent);
            }

            return(CodeBlockBuilder.FromStringBuilder(body));
        }