protected override async Task WriteAsync(
            CodeWriter writer,
            IInputClassDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            await writer.WriteIndentAsync().ConfigureAwait(false);

            await writer.WriteAsync("public class ").ConfigureAwait(false);

            await writer.WriteAsync(descriptor.Name).ConfigureAwait(false);

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

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

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

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

            using (writer.IncreaseIndent())
            {
                for (int i = 0; i < descriptor.Fields.Count; i++)
                {
                    IInputFieldDescriptor fieldDescriptor = descriptor.Fields[i];

                    string typeName = typeLookup.GetTypeName(
                        fieldDescriptor.Type,
                        fieldDescriptor.InputObjectType?.Name,
                        false);

                    if (i > 0)
                    {
                        await writer.WriteLineAsync().ConfigureAwait(false);
                    }

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

                    await writer.WriteAsync($"public Optional<{typeName}>")
                    .ConfigureAwait(false);

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

                    await writer.WriteAsync(GetPropertyName(fieldDescriptor.Name))
                    .ConfigureAwait(false);

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

                    await writer.WriteAsync("{ get; set; }").ConfigureAwait(false);

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

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

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

            await writer.WriteLineAsync().ConfigureAwait(false);
        }
        protected override async Task WriteAsync(
            CodeWriter writer,
            IClientDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            await writer.WriteIndentAsync().ConfigureAwait(false);

            await writer.WriteAsync(
                $"{ClientAccessModifier} partial interface ")
            .ConfigureAwait(false);

            await writer.WriteAsync(GetInterfaceName(descriptor.Name)).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())
            {
                for (int i = 0; i < descriptor.Operations.Count; i++)
                {
                    IOperationDescriptor operation = descriptor.Operations[i];

                    string typeName = typeLookup.GetTypeName(
                        new NonNullType(operation.OperationType),
                        operation.ResultType.Name,
                        true);

                    if (i > 0)
                    {
                        await writer.WriteLineAsync().ConfigureAwait(false);
                    }

                    await WriteOperationAsync(
                        writer, operation, typeName, true, typeLookup)
                    .ConfigureAwait(false);

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

                    await WriteOperationRequestAsync(
                        writer, operation, typeName, true)
                    .ConfigureAwait(false);
                }
            }

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

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

            await writer.WriteLineAsync().ConfigureAwait(false);
        }
Ejemplo n.º 3
0
        private async Task WriteFieldsAsync(
            CodeWriter writer,
            IOperationDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            if (descriptor.Arguments.Count > 0)
            {
                for (int i = 0; i < descriptor.Arguments.Count; i++)
                {
                    Descriptors.IArgumentDescriptor argument =
                        descriptor.Arguments[i];

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

                    await writer.WriteAsync("private bool _modified_").ConfigureAwait(false);

                    await writer.WriteAsync(GetFieldName(argument.Name)).ConfigureAwait(false);

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

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

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

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

                    string typeName = typeLookup.GetTypeName(
                        argument.Type,
                        argument.Type.NamedType().Name,
                        true);

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

                    await writer.WriteAsync("private ").ConfigureAwait(false);

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

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

                    await writer.WriteAsync("_value_").ConfigureAwait(false);

                    await writer.WriteAsync(GetFieldName(argument.Name)).ConfigureAwait(false);

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

                    await writer.WriteLineAsync().ConfigureAwait(false);
                }
            }
        }
Ejemplo n.º 4
0
        private static async Task WriteArgumentAsync(
            CodeWriter writer,
            Descriptors.IArgumentDescriptor argument,
            ITypeLookup typeLookup)
        {
            string typeName = typeLookup.GetTypeName(
                argument.Type,
                argument.Type.NamedType().Name,
                true);

            await writer.WriteIndentedLineAsync(
                $"public Optional<{typeName}> {GetPropertyName(argument.Name)} {{ get; set; }}")
            .ConfigureAwait(false);
        }
        protected override Task WriteAsync(
            CodeWriter writer,
            IResultParserMethodDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            string resultTypeName = descriptor.ResultSelection is null
                ? descriptor.ResultDescriptor.Name
                : typeLookup.GetTypeName(
                descriptor.ResultSelection,
                descriptor.ResultType,
                true);

            if (descriptor.ResultSelection is null)
            {
                return(WriteOperationSelectionSet(
                           writer, descriptor, typeLookup, resultTypeName));
            }

            return(WriteFieldSelectionSet(
                       writer, descriptor, typeLookup, resultTypeName));
        }
        protected override Task WriteAsync(
            CodeWriter writer,
            IResultParserMethodDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            bool isOperation = descriptor.ResultSelection.Directives.Any(t =>
                                                                         t.Name.Value.EqualsOrdinal(GeneratorDirectives.Operation));

            string resultTypeName = isOperation
                ? descriptor.ResultDescriptor.Name
                : typeLookup.GetTypeName(
                descriptor.ResultType,
                descriptor.ResultSelection,
                true);

            if (isOperation)
            {
                return(WriteParseDataAsync(
                           writer, descriptor, typeLookup, resultTypeName));
            }

            return(WriteFieldSelectionSet(
                       writer, descriptor, typeLookup, resultTypeName));
        }
Ejemplo n.º 7
0
        private async Task WriteArgumentAsync(
            CodeWriter writer,
            Descriptors.IArgumentDescriptor argument,
            ITypeLookup typeLookup)
        {
            string typeName = typeLookup.GetTypeName(
                argument.Type,
                argument.Type.NamedType().Name,
                true);

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

            await writer.WriteAsync("public ").ConfigureAwait(false);

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

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

            await writer.WriteAsync(GetPropertyName(argument.Name)).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("get => ").ConfigureAwait(false);

                await writer.WriteAsync("_value_").ConfigureAwait(false);

                await writer.WriteAsync(GetFieldName(argument.Name)).ConfigureAwait(false);

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

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

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

                await writer.WriteAsync("set").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("_value_").ConfigureAwait(false);

                    await writer.WriteAsync(GetFieldName(argument.Name)).ConfigureAwait(false);

                    await writer.WriteAsync(" = value;").ConfigureAwait(false);

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

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

                    await writer.WriteAsync("_modified_").ConfigureAwait(false);

                    await writer.WriteAsync(GetFieldName(argument.Name)).ConfigureAwait(false);

                    await writer.WriteAsync(" = true;").ConfigureAwait(false);

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

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

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

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

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

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

            await writer.WriteLineAsync().ConfigureAwait(false);
        }
Ejemplo n.º 8
0
        private static async Task WriteConstructorAsync(
            CodeWriter writer,
            IClassDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            await writer.WriteIndentedLineAsync(
                "public {0}(", descriptor.Name)
            .ConfigureAwait(false);

            using (writer.IncreaseIndent())
            {
                for (int i = 0; i < descriptor.Fields.Count; i++)
                {
                    IFieldDescriptor fieldDescriptor = descriptor.Fields[i];

                    string typeName = typeLookup.GetTypeName(
                        fieldDescriptor.Type,
                        fieldDescriptor.Selection,
                        true);

                    string parameterName = GetFieldName(
                        fieldDescriptor.ResponseName);

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

                    await writer.WriteAsync(string.Format(
                                                "{0} {1}", typeName, parameterName))
                    .ConfigureAwait(false);

                    if (i < descriptor.Fields.Count - 1)
                    {
                        await writer.WriteAsync(", ").ConfigureAwait(false);
                    }
                    else
                    {
                        await writer.WriteAsync(")").ConfigureAwait(false);
                    }

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

            await writer.WriteIndentedLineAsync("{").ConfigureAwait(false);

            using (writer.IncreaseIndent())
            {
                for (int i = 0; i < descriptor.Fields.Count; i++)
                {
                    IFieldDescriptor fieldDescriptor = descriptor.Fields[i];

                    string propetyName = GetPropertyName(
                        fieldDescriptor.ResponseName);

                    string parameterName = GetFieldName(
                        fieldDescriptor.ResponseName);

                    await writer.WriteIndentedLineAsync(
                        "{0} = {1};",
                        propetyName,
                        parameterName)
                    .ConfigureAwait(false);
                }
            }

            await writer.WriteIndentedLineAsync("}").ConfigureAwait(false);
        }
Ejemplo n.º 9
0
        protected override async Task WriteAsync(
            CodeWriter writer,
            IClassDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            await writer.WriteIndentAsync().ConfigureAwait(false);

            await writer.WriteAsync("public class ").ConfigureAwait(false);

            await writer.WriteAsync(descriptor.Name).ConfigureAwait(false);

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

            using (writer.IncreaseIndent())
            {
                for (int i = 0; i < descriptor.Implements.Count; i++)
                {
                    await writer.WriteIndentAsync().ConfigureAwait(false);

                    if (i == 0)
                    {
                        await writer.WriteAsync(':').ConfigureAwait(false);
                    }
                    else
                    {
                        await writer.WriteAsync(',').ConfigureAwait(false);
                    }

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

                    await writer.WriteAsync(descriptor.Implements[i].Name).ConfigureAwait(false);

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

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

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

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

            if (descriptor.Fields.Count > 0)
            {
                using (writer.IncreaseIndent())
                {
                    await WriteConstructorAsync(writer, descriptor, typeLookup)
                    .ConfigureAwait(false);

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

                    for (int i = 0; i < descriptor.Fields.Count; i++)
                    {
                        IFieldDescriptor fieldDescriptor = descriptor.Fields[i];

                        string typeName = typeLookup.GetTypeName(
                            fieldDescriptor.Type,
                            fieldDescriptor.Selection,
                            true);

                        string propertyName = GetPropertyName(fieldDescriptor.ResponseName);

                        if (i > 0)
                        {
                            await writer.WriteLineAsync().ConfigureAwait(false);
                        }

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

                        await writer.WriteAsync("public").ConfigureAwait(false);

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

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

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

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

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

                        await writer.WriteAsync("{ get; }").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 WriteOperationAsync(
            CodeWriter writer,
            IOperationDescriptor operation,
            string operationTypeName,
            bool cancellationToken,
            ITypeLookup typeLookup)
        {
            await writer.WriteIndentAsync().ConfigureAwait(false);

            if (operation.Operation.Operation == OperationType.Subscription)
            {
                await writer.WriteAsync(
                    $"Task<IResponseStream<{operationTypeName}>> ")
                .ConfigureAwait(false);
            }
            else
            {
                await writer.WriteAsync(
                    $"Task<IOperationResult<{operationTypeName}>> ")
                .ConfigureAwait(false);
            }
            await writer.WriteAsync(
                $"{GetPropertyName(operation.Operation.Name.Value)}Async(")
            .ConfigureAwait(false);

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

                    if (j > 0)
                    {
                        await writer.WriteAsync(',').ConfigureAwait(false);
                    }

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

                    string argumentType = typeLookup.GetTypeName(
                        argument.Type,
                        argument.Type.NamedType().Name,
                        true);

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

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

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

                    await writer.WriteAsync(GetFieldName(argument.Name))
                    .ConfigureAwait(false);
                }

                if (cancellationToken)
                {
                    if (operation.Arguments.Count > 0)
                    {
                        await writer.WriteAsync(',').ConfigureAwait(false);
                    }

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

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

                    await writer.WriteAsync(
                        "CancellationToken cancellationToken")
                    .ConfigureAwait(false);
                }

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

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

                await writer.WriteLineAsync().ConfigureAwait(false);
            }
        }
Ejemplo n.º 11
0
        protected override async Task WriteAsync(
            CodeWriter writer,
            IClientDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            await writer.WriteIndentAsync().ConfigureAwait(false);

            await writer.WriteAsync("public class ").ConfigureAwait(false);

            await writer.WriteAsync(GetClassName(descriptor.Name)).ConfigureAwait(false);

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

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

                await writer.WriteAsync(": ").ConfigureAwait(false);

                await writer.WriteAsync(GetInterfaceName(descriptor.Name)).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 WriteFieldsAsync(writer, descriptor).ConfigureAwait(false);

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

                await WriteConstructorAsync(writer, descriptor).ConfigureAwait(false);

                for (int i = 0; i < descriptor.Operations.Count; i++)
                {
                    IOperationDescriptor operation = descriptor.Operations[i];

                    string typeName = typeLookup.GetTypeName(
                        new NonNullType(operation.OperationType),
                        operation.ResultType.Name,
                        true);

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

                    await WriteOperationOverloadAsync(
                        writer, operation, typeName, typeLookup)
                    .ConfigureAwait(false);

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

                    await WriteOperationAsync(
                        writer, operation, typeName, typeLookup)
                    .ConfigureAwait(false);
                }
            }

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

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

            await writer.WriteLineAsync().ConfigureAwait(false);
        }
        private async Task WriteListAsync(
            CodeWriter writer,
            IResultParserMethodDescriptor methodDescriptor,
            string jsonElement,
            string elementField,
            string listField,
            ITypeLookup typeLookup)
        {
            IType elementType = methodDescriptor.ResultType.ElementType();

            string resultTypeName = typeLookup.GetTypeName(
                elementType.IsNonNullType() ? elementType : new NonNullType(elementType),
                methodDescriptor.ResultSelection,
                true);

            string lengthField = jsonElement + "Length";
            string indexField  = jsonElement + "Index";

            await writer.WriteIndentedLineAsync(
                "int {0} = {1}.GetArrayLength();",
                lengthField,
                jsonElement)
            .ConfigureAwait(false);

            await writer.WriteIndentedLineAsync(
                "var {0} = new {1}[{2}];",
                listField,
                resultTypeName,
                lengthField)
            .ConfigureAwait(false);

            await writer.WriteIndentedLineAsync(
                "for (int {0} = 0; {0} < {1}; {0}++)",
                indexField,
                lengthField)
            .ConfigureAwait(false);

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

            using (writer.WriteBraces())
            {
                await writer.WriteIndentedLineAsync(
                    "JsonElement {0} = {1}[{2}];",
                    elementField,
                    jsonElement,
                    indexField)
                .ConfigureAwait(false);

                if (elementType.IsListType())
                {
                    await WriteListAsync(
                        writer,
                        methodDescriptor,
                        elementField,
                        "inner" + char.ToUpper(elementField[0]) + elementField.Substring(1),
                        "inner" + char.ToUpper(listField[0]) + listField.Substring(1),
                        typeLookup)
                    .ConfigureAwait(false);
                }
                else
                {
                    if (elementType.IsAbstractType() &&
                        methodDescriptor.PossibleTypes.Count > 1)
                    {
                        await WriteAbstractTypeHandlingAsync(
                            writer,
                            methodDescriptor,
                            typeLookup,
                            elementField,
                            async m =>
                        {
                            await WriteCreateListElementAsync(
                                writer,
                                methodDescriptor,
                                m,
                                elementField,
                                listField,
                                indexField,
                                typeLookup)
                            .ConfigureAwait(false);
                            await writer.WriteIndentedLineAsync("break;").ConfigureAwait(false);
                        });
                    }
                    else
                    {
                        await WriteCreateListElementAsync(
                            writer,
                            methodDescriptor,
                            methodDescriptor.PossibleTypes[0],
                            elementField,
                            listField,
                            indexField,
                            typeLookup)
                        .ConfigureAwait(false);
                    }
                }
            }

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

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

            await writer.WriteIndentedLineAsync("return {0};", listField).ConfigureAwait(false);
        }
Ejemplo n.º 13
0
        protected override async Task WriteAsync(
            CodeWriter writer,
            IInterfaceDescriptor descriptor,
            ITypeLookup typeLookup)
        {
            await writer.WriteIndentAsync();

            await writer.WriteAsync("public interface ");

            await writer.WriteAsync(descriptor.Name);

            await writer.WriteLineAsync();

            using (writer.IncreaseIndent())
            {
                for (int i = 0; i < descriptor.Implements.Count; i++)
                {
                    await writer.WriteIndentAsync();

                    if (i == 0)
                    {
                        await writer.WriteAsync(':');
                    }
                    else
                    {
                        await writer.WriteAsync(',');
                    }

                    await writer.WriteSpaceAsync();

                    await writer.WriteAsync(descriptor.Implements[i].Name);

                    await writer.WriteLineAsync();
                }
            }

            await writer.WriteIndentAsync();

            await writer.WriteAsync("{");

            await writer.WriteLineAsync();

            using (writer.IncreaseIndent())
            {
                if (descriptor.Type is IComplexOutputType complexType)
                {
                    for (int i = 0; i < descriptor.Fields.Count; i++)
                    {
                        IFieldDescriptor fieldDescriptor = descriptor.Fields[i];

                        if (complexType.Fields.ContainsField(
                                fieldDescriptor.Selection.Name.Value))
                        {
                            string typeName = typeLookup.GetTypeName(
                                fieldDescriptor.Selection,
                                fieldDescriptor.Type,
                                true);

                            string propertyName = GetPropertyName(fieldDescriptor.ResponseName);

                            if (i > 0)
                            {
                                await writer.WriteLineAsync();
                            }

                            await writer.WriteIndentAsync();

                            await writer.WriteAsync(typeName);

                            await writer.WriteSpaceAsync();

                            await writer.WriteAsync(propertyName);

                            await writer.WriteSpaceAsync();

                            await writer.WriteAsync("{ get; }");

                            await writer.WriteLineAsync();
                        }
                        else
                        {
                            // TODO : exception
                            // TODO : resources
                            throw new Exception("Unknown field.");
                        }
                    }
                }
            }

            await writer.WriteIndentAsync();

            await writer.WriteAsync("}");

            await writer.WriteLineAsync();
        }
Ejemplo n.º 14
0
        private static async Task WriteOperationSignatureAsync(
            CodeWriter writer,
            IOperationDescriptor operation,
            string operationTypeName,
            ITypeLookup typeLookup)
        {
            await writer.WriteIndentAsync().ConfigureAwait(false);

            await writer.WriteAsync("public ").ConfigureAwait(false);

            if (operation.Operation.Operation == OperationType.Subscription)
            {
                await writer.WriteAsync(
                    "global::System.Threading.Tasks.Task<" +
                    $"global::StrawberryShake.IResponseStream<{operationTypeName}>> ")
                .ConfigureAwait(false);
            }
            else
            {
                await writer.WriteAsync(
                    "global::System.Threading.Tasks.Task<" +
                    $"global::StrawberryShake.IOperationResult<{operationTypeName}>> ")
                .ConfigureAwait(false);
            }
            await writer.WriteAsync(
                $"{GetPropertyName(operation.Operation.Name!.Value)}Async(")
            .ConfigureAwait(false);

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

                    if (j > 0)
                    {
                        await writer.WriteAsync(',')
                        .ConfigureAwait(false);
                    }

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

                    string argumentType = typeLookup.GetTypeName(
                        argument.Type,
                        argument.Type.NamedType().Name,
                        true);

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

                    await writer.WriteAsync(
                        $"global::StrawberryShake.Optional<{argumentType}>")
                    .ConfigureAwait(false);

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

                    await writer.WriteAsync(GetFieldName(argument.Name)).ConfigureAwait(false);

                    await writer.WriteAsync(" = default").ConfigureAwait(false);
                }

                if (operation.Arguments.Count > 0)
                {
                    await writer.WriteAsync(',').ConfigureAwait(false);
                }
                await writer.WriteLineAsync().ConfigureAwait(false);

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

                await writer.WriteAsync(
                    "global::System.Threading.CancellationToken cancellationToken = default")
                .ConfigureAwait(false);

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

                await writer.WriteLineAsync().ConfigureAwait(false);
            }
        }
        private async Task WriteListAsync(
            CodeWriter writer,
            IResultParserMethodDescriptor methodDescriptor,
            IResultParserTypeDescriptor possibleType,
            string jsonElement,
            string elementField,
            string listField,
            string entityField,
            ITypeLookup typeLookup)
        {
            IType elementType = methodDescriptor.ResultType.ElementType();

            string resultTypeName = typeLookup.GetTypeName(
                methodDescriptor.ResultSelection,
                elementType,
                true);

            string lengthField = jsonElement + "Length";
            string indexField  = jsonElement + "Index";

            await writer.WriteIndentAsync();

            await writer.WriteAsync("int ");

            await writer.WriteAsync(lengthField);

            await writer.WriteAsync(" = ");

            await writer.WriteAsync(jsonElement);

            await writer.WriteAsync(".GetArrayLength();");

            await writer.WriteLineAsync();

            await writer.WriteIndentAsync();

            await writer.WriteAsync("var ");

            await writer.WriteAsync(listField);

            await writer.WriteAsync(" = new ");

            await writer.WriteAsync(resultTypeName);

            await writer.WriteAsync('[');

            await writer.WriteAsync(lengthField);

            await writer.WriteAsync(']');

            await writer.WriteAsync(';');

            await writer.WriteLineAsync();

            await writer.WriteLineAsync();

            await writer.WriteIndentAsync();

            await writer.WriteAsync("for (int ");

            await writer.WriteAsync(indexField);

            await writer.WriteAsync(" = 0; ");

            await writer.WriteAsync(indexField);

            await writer.WriteAsync($" < {lengthField}; ");

            await writer.WriteAsync(indexField);

            await writer.WriteAsync("++)");

            await writer.WriteLineAsync();

            await writer.WriteIndentAsync();

            using (writer.WriteBraces())
            {
                await writer.WriteIndentAsync();

                await writer.WriteAsync("JsonElement ");

                await writer.WriteAsync(elementField);

                await writer.WriteAsync(" = ");

                await writer.WriteAsync(jsonElement);

                await writer.WriteAsync('[');

                await writer.WriteAsync(indexField);

                await writer.WriteAsync(']');

                await writer.WriteAsync(';');

                await writer.WriteLineAsync();

                if (elementType.IsListType())
                {
                    await WriteListAsync(
                        writer,
                        methodDescriptor,
                        possibleType,
                        elementField,
                        "inner" + char.ToUpper(elementField[0]) + elementField.Substring(1),
                        "inner" + char.ToUpper(listField[0]) + listField.Substring(1),
                        "inner" + char.ToUpper(entityField[0]) + entityField.Substring(1),
                        typeLookup);
                }
                else
                {
                    await writer.WriteIndentAsync();

                    await writer.WriteAsync("var ");

                    await writer.WriteAsync(entityField);

                    await writer.WriteAsync(" = new ");

                    await writer.WriteAsync(possibleType.ResultDescriptor.Name);

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

                    await writer.WriteLineAsync();

                    await WriteObjectPropertyDeserializationAsync(
                        writer,
                        possibleType,
                        elementField,
                        entityField,
                        typeLookup);

                    await writer.WriteIndentAsync();

                    await writer.WriteAsync(listField);

                    await writer.WriteAsync('[');

                    await writer.WriteAsync(indexField);

                    await writer.WriteAsync(']');

                    await writer.WriteAsync(" = ");

                    await writer.WriteAsync(entityField);

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

            await writer.WriteLineAsync();

            await writer.WriteLineAsync();

            await writer.WriteIndentAsync();

            await writer.WriteAsync("return ");

            await writer.WriteAsync(listField);

            await writer.WriteAsync(';');
        }