Skip to content

Commit 43c568a

Browse files
authored
Enable raw array as input and output (#3044)
* Change raw array response as paging * Add test * Update * Update * Update * Fix * Update * Fix * Fix * Update * Update * Update
1 parent ad0b356 commit 43c568a

35 files changed

+5468
-86
lines changed

eng/Generate.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ if (!($Exclude -contains "Samples"))
253253
# Cadl projects
254254
$cadlRanchProjectDirectory = Join-Path $repoRoot 'test' 'CadlRanchProjects'
255255
$cadlRanchProjectPaths =
256+
'arrays/item-types',
256257
'authentication/api-key',
257258
'authentication/oauth2',
258259
'authentication/union',

eng/Generation.psm1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ $repoRoot = Resolve-Path (Join-Path $PSScriptRoot '..')
22
$autoRestBinary = "npx --no-install autorest"
33
$AutoRestPluginProject = Resolve-Path (Join-Path $repoRoot 'src' 'AutoRest.CSharp')
44

5-
function Invoke($command)
5+
function Invoke($command, $executePath=$repoRoot)
66
{
77
Write-Host "> $command"
8-
pushd $repoRoot
8+
pushd $executePath
99
if ($IsLinux -or $IsMacOs)
1010
{
1111
sh -c "$command 2>&1"
@@ -83,7 +83,7 @@ function Invoke-Cadl($baseOutput, $projectName, $mainFile, $arguments="", $share
8383
{
8484
$cadlFileName = $mainFile ? $mainFile : "$baseOutput/$projectName.cadl"
8585
$emitCommand = "npx cadl compile $cadlFileName --emit @azure-tools/cadl-csharp --option @azure-tools/cadl-csharp.emitter-output-dir=$outputPath --option @azure-tools/cadl-csharp.csharpGeneratorPath=$autorestCsharpBinPath $arguments"
86-
Invoke $emitCommand
86+
Invoke $emitCommand $outputPath
8787
}
8888
Finally
8989
{

src/AutoRest.CSharp/Common/Generation/Writers/FormattableStringHelpers.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ public static FormattableString GetIdentifiersFormattable(this IEnumerable<strin
8585

8686
public static FormattableString GetConversionFormattable(this Parameter parameter, CSharpType toType)
8787
{
88+
if (TypeFactory.IsList(parameter.Type) && toType.EqualsIgnoreNullable(typeof(RequestContent)))
89+
{
90+
return $"{typeof(RequestContent)}.{nameof(RequestContent.Create)}({parameter.Name})";
91+
}
92+
8893
var conversionMethod = GetConversionMethod(parameter.Type, toType);
8994
if (conversionMethod == null)
9095
{

src/AutoRest.CSharp/Common/Generation/Writers/ResponseWriterHelpers.cs

Lines changed: 88 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ namespace AutoRest.CSharp.Generation.Writers
1515
{
1616
internal static class ResponseWriterHelpers
1717
{
18-
public static void WriteStatusCodeSwitch(CodeWriter writer, string messageVariableName, RestClientMethod operation, bool async, FieldDeclaration? clientDiagnosticsField)
18+
public static void WriteRawResponseToGeneric(CodeWriter writer, RestClientMethod operation, Output.Models.Responses.Response response, bool async, string? messageVariableName, FormattableString responseVariable)
1919
{
20-
FormattableString responseVariable = $"{messageVariableName}.Response";
21-
2220
var returnType = operation.ReturnType;
2321
var headersModelType = operation.HeaderModel?.Type;
2422

@@ -41,6 +39,92 @@ public static void WriteStatusCodeSwitch(CodeWriter writer, string messageVariab
4139
kind = ReturnKind.Response;
4240
}
4341

42+
var responseBody = response.ResponseBody;
43+
ReferenceOrConstant value = default;
44+
45+
var valueVariable = new CodeWriterDeclaration("value");
46+
switch (responseBody)
47+
{
48+
case ObjectResponseBody objectResponseBody:
49+
writer.Line($"{responseBody.Type} {valueVariable:D} = default;");
50+
writer.WriteDeserializationForMethods(objectResponseBody.Serialization, async, valueVariable, responseVariable, objectResponseBody.Type);
51+
value = new Reference(valueVariable.ActualName, responseBody.Type);
52+
break;
53+
case StreamResponseBody _:
54+
writer.Line($"var {valueVariable:D} = {messageVariableName}.ExtractResponseContent();");
55+
value = new Reference(valueVariable.ActualName, responseBody.Type);
56+
break;
57+
case ConstantResponseBody body:
58+
writer.Append($"{returnType} {valueVariable:D} = ");
59+
writer.WriteReferenceOrConstant(body.Value);
60+
writer.Line($";");
61+
value = new Reference(valueVariable.ActualName, responseBody.Type);
62+
break;
63+
case StringResponseBody _:
64+
var streamReaderVariable = new CodeWriterDeclaration("streamReader");
65+
writer.Line($"{typeof(StreamReader)} {streamReaderVariable:D} = new {typeof(StreamReader)}({responseVariable}.ContentStream);");
66+
writer.Append($"{returnType} {valueVariable:D} = ");
67+
if (async)
68+
{
69+
writer.Line($"await {streamReaderVariable}.ReadToEndAsync().ConfigureAwait(false);");
70+
}
71+
else
72+
{
73+
writer.Line($"{streamReaderVariable}.ReadToEnd();");
74+
}
75+
value = new Reference(valueVariable.ActualName, responseBody.Type);
76+
break;
77+
default:
78+
{
79+
if (returnType != null)
80+
{
81+
value = Constant.Default(returnType.WithNullable(true));
82+
}
83+
84+
break;
85+
}
86+
}
87+
88+
switch (kind)
89+
{
90+
case ReturnKind.Response:
91+
writer.Append($"return {responseVariable};");
92+
break;
93+
case ReturnKind.Headers:
94+
writer.Append($"return {typeof(ResponseWithHeaders)}.FromValue(headers, {responseVariable});");
95+
break;
96+
case ReturnKind.HeadersAndValue:
97+
writer.Append($"return {typeof(ResponseWithHeaders)}.FromValue");
98+
if (!Equals(responseBody?.Type, operation.ReturnType))
99+
{
100+
writer.Append($"<{operation.ReturnType}, {headersModelType}>");
101+
}
102+
writer.Append($"(");
103+
writer.WriteReferenceOrConstant(value);
104+
writer.Append($", headers, {responseVariable});");
105+
break;
106+
case ReturnKind.Value:
107+
writer.Append($"return {typeof(Azure.Response)}.FromValue");
108+
if (!Equals(responseBody?.Type, operation.ReturnType))
109+
{
110+
writer.Append($"<{operation.ReturnType}>");
111+
}
112+
writer.Append($"(");
113+
writer.WriteReferenceOrConstant(value);
114+
writer.Append($", {responseVariable});");
115+
break;
116+
default:
117+
throw new ArgumentOutOfRangeException();
118+
}
119+
}
120+
121+
public static void WriteStatusCodeSwitch(CodeWriter writer, string messageVariableName, RestClientMethod operation, bool async, FieldDeclaration? clientDiagnosticsField)
122+
{
123+
FormattableString responseVariable = $"{messageVariableName}.Response";
124+
125+
var returnType = operation.ReturnType;
126+
var headersModelType = operation.HeaderModel?.Type;
127+
44128
if (headersModelType != null)
45129
{
46130
writer.Line($"var headers = new {headersModelType}({responseVariable});");
@@ -67,82 +151,7 @@ public static void WriteStatusCodeSwitch(CodeWriter writer, string messageVariab
67151

68152
using (responseBody != null ? writer.Scope() : default)
69153
{
70-
ReferenceOrConstant value = default;
71-
72-
var valueVariable = new CodeWriterDeclaration("value");
73-
switch (responseBody)
74-
{
75-
case ObjectResponseBody objectResponseBody:
76-
writer.Line($"{responseBody.Type} {valueVariable:D} = default;");
77-
writer.WriteDeserializationForMethods(objectResponseBody.Serialization, async, valueVariable, responseVariable, objectResponseBody.Type);
78-
value = new Reference(valueVariable.ActualName, responseBody.Type);
79-
break;
80-
case StreamResponseBody _:
81-
writer.Line($"var {valueVariable:D} = {messageVariableName}.ExtractResponseContent();");
82-
value = new Reference(valueVariable.ActualName, responseBody.Type);
83-
break;
84-
case ConstantResponseBody body:
85-
writer.Append($"{returnType} {valueVariable:D} = ");
86-
writer.WriteReferenceOrConstant(body.Value);
87-
writer.Line($";");
88-
value = new Reference(valueVariable.ActualName, responseBody.Type);
89-
break;
90-
case StringResponseBody _:
91-
var streamReaderVariable = new CodeWriterDeclaration("streamReader");
92-
writer.Line($"{typeof(StreamReader)} {streamReaderVariable:D} = new {typeof(StreamReader)}({messageVariableName}.Response.ContentStream);");
93-
writer.Append($"{returnType} {valueVariable:D} = ");
94-
if (async)
95-
{
96-
writer.Line($"await {streamReaderVariable}.ReadToEndAsync().ConfigureAwait(false);");
97-
}
98-
else
99-
{
100-
writer.Line($"{streamReaderVariable}.ReadToEnd();");
101-
}
102-
value = new Reference(valueVariable.ActualName, responseBody.Type);
103-
break;
104-
default:
105-
{
106-
if (returnType != null)
107-
{
108-
value = Constant.Default(returnType.WithNullable(true));
109-
}
110-
111-
break;
112-
}
113-
}
114-
115-
switch (kind)
116-
{
117-
case ReturnKind.Response:
118-
writer.Append($"return {responseVariable};");
119-
break;
120-
case ReturnKind.Headers:
121-
writer.Append($"return {typeof(ResponseWithHeaders)}.FromValue(headers, {responseVariable});");
122-
break;
123-
case ReturnKind.HeadersAndValue:
124-
writer.Append($"return {typeof(ResponseWithHeaders)}.FromValue");
125-
if (!Equals(responseBody?.Type, operation.ReturnType))
126-
{
127-
writer.Append($"<{operation.ReturnType}, {headersModelType}>");
128-
}
129-
writer.Append($"(");
130-
writer.WriteReferenceOrConstant(value);
131-
writer.Append($", headers, {responseVariable});");
132-
break;
133-
case ReturnKind.Value:
134-
writer.Append($"return {typeof(Azure.Response)}.FromValue");
135-
if (!Equals(responseBody?.Type, operation.ReturnType))
136-
{
137-
writer.Append($"<{operation.ReturnType}>");
138-
}
139-
writer.Append($"(");
140-
writer.WriteReferenceOrConstant(value);
141-
writer.Append($", {responseVariable});");
142-
break;
143-
default:
144-
throw new ArgumentOutOfRangeException();
145-
}
154+
WriteRawResponseToGeneric(writer, operation, response, async, messageVariableName, responseVariable);
146155
}
147156
}
148157

src/AutoRest.CSharp/LowLevel/Generation/LowLevelClientWriter.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,10 @@ private void WriteConvenienceMethod(LowLevelClientMethod clientMethod, Convenien
306306
{
307307
_writer.Line($"return {responseVariable:I};");
308308
}
309+
else if (TypeFactory.IsReadOnlyList(responseType))
310+
{
311+
ResponseWriterHelpers.WriteRawResponseToGeneric(_writer, clientMethod.RequestMethod, clientMethod.RequestMethod.Responses[0], async, null, $"{responseVariable.ActualName}");
312+
}
309313
else
310314
{
311315
_writer.Line($"return {typeof(Response)}.{nameof(Response.FromValue)}({responseType}.FromResponse({responseVariable:I}), {responseVariable:I});");

src/AutoRest.CSharp/LowLevel/Output/OperationMethodChainBuilder.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ private ReturnTypeChain BuildReturnTypes()
129129
var firstBodyType = operationBodyTypes[0];
130130
if (firstBodyType != null)
131131
{
132-
responseType = _typeFactory.CreateType(firstBodyType);
132+
responseType = TypeFactory.GetOutputType(_typeFactory.CreateType(firstBodyType));
133133
}
134134
};
135135

@@ -213,9 +213,17 @@ private ConvenienceMethod BuildConvenienceMethod(ReturnTypeChain returnTypeChain
213213
}
214214
}
215215

216-
} else if (parameterChain.Convenience != null)
216+
}
217+
else if (parameterChain.Convenience != null)
217218
{
218-
parameterList.Add(parameterChain.Convenience);
219+
if (TypeFactory.IsList(parameterChain.Convenience.Type))
220+
{
221+
parameterList.Add(parameterChain.Convenience with { Type = new CSharpType(typeof(object)) });
222+
}
223+
else
224+
{
225+
parameterList.Add(parameterChain.Convenience);
226+
}
219227
}
220228
}
221229
var attributes = Operation.Deprecated is { } deprecated

src/AutoRest.CSharp/Properties/launchSettings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@
164164
"commandName": "Project",
165165
"commandLineArgs": "--standalone $(SolutionDir)\\test\\TestProjects\\BodyAndPath-LowLevel\\Generated"
166166
},
167+
"cadl-arrays/item-types": {
168+
"commandName": "Project",
169+
"commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\arrays\\item-types\\Generated"
170+
},
167171
"cadl-authentication/api-key": {
168172
"commandName": "Project",
169173
"commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\authentication\\api-key\\Generated"

0 commit comments

Comments
 (0)