Beispiel #1
0
 public ClientMethod(string name, RestClientMethod restClientMethod, string?description, Diagnostic diagnostics)
 {
     Name             = name;
     RestClientMethod = restClientMethod;
     Description      = description;
     Diagnostics      = diagnostics;
 }
        private void WriteOperation(CodeWriter writer, RestClientMethod operation, bool async)
        {
            using var methodScope = writer.AmbientScope();

            CSharpType?bodyType        = operation.ReturnType;
            CSharpType?headerModelType = operation.HeaderModel?.Type;
            CSharpType responseType    = bodyType switch
            {
                null when headerModelType != null => new CSharpType(typeof(ResponseWithHeaders <>), headerModelType),
                { } when  headerModelType == null => new CSharpType(typeof(Response <>), bodyType),
                { } => new CSharpType(typeof(ResponseWithHeaders <>), bodyType, headerModelType),
Beispiel #3
0
        private IEnumerable <PagingMethod> BuildPagingMethods()
        {
            foreach (var operation in _operationGroup.Operations)
            {
                Paging?paging = operation.Language.Default.Paging;
                if (paging == null || operation.IsLongRunning)
                {
                    continue;
                }

                foreach (var serviceRequest in operation.Requests)
                {
                    RestClientMethod method         = RestClient.GetOperationMethod(serviceRequest);
                    RestClientMethod?nextPageMethod = RestClient.GetNextOperationMethod(serviceRequest);

                    if (!(method.Responses.SingleOrDefault(r => r.ResponseBody != null)?.ResponseBody is ObjectResponseBody objectResponseBody))
                    {
                        throw new InvalidOperationException($"Method {method.Name} has to have a return value");
                    }

                    TypeProvider implementation = objectResponseBody.Type.Implementation;
                    if (!(implementation is ObjectType type))
                    {
                        throw new InvalidOperationException($"The return type of {method.Name} has to be an object schema to be used in paging");
                    }

                    string?nextLinkName = paging.NextLinkName;
                    string itemName     = paging.ItemName ?? "value";

                    ObjectTypeProperty itemProperty = type.GetPropertyBySerializedName(itemName);

                    ObjectTypeProperty?nextLinkProperty = null;
                    if (!string.IsNullOrWhiteSpace(nextLinkName))
                    {
                        nextLinkProperty = type.GetPropertyBySerializedName(nextLinkName);
                    }

                    if (!(itemProperty.SchemaProperty?.Schema is ArraySchema arraySchema))
                    {
                        throw new InvalidOperationException($"{itemName} property has to be an array schema, actual {itemProperty.SchemaProperty?.Schema}");
                    }

                    CSharpType itemType = _context.TypeFactory.CreateType(arraySchema.ElementType, false);
                    yield return(new PagingMethod(
                                     method,
                                     nextPageMethod,
                                     method.Name,
                                     nextLinkProperty?.Declaration.Name,
                                     itemProperty.Declaration.Name,
                                     itemType,
                                     new Diagnostic($"{Declaration.Name}.{method.Name}")));
                }
            }
        }
Beispiel #4
0
        private void WriteStartOperationOperation(CodeWriter writer, LongRunningOperationMethod lroMethod, bool async)
        {
            RestClientMethod originalMethod = lroMethod.StartMethod;
            CSharpType       returnType     = async ? new CSharpType(typeof(Task <>), lroMethod.Operation.Type) : lroMethod.Operation.Type;

            Parameter[] parameters = originalMethod.Parameters;

            writer.WriteXmlDocumentationSummary(originalMethod.Description);

            foreach (Parameter parameter in parameters)
            {
                writer.WriteXmlDocumentationParameter(parameter.Name, parameter.Description);
            }
            writer.WriteXmlDocumentationParameter("cancellationToken", "The cancellation token to use.");

            string asyncText = async ? "async " : string.Empty;

            writer.Append($"public virtual {asyncText}{returnType} {CreateStartOperationName(lroMethod.Name, async)}(");
            foreach (Parameter parameter in parameters)
            {
                writer.WriteParameter(parameter);
            }
            writer.Line($"{typeof(CancellationToken)} cancellationToken = default)");

            using (writer.Scope())
            {
                writer.WriteParameterNullChecks(parameters);

                WriteDiagnosticScope(writer, lroMethod.Diagnostics, writer =>
                {
                    string awaitText     = async ? "await" : string.Empty;
                    string configureText = async ? ".ConfigureAwait(false)" : string.Empty;
                    writer.Append($"var originalResponse = {awaitText} RestClient.{CreateMethodName(originalMethod.Name, async)}(");
                    foreach (Parameter parameter in parameters)
                    {
                        writer.Append($"{parameter.Name}, ");
                    }

                    writer.Line($"cancellationToken){configureText};");

                    writer.Append($"return new {lroMethod.Operation.Type}({ClientDiagnosticsField}, {PipelineField}, RestClient.{CreateRequestMethodName(originalMethod.Name)}(");
                    foreach (Parameter parameter in parameters)
                    {
                        writer.Append($"{parameter.Name}, ");
                    }
                    writer.RemoveTrailingComma();
                    writer.Line($").Request, originalResponse);");
                });
            }
            writer.Line();
        }
Beispiel #5
0
        private IEnumerable <LongRunningOperationMethod> BuildLongRunningOperationMethods()
        {
            foreach (var operation in _operationGroup.Operations)
            {
                if (operation.IsLongRunning)
                {
                    foreach (var serviceRequest in operation.Requests)
                    {
                        var name = operation.CSharpName();
                        RestClientMethod startMethod = RestClient.GetOperationMethod(serviceRequest);

                        yield return(new LongRunningOperationMethod(
                                         name,
                                         _context.Library.FindLongRunningOperation(operation),
                                         startMethod,
                                         new Diagnostic($"{Declaration.Name}.Start{name}")
                                         ));
                    }
                }
            }
        }
Beispiel #6
0
        private IEnumerable <ClientMethod> BuildMethods()
        {
            foreach (var operation in _operationGroup.Operations)
            {
                if (operation.IsLongRunning || operation.Language.Default.Paging != null)
                {
                    continue;
                }

                foreach (var request in operation.Requests)
                {
                    var name = operation.CSharpName();
                    RestClientMethod startMethod = RestClient.GetOperationMethod(request);

                    yield return(new ClientMethod(
                                     name,
                                     startMethod,
                                     BuilderHelpers.EscapeXmlDescription(operation.Language.Default.Description),
                                     new Diagnostic($"{Declaration.Name}.{name}", Array.Empty <DiagnosticAttribute>())));
                }
            }
        }
Beispiel #7
0
        private IEnumerable <RestClientMethod> BuildAllMethods()
        {
            foreach (var operation in _operationGroup.Operations)
            {
                foreach (var serviceRequest in operation.Requests)
                {
                    RestClientMethod method = GetOperationMethod(serviceRequest);
                    yield return(method);
                }
            }

            foreach (var operation in _operationGroup.Operations)
            {
                foreach (var serviceRequest in operation.Requests)
                {
                    // remove duplicates when GetNextPage method is not autogenerated
                    if (GetNextOperationMethod(serviceRequest) is {} nextOperationMethod&&
                        operation.Language.Default.Paging?.NextLinkOperation == null)
                    {
                        yield return(nextOperationMethod);
                    }
                }
            }
        }
        private void WriteRequestCreation(CodeWriter writer, RestClientMethod clientMethod)
        {
            using var methodScope = writer.AmbientScope();

            var methodName = CreateRequestMethodName(clientMethod.Name);

            writer.Append($"internal {typeof(HttpMessage)} {methodName}(");
            var parameters = clientMethod.Parameters;

            foreach (Parameter clientParameter in parameters)
            {
                writer.Append($"{clientParameter.Type} {clientParameter.Name:D},");
            }
            writer.RemoveTrailingComma();
            writer.Line($")");
            using (writer.Scope())
            {
                var message = new CodeWriterDeclaration("message");
                var request = new CodeWriterDeclaration("request");
                var uri     = new CodeWriterDeclaration("uri");

                writer.Line($"var {message:D} = {PipelineField}.CreateMessage();");
                writer.Line($"var {request:D} = {message}.Request;");
                var method = clientMethod.Request.HttpMethod;
                writer.Line($"{request}.Method = {typeof(RequestMethod)}.{method.ToRequestMethodName()};");

                writer.Line($"var {uri:D} = new RawRequestUriBuilder();");
                foreach (var segment in clientMethod.Request.PathSegments)
                {
                    if (!segment.Value.IsConstant && segment.Value.Reference.Name == "nextLink")
                    {
                        if (segment.IsRaw)
                        {
                            // Artificial nextLink needs additional logic for relative versus absolute links
                            WritePathSegment(writer, uri, segment, "AppendRawNextLink");
                        }
                        else
                        {
                            // Natural nextLink parameters need to use a different method to parse path and query elements
                            WritePathSegment(writer, uri, segment, "AppendRaw");
                        }
                    }
                    else
                    {
                        WritePathSegment(writer, uri, segment);
                    }
                }

                //TODO: Duplicate code between query and header parameter processing logic
                foreach (var queryParameter in clientMethod.Request.Query)
                {
                    WriteQueryParameter(writer, uri, queryParameter);
                }

                writer.Line($"{request}.Uri = {uri};");

                foreach (var header in clientMethod.Request.Headers)
                {
                    WriteHeader(writer, request, header);
                }

                switch (clientMethod.Request.Body)
                {
                case SchemaRequestBody body:
                    using (WriteValueNullCheck(writer, body.Value))
                    {
                        WriteSerializeContent(
                            writer,
                            request,
                            body.Serialization,
                            w => WriteConstantOrParameter(w, body.Value, ignoreNullability: true));
                    }

                    break;

                case BinaryRequestBody binaryBody:
                    using (WriteValueNullCheck(writer, binaryBody.Value))
                    {
                        writer.Append($"{request}.Content = {typeof(RequestContent)}.Create(");
                        WriteConstantOrParameter(writer, binaryBody.Value);
                        writer.Line($");");
                    }
                    break;

                case TextRequestBody textBody:
                    using (WriteValueNullCheck(writer, textBody.Value))
                    {
                        writer.Append($"{request}.Content = new {typeof(StringRequestContent)}(");
                        WriteConstantOrParameter(writer, textBody.Value);
                        writer.Line($");");
                    }
                    break;

                case FlattenedSchemaRequestBody flattenedSchemaRequestBody:
                    var modelVariable = new CodeWriterDeclaration("model");
                    writer.Append($"var {modelVariable:D} = ")
                    .WriteInitialization(flattenedSchemaRequestBody.ObjectType, flattenedSchemaRequestBody.Initializers)
                    .Line($";");

                    WriteSerializeContent(
                        writer,
                        request,
                        flattenedSchemaRequestBody.Serialization,
                        w => w.Append(modelVariable));
                    break;

                case null:
                    break;

                default:
                    throw new NotImplementedException(clientMethod.Request.Body?.GetType().FullName);
                }

                writer.Line($"return {message};");
            }
            writer.Line();
        }