Skip to content

Commit

Permalink
feat(dpg): support logicalPath of lro
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/TypeSpec.Extension/Emitter.Csharp/src/lib/operation.ts

- pass in `logicalPath` info from emitter
- in generator, generate convert lambda to fetch the return value from `logicalPath`
- add test case

resolve #3837
  • Loading branch information
Mingzhe Huang (from Dev Box) committed Oct 16, 2023
1 parent bb1b965 commit edcbcae
Show file tree
Hide file tree
Showing 15 changed files with 979 additions and 485 deletions.
1 change: 1 addition & 0 deletions src/AutoRest.CSharp/Common/Input/CodeModelConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ public List<InputParameter> CreateOperationParameters(IReadOnlyCollection<Reques
public OperationResponse CreateOperationResponse(ServiceResponse response) => new(
StatusCodes: response.HttpResponse.IntStatusCodes.ToList(),
BodyType: GetResponseBodyType(response),
ResultPath: null,
BodyMediaType: GetBodyFormat(response.HttpResponse.KnownMediaType),
Headers: GetResponseHeaders(response.HttpResponse.Headers),
IsErrorResponse: false
Expand Down
24 changes: 22 additions & 2 deletions src/AutoRest.CSharp/Common/Input/InputTypes/OperationResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,30 @@

using System;
using System.Collections.Generic;
using System.Linq;
using AutoRest.CSharp.Utilities;

namespace AutoRest.CSharp.Common.Input;

internal record OperationResponse(IReadOnlyList<int> StatusCodes, InputType? BodyType, BodyMediaType BodyMediaType, IReadOnlyList<OperationResponseHeader> Headers, bool IsErrorResponse)
internal record OperationResponse(IReadOnlyList<int> StatusCodes, InputType? BodyType, BodyMediaType BodyMediaType, IReadOnlyList<OperationResponseHeader> Headers, bool IsErrorResponse, string? ResultPath)
{
public OperationResponse() : this(StatusCodes: Array.Empty<int>(), BodyType: null, BodyMediaType: BodyMediaType.None, Headers: Array.Empty<OperationResponseHeader>(), IsErrorResponse: false) { }
public OperationResponse() : this(StatusCodes: Array.Empty<int>(), BodyType: null, BodyMediaType: BodyMediaType.None, Headers: Array.Empty<OperationResponseHeader>(), IsErrorResponse: false, ResultPath: null) { }

/// <summary>
/// Meaninngful return type of the long running operation.
/// </summary>
public InputType? ReturnType
{
get
{
if (BodyType is null)
return null;

if (ResultPath is null)
return BodyType;

var rawResponseType = (InputModelType)BodyType;
return rawResponseType.Properties.FirstOrDefault(p => p.SerializedName == ResultPath)!.Type;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected LongRunningOperation(InputOperation operation, BuildContext context, L
FinalStateVia = operation.LongRunning.FinalStateVia;

var finalResponse = operation.LongRunning.FinalResponse;
var finalResponseType = finalResponse.BodyType;
var finalResponseType = finalResponse.ReturnType;

if (finalResponseType != null)
{
Expand Down
16 changes: 15 additions & 1 deletion src/AutoRest.CSharp/LowLevel/Generation/DpgClientWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -360,12 +360,26 @@ private void WriteConvenienceLroMethod(LowLevelClientMethod clientMethod, Conven
.LineRaw(";");
// return ProtocolOperationHelpers.Convert(response, r => responseType.FromResponse(r), ClientDiagnostics, scopeName);
var diagnostic = convenienceMethod.Diagnostic ?? clientMethod.ProtocolMethodDiagnostic;
_writer.Line($"return {typeof(ProtocolOperationHelpers)}.{nameof(ProtocolOperationHelpers.Convert)}({responseVariable:I}, {responseType}.FromResponse, {fields.ClientDiagnosticsProperty.Name}, {diagnostic.ScopeName:L});");
_writer.Line($"return {typeof(ProtocolOperationHelpers)}.{nameof(ProtocolOperationHelpers.Convert)}({responseVariable:I}, {GetConvertMethodStatement(clientMethod.LongRunning!, responseType)}, {fields.ClientDiagnosticsProperty.Name}, {diagnostic.ScopeName:L});");
}
}
_writer.Line();
}

private string GetConvertMethodStatement(OperationLongRunning longRunning, CSharpType responseType)
{
if (longRunning.FinalResponse.ResultPath.IsNullOrEmpty())
{
return $"{responseType.Name}.FromResponse";
}

var bodyType = longRunning.FinalResponse.BodyType!;
return @$"r => {{
{bodyType.Name} rawResponse = {bodyType.Name}.FromResponse(r);
return rawResponse.{longRunning.FinalResponse.ResultPath!.ToCleanName()};
}}";
}

private void WriteConveniencePageableMethod(LowLevelClientMethod clientMethod, ConvenienceMethod convenienceMethod, ProtocolMethodPaging pagingInfo, ClientFields fields, bool async)
{
_writer.WritePageable(convenienceMethod, clientMethod.RequestMethod, pagingInfo.NextPageMethod, fields.ClientDiagnosticsProperty, fields.PipelineField, clientMethod.ProtocolMethodDiagnostic.ScopeName, pagingInfo.ItemName, pagingInfo.NextLinkName, async);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ private ReturnTypeChain BuildReturnTypes()
{
if (Operation.LongRunning != null)
{
return Operation.LongRunning.FinalResponse.BodyType;
return Operation.LongRunning.FinalResponse.ReturnType;
}

var operationBodyTypes = Operation.Responses.Where(r => !r.IsErrorResponse).Select(r => r.BodyType).Distinct();
Expand Down
5 changes: 4 additions & 1 deletion src/TypeSpec.Extension/Emitter.Csharp/src/lib/operation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,9 @@ export function loadOperation(
if (op.verb !== "delete") {
const formattedType = getFormattedType(
program,
metadata.logicalResult
metadata.logicalPath
? metadata.envelopeResult
: metadata.logicalResult
);
bodyType = getInputType(context, formattedType, models, enums);
}
Expand All @@ -400,6 +402,7 @@ export function loadOperation(
// for now, let assume we don't allow return type
StatusCodes: op.verb === "delete" ? [204] : [200],
BodyType: bodyType,
ResultPath: metadata.logicalPath,
BodyMediaType: BodyMediaType.Json
} as OperationResponse
} as OperationLongRunning;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export interface OperationResponse {
BodyMediaType: BodyMediaType;
Headers: HttpResponseHeader[];
IsErrorResponse: boolean;
ResultPath?: string;
}
Loading

0 comments on commit edcbcae

Please sign in to comment.