private async Task WriteParserForSingleResultType(
            CodeWriter writer,
            IResultParserMethodDescriptor methodDescriptor,
            IResultParserTypeDescriptor possibleType,
            ITypeLookup typeLookup)
        {
            if (methodDescriptor.ResultType.IsListType())
            {
                await WriteListAsync(
                    writer,
                    methodDescriptor,
                    "obj",
                    "element",
                    "list",
                    typeLookup)
                .ConfigureAwait(false);
            }
            else
            {
                await writer.WriteIndentAsync().ConfigureAwait(false);

                await writer.WriteAsync("return ").ConfigureAwait(false);
                await WriteCreateObjectAsync(
                    writer,
                    methodDescriptor,
                    possibleType,
                    "obj",
                    typeLookup)
                .ConfigureAwait(false);
            }
        }
        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 WriteCreateListElementAsync(
            CodeWriter writer,
            IResultParserMethodDescriptor methodDescriptor,
            IResultParserTypeDescriptor possibleType,
            string jsonElement,
            string listField,
            string indexField,
            ITypeLookup typeLookup)
        {
            await writer.WriteIndentAsync().ConfigureAwait(false);

            await writer.WriteAsync(string.Format(
                                        "{0}[{1}] = ",
                                        listField,
                                        indexField))
            .ConfigureAwait(false);

            await WriteCreateObjectAsync(
                writer,
                methodDescriptor,
                possibleType,
                jsonElement,
                typeLookup)
            .ConfigureAwait(false);
        }
Beispiel #4
0
 public ResultParserMethodDescriptor(
     string name,
     OperationDefinitionNode operation,
     IType resultType,
     FieldNode resultSelection,
     Path path,
     IInterfaceDescriptor resultDescriptor,
     IReadOnlyList <IResultParserTypeDescriptor> possibleTypes,
     IResultParserTypeDescriptor unknownType)
 {
     Name = name
            ?? throw new ArgumentNullException(nameof(name));
     Operation = operation
                 ?? throw new ArgumentNullException(nameof(operation));
     ResultType = resultType
                  ?? throw new ArgumentNullException(nameof(resultType));
     ResultSelection = resultSelection;
     Path            = path
                       ?? throw new ArgumentNullException(nameof(path));
     ResultDescriptor = resultDescriptor
                        ?? throw new ArgumentNullException(nameof(resultDescriptor));
     PossibleTypes = possibleTypes
                     ?? throw new ArgumentNullException(nameof(possibleTypes));
     UnknownType = unknownType;
 }
        private async Task WriteParserForSingleResultType(
            CodeWriter writer,
            IResultParserMethodDescriptor methodDescriptor,
            IResultParserTypeDescriptor possibleType,
            ITypeLookup typeLookup)
        {
            if (methodDescriptor.ResultType.IsListType())
            {
                await WriteListAsync(
                    writer,
                    methodDescriptor,
                    possibleType,
                    "obj",
                    "element",
                    "list",
                    "entity",
                    typeLookup);
            }
            else
            {
                await WriteCreateObjectAsync(
                    writer,
                    methodDescriptor,
                    possibleType,
                    "obj",
                    typeLookup);
            }

            await writer.WriteLineAsync();
        }
        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 WriteDeserializeMethodAsync(
            CodeWriter writer,
            IResultParserTypeDescriptor possibleType,
            ITypeLookup typeLookup,
            ISet <string> generatedMethods)
        {
            bool first = true;

            foreach (IType type in possibleType.ResultDescriptor.Fields
                     .Where(t => t.Type.NamedType().IsLeafType())
                     .Select(t => t.Type))
            {
                string methodName = SerializerNameUtils.CreateDeserializerName(type);

                if (generatedMethods.Add(methodName))
                {
                    Type   serializationType = typeLookup.GetSerializationType(type);
                    string serializerMethod  = _jsonMethod[serializationType];

                    if (!first)
                    {
                        await writer.WriteLineAsync().ConfigureAwait(false);
                    }
                    first = false;

                    if (type.IsListType() && type.ListType().ElementType.IsListType())
                    {
                        // TODO : implement this
                        throw new NotImplementedException();
                    }
                    else if (type.IsListType() &&
                             type.ListType().ElementType.IsLeafType())
                    {
                        await WriteDeserializeLeafListAsync(
                            writer,
                            typeLookup,
                            methodName,
                            type,
                            type.NamedType().Name,
                            serializerMethod)
                        .ConfigureAwait(false);
                    }
                    else
                    {
                        await WriteDeserializeLeafAsync(
                            writer,
                            methodName,
                            typeLookup.GetLeafClrTypeName(type),
                            type.NamedType().Name,
                            serializerMethod,
                            type.IsNonNullType())
                        .ConfigureAwait(false);
                    }
                }
            }
        }
        private async Task WriteCreateObjectAsync(
            CodeWriter writer,
            IResultParserMethodDescriptor methodDescriptor,
            IResultParserTypeDescriptor possibleType,
            string jsonElement,
            ITypeLookup typeLookup)
        {
            string entityField = GetFieldName(possibleType.ResultDescriptor.Name);

            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,
                jsonElement,
                entityField,
                typeLookup);

            await writer.WriteIndentAsync();

            await writer.WriteAsync("return ");

            await writer.WriteAsync(entityField);

            await writer.WriteAsync(';');
        }
        private async Task WriteCreateObjectAsync(
            CodeWriter writer,
            IResultParserMethodDescriptor methodDescriptor,
            IResultParserTypeDescriptor possibleType,
            string jsonElement,
            ITypeLookup typeLookup)
        {
            await writer.WriteAsync("new ").ConfigureAwait(false);

            await writer.WriteAsync(possibleType.ResultDescriptor.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 WriteObjectPropertyDeserializationAsync(
                    writer,
                    possibleType,
                    jsonElement,
                    typeLookup)
                .ConfigureAwait(false);
            }

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

            await writer.WriteAsync(')').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();
            }
        }
        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(';');
        }