private async Task WriteObjectPropertyDeserializationAsync(
            CodeWriter writer,
            IResultParserTypeDescriptor possibleType,
            string jsonElement,
            ITypeLookup typeLookup)
        {
            for (int i = 0; i < possibleType.ResultDescriptor.Fields.Count; i++)
            {
                IFieldDescriptor fieldDescriptor = possibleType.ResultDescriptor.Fields[i];

                await writer.WriteIndentAsync().ConfigureAwait(false);

                if (fieldDescriptor.Type.NamedType().IsLeafType())
                {
                    ITypeInfo typeInfo = typeLookup.GetTypeInfo(
                        fieldDescriptor.Type,
                        true);

                    string deserializeMethod =
                        SerializerNameUtils.CreateDeserializerName(
                            fieldDescriptor.Type);

                    await writer.WriteAsync(deserializeMethod).ConfigureAwait(false);

                    await writer.WriteAsync('(').ConfigureAwait(false);

                    await writer.WriteAsync(jsonElement).ConfigureAwait(false);

                    await writer.WriteAsync(", \"").ConfigureAwait(false);

                    await writer.WriteAsync(fieldDescriptor.ResponseName).ConfigureAwait(false);

                    await writer.WriteAsync("\")").ConfigureAwait(false);
                }
                else
                {
                    await writer.WriteAsync("Parse").ConfigureAwait(false);

                    await writer.WriteAsync(GetPathName(fieldDescriptor.Path))
                    .ConfigureAwait(false);

                    await writer.WriteAsync('(').ConfigureAwait(false);

                    await writer.WriteAsync(jsonElement).ConfigureAwait(false);

                    await writer.WriteAsync(", \"").ConfigureAwait(false);

                    await writer.WriteAsync(fieldDescriptor.ResponseName).ConfigureAwait(false);

                    await writer.WriteAsync("\")").ConfigureAwait(false);
                }

                if (i < possibleType.ResultDescriptor.Fields.Count - 1)
                {
                    await writer.WriteAsync(',').ConfigureAwait(false);
                }

                await writer.WriteLineAsync().ConfigureAwait(false);
            }
        }
        private async Task WriteDeserializeMethodAsync(
            CodeWriter writer,
            IResultParserTypeDescriptor possibleType,
            ITypeLookup typeLookup,
            ISet <string> generatedMethods)
        {
            bool first = true;

            foreach (IFieldDescriptor fieldDescriptor in possibleType.ResultDescriptor.Fields)
            {
                if (fieldDescriptor.Type.NamedType().IsLeafType())
                {
                    ITypeInfo typeInfo = typeLookup.GetTypeInfo(
                        fieldDescriptor.Type,
                        false);

                    string methodName = CreateDeserializerName(typeInfo);

                    if (generatedMethods.Add(methodName))
                    {
                        string serializerMethod = _jsonMethod[typeInfo.SerializationType];

                        if (fieldDescriptor.Type.IsListType() &&
                            fieldDescriptor.Type.ListType().ElementType.IsListType())
                        {
                            if (!first)
                            {
                                await writer.WriteLineAsync();
                            }
                            first = false;
                            await WriteDeserializeNestedLeafList(
                                writer, methodName, typeInfo, serializerMethod);
                        }
                        else if (fieldDescriptor.Type.IsListType() &&
                                 fieldDescriptor.Type.ListType().ElementType.IsLeafType())
                        {
                            if (!first)
                            {
                                await writer.WriteLineAsync();
                            }
                            first = false;
                            await WriteDeserializeLeafList(
                                writer, methodName, typeInfo, serializerMethod);
                        }
                        else
                        {
                            if (!first)
                            {
                                await writer.WriteLineAsync();
                            }
                            first = false;
                            await WriteDeserializeLeaf(
                                writer, methodName, typeInfo, serializerMethod);
                        }
                    }
                }
            }
        }
        private async Task WriteOperationNullChecksAsync(
            CodeWriter writer,
            IOperationDescriptor operation,
            ITypeLookup typeLookup)
        {
            int checks = 0;

            for (int j = 0; j < operation.Arguments.Count; j++)
            {
                Descriptors.IArgumentDescriptor argument =
                    operation.Arguments[j];

                bool needsNullCheck = argument.Type.IsNonNullType();

                if (needsNullCheck && argument.Type.IsLeafType())
                {
                    ITypeInfo argumentType = typeLookup.GetTypeInfo(
                        argument.Type,
                        true);
                    needsNullCheck = !argumentType.IsValueType;
                }

                if (argument.Type.IsNonNullType())
                {
                    if (checks > 0)
                    {
                        await writer.WriteLineAsync().ConfigureAwait(false);
                    }

                    checks++;

                    await writer.WriteIndentAsync().ConfigureAwait(false);

                    await writer.WriteAsync($"if ({argument.Name} is null)")
                    .ConfigureAwait(false);

                    await writer.WriteLineAsync().ConfigureAwait(false);

                    await writer.WriteIndentAsync().ConfigureAwait(false);

                    await writer.WriteAsync('{').ConfigureAwait(false);

                    await writer.WriteLineAsync().ConfigureAwait(false);

                    using (writer.IncreaseIndent())
                    {
                        await writer.WriteIndentAsync().ConfigureAwait(false);

                        await writer.WriteAsync(
                            $"throw new ArgumentNullException(nameof({argument.Name}));")
                        .ConfigureAwait(false);

                        await writer.WriteLineAsync().ConfigureAwait(false);
                    }

                    await writer.WriteIndentAsync().ConfigureAwait(false);

                    await writer.WriteAsync('}').ConfigureAwait(false);

                    await writer.WriteLineAsync().ConfigureAwait(false);
                }
            }
        }
        private async Task WriteObjectPropertyDeserializationAsync(
            CodeWriter writer,
            IResultParserTypeDescriptor possibleType,
            string jsonElement,
            string entityField,
            ITypeLookup typeLookup)
        {
            foreach (IFieldDescriptor fieldDescriptor in possibleType.ResultDescriptor.Fields)
            {
                await writer.WriteIndentAsync();

                await writer.WriteAsync(entityField);

                await writer.WriteAsync('.');

                await writer.WriteAsync(GetPropertyName(fieldDescriptor.ResponseName));

                await writer.WriteAsync(" = ");

                if (fieldDescriptor.Type.NamedType().IsLeafType())
                {
                    ITypeInfo typeInfo = typeLookup.GetTypeInfo(
                        fieldDescriptor.Type,
                        true);

                    string deserializeMethod =
                        ResultParserDeserializeMethodGenerator.CreateDeserializerName(typeInfo);

                    await writer.WriteAsync('(');

                    await writer.WriteAsync(typeInfo.ClrTypeName);

                    await writer.WriteAsync(')');

                    await writer.WriteAsync(deserializeMethod);

                    await writer.WriteAsync('(');

                    await writer.WriteAsync(jsonElement);

                    await writer.WriteAsync(", \"");

                    await writer.WriteAsync(fieldDescriptor.ResponseName);

                    await writer.WriteAsync("\");");
                }
                else
                {
                    await writer.WriteAsync("Parse");

                    await writer.WriteAsync(GetPathName(fieldDescriptor.Path));

                    await writer.WriteAsync('(');

                    await writer.WriteAsync(jsonElement);

                    await writer.WriteAsync(", \"");

                    await writer.WriteAsync(fieldDescriptor.ResponseName);

                    await writer.WriteAsync("\");");
                }

                await writer.WriteLineAsync();
            }
        }