Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8717fbc
Put all optional client parameters into client options
pshao25 Nov 7, 2023
71287d1
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Nov 7, 2023
4472b2f
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Nov 8, 2023
c26032e
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Nov 10, 2023
ab7d989
update
pshao25 Nov 13, 2023
4abe948
Regenerate all code (any successful run even without change will have…
actions-user Nov 13, 2023
15b9299
update
pshao25 Nov 14, 2023
f750175
Merge branch 'constructor3706' of https://github.com/pshao25/autorest…
pshao25 Nov 14, 2023
4997efc
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Nov 14, 2023
3d9d590
update
pshao25 Nov 14, 2023
e2d833e
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Nov 15, 2023
7aa23a5
update
pshao25 Nov 15, 2023
862d4eb
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Nov 16, 2023
66beca9
update
pshao25 Nov 16, 2023
b303284
update
pshao25 Nov 16, 2023
37f52ba
update
pshao25 Nov 16, 2023
d9f06da
update
pshao25 Nov 16, 2023
87d5950
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Nov 27, 2023
1506b29
update
pshao25 Nov 27, 2023
2c96f11
update
pshao25 Nov 27, 2023
c9f5a2c
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Nov 27, 2023
b428cee
update
pshao25 Nov 27, 2023
9fabdbe
update
pshao25 Nov 28, 2023
e4d0ab7
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Nov 28, 2023
e20e3b7
update
pshao25 Nov 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<AzureCoreSharedSources>$(MSBuildThisFileDirectory)/src/assets/Azure.Core.Shared/</AzureCoreSharedSources>
<ShouldUseCentralVersions Condition="'$(ShouldUseCentralVersions)' == ''">true</ShouldUseCentralVersions>
<NoWarn Condition="'$(IsTestGenerationTestProject)' == 'true'">$(NoWarn);CS1591</NoWarn>
<NoWarn>$(NoWarn);NU5105</NoWarn>
<NoWarn>$(NoWarn);NU5105;AD0001</NoWarn>
<!-- Test client libraries won't be in the approved namespace list -->
<NoWarn Condition="'$(IsTestGenerationSrcProject)' == 'true'">$(NoWarn);AZC0001</NoWarn>
<!-- Test client libraries can have single word class names -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using AutoRest.CSharp.Common.Input;
using AutoRest.CSharp.Output.Models.Types;
using AutoRest.CSharp.Utilities;

namespace AutoRest.CSharp.Generation.Writers
{
Expand Down Expand Up @@ -50,6 +51,21 @@ public static void WriteClientOptions(CodeWriter writer, ClientOptionsTypeProvid
}
}
}

if (clientOptions.AdditionalProperties != null && !Configuration.KeepOptionalClientParametersInConstructor)
{
if (clientOptions.ApiVersions is not null)
{
writer.Line();
}

foreach (var property in clientOptions.AdditionalProperties)
Comment thread
pshao25 marked this conversation as resolved.
Outdated
{
writer.WriteXmlDocumentationSummary(property.Description);
writer.Line($"public {property.Type} {property.Name.FirstCharToUpperCase()} {{ get; set; }}");
Comment thread
pshao25 marked this conversation as resolved.
Outdated
writer.Line();
}
}
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/AutoRest.CSharp/Common/Input/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using AutoRest.CSharp.AutoRest.Communication;
Expand Down Expand Up @@ -42,6 +43,7 @@ public static class Options
public const string UnreferencedTypesHandling = "unreferenced-types-handling";
public const string UseOverloadsBetweenProtocolAndConvenience = "use-overloads-between-protocol-and-convenience";
public const string KeepNonOverloadableProtocolSignature = "keep-non-overloadable-protocol-signature";
public const string KeepOptionalClientParametersInConstructor = "keep-optional-client-parameters-in-constructor";
public const string ModelFactoryForHlc = "model-factory-for-hlc";
public const string GenerateModelFactory = "generate-model-factory";
public const string ModelsToTreatEmptyStringAsNull = "models-to-treat-empty-string-as-null";
Expand Down Expand Up @@ -86,6 +88,7 @@ public static void Initialize(
UnreferencedTypesHandlingOption unreferencedTypesHandling,
bool useOverloadsBetweenProtocolAndConvenience,
bool keepNonOverloadableProtocolSignature,
bool keepOptionalClientParametersInConstructor,
string? projectFolder,
string? existingProjectFolder,
IReadOnlyList<string> protocolMethodList,
Expand Down Expand Up @@ -117,6 +120,7 @@ public static void Initialize(
UnreferencedTypesHandling = unreferencedTypesHandling;
UseOverloadsBetweenProtocolAndConvenience = useOverloadsBetweenProtocolAndConvenience;
KeepNonOverloadableProtocolSignature = keepNonOverloadableProtocolSignature;
KeepOptionalClientParametersInConstructor = keepOptionalClientParametersInConstructor;
ShouldTreatBase64AsBinaryData = !azureArm && !generation1ConvenienceClient ? shouldTreatBase64AsBinaryData : false;
UseCoreDataFactoryReplacements = useCoreDataFactoryReplacements;
projectFolder ??= ProjectFolderDefault;
Expand Down Expand Up @@ -264,6 +268,7 @@ internal static (string AbsoluteProjectFolder, string RelativeProjectFolder) Par
public static bool DeserializeNullCollectionAsNullValue { get; private set; }
public static bool UseOverloadsBetweenProtocolAndConvenience { get; private set; }
public static bool KeepNonOverloadableProtocolSignature { get; private set; }
public static bool KeepOptionalClientParametersInConstructor { get; private set; }

private static IReadOnlyList<string>? _oldModelFactoryEntries;
/// <summary>
Expand Down Expand Up @@ -318,6 +323,7 @@ public static void Initialize(IPluginCommunication autoRest, string defaultNames
unreferencedTypesHandling: GetOptionEnumValue<UnreferencedTypesHandlingOption>(autoRest, Options.UnreferencedTypesHandling),
useOverloadsBetweenProtocolAndConvenience: GetOptionBoolValue(autoRest, Options.UseOverloadsBetweenProtocolAndConvenience),
keepNonOverloadableProtocolSignature: GetOptionBoolValue(autoRest, Options.KeepNonOverloadableProtocolSignature),
keepOptionalClientParametersInConstructor: GetOptionBoolValue(autoRest, Options.KeepOptionalClientParametersInConstructor),
useCoreDataFactoryReplacements: GetOptionBoolValue(autoRest, Options.UseCoreDataFactoryReplacements),
projectFolder: GetProjectFolderOption(autoRest),
existingProjectFolder: autoRest.GetValue<string?>(Options.ExistingProjectfolder).GetAwaiter().GetResult(),
Expand Down Expand Up @@ -393,6 +399,8 @@ private static bool GetOptionBoolValue(IPluginCommunication autoRest, string opt
return true;
case Options.KeepNonOverloadableProtocolSignature:
return false;
case Options.KeepOptionalClientParametersInConstructor:
return false;
case Options.ShouldTreatBase64AsBinaryData:
return true;
case Options.DeserializeNullCollectionAsNullValue:
Expand Down Expand Up @@ -478,6 +486,7 @@ internal static void LoadConfiguration(JsonElement root, string? projectPath, st
ReadEnumOption<UnreferencedTypesHandlingOption>(root, Options.UnreferencedTypesHandling),
ReadOption(root, Options.UseOverloadsBetweenProtocolAndConvenience),
ReadOption(root, Options.KeepNonOverloadableProtocolSignature),
ReadOption(root, Options.KeepOptionalClientParametersInConstructor),
projectPath ?? ReadStringOption(root, Options.ProjectFolder),
existingProjectFolder,
protocolMethods,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public static Parameter FromInputParameter(in InputParameter operationParameter,

private static Constant? GetDefaultValue(InputParameter operationParameter, TypeFactory typeFactory) => operationParameter switch
{
{ Name: "$host", DefaultValue.Value: ""} => (Constant?)null, // In M4, when endpoint is not set, its default value is an empty string instead of null
Comment thread
pshao25 marked this conversation as resolved.
Outdated
{ NameInRequest: var nameInRequest } when RequestHeader.ClientRequestIdHeaders.Contains(nameInRequest) => Constant.FromExpression($"message.{Configuration.ApiTypes.HttpMessageRequestName}.ClientRequestId", new CSharpType(typeof(string))),
{ NameInRequest: var nameInRequest } when RequestHeader.ReturnClientRequestIdResponseHeaders.Contains(nameInRequest) => new Constant("true", new CSharpType(typeof(string))),
{ DefaultValue: not null } => BuilderHelpers.ParseConstant(operationParameter.DefaultValue.Value, typeFactory.CreateType(operationParameter.DefaultValue.Type)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Linq;
using System.Text;
using AutoRest.CSharp.Input.Source;
using AutoRest.CSharp.Output.Models.Shared;

namespace AutoRest.CSharp.Output.Models.Types
{
Expand All @@ -16,6 +17,7 @@ internal sealed class ClientOptionsTypeProvider : TypeProvider

public FormattableString Description { get; }
public IReadOnlyList<ApiVersion>? ApiVersions { get; }
public IList<Parameter>? AdditionalProperties { get; private set; }
Comment thread
pshao25 marked this conversation as resolved.
Outdated
protected override string DefaultName { get; }
protected override string DefaultAccessibility { get; }

Expand All @@ -29,6 +31,18 @@ public ClientOptionsTypeProvider(IReadOnlyList<string>? versions, string name, s
ApiVersions = ConvertApiVersions(versions);
}

public void AddAdditionalProperty(IEnumerable<Parameter> parameters)
{
AdditionalProperties ??= new List<Parameter>();
foreach (var parameter in parameters)
{
if (!AdditionalProperties.Any(property => property.Name == parameter.Name))
{
AdditionalProperties.Add(parameter);
}
}
}

private static ApiVersion[] ConvertApiVersions(IReadOnlyList<string> versions) =>
versions.Select((v, i) => new ApiVersion(NormalizeVersion(v), $"Service version \"{v}\"", i + 1, v)).ToArray();

Expand Down
4 changes: 4 additions & 0 deletions src/AutoRest.CSharp/LowLevel/Generation/DpgClientWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ private void WritePrimaryPublicConstructor(ConstructorSignature signature)
{
_writer.Line($"{field.Name:I} = {clientOptionsParameter.Name:I}.Version;");
}
else if (parameter.IsOptionalInSignature && !Configuration.KeepOptionalClientParametersInConstructor)
{
_writer.Line($"{field.Name:I} = {clientOptionsParameter.Name:I}.{parameter.Name.FirstCharToUpperCase()};");
}
else
{
_writer.Line($"{field.Name:I} = {parameter.Name:I};");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,8 @@ private IEnumerable<LowLevelClient> CreateClients(IEnumerable<ClientInfo> client

subClients.AddRange(CreateClients(clientInfo.Children, typeFactory, clientOptions, client));

clientOptions.AddAdditionalProperty(RestClientBuilder.GetOptionalParameters(client.Parameters));

yield return client;
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/AutoRest.CSharp/LowLevel/Output/LowLevelClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ public static IEnumerable<LowLevelClientMethod> BuildMethods(LowLevelClient? cli

private IEnumerable<ConstructorSignature> BuildPrimaryConstructors(IReadOnlyList<Parameter> requiredParameters, IReadOnlyList<Parameter> optionalParameters)
{
var optionalToRequired = optionalParameters
var neededOptionalParameters = Configuration.KeepOptionalClientParametersInConstructor ? optionalParameters : optionalParameters.Where(p => ClientOptions.Type.EqualsIgnoreNullable(p.Type));
var optionalToRequired = neededOptionalParameters
.Select(parameter => ClientOptions.Type.EqualsIgnoreNullable(parameter.Type)
? parameter with { DefaultValue = null, Validation = ValidationType.None }
: parameter with
Expand Down Expand Up @@ -191,15 +192,17 @@ private IEnumerable<ConstructorSignature> BuildSecondaryConstructors(IReadOnlyLi
yield return CreateMockingConstructor();
}

var neededOptionalParameters = Configuration.KeepOptionalClientParametersInConstructor ? optionalParameters : optionalParameters.Where(p => ClientOptions.Type.EqualsIgnoreNullable(p.Type));

/* Construct the parameter arguments to call primitive constructor.
* In primitive constructor, the endpoint is the first parameter,
* so put the endpoint as the first parameter argument if the endpoint is optional paramter.
* */
var optionalParametersArguments = optionalParameters
var optionalParametersArguments = neededOptionalParameters
.Where(p => !p.Name.Equals("endpoint", StringComparison.OrdinalIgnoreCase))
.Select(p => p.Initializer ?? p.Type.GetParameterInitializer(p.DefaultValue!.Value)!)
.ToArray();
var optionalEndpoint = optionalParameters.Where(p => p.Name.Equals("endpoint", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
var optionalEndpoint = neededOptionalParameters.Where(p => p.Name.Equals("endpoint", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
var arguments = new List<FormattableString>();
if (optionalEndpoint != null)
{
Expand Down
2 changes: 2 additions & 0 deletions src/TypeSpec.Extension/Emitter.Csharp/src/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ export async function $onEmit(context: EmitContext<NetEmitterOptions>) {
options["use-overloads-between-protocol-and-convenience"],
"keep-non-overloadable-protocol-signature":
options["keep-non-overloadable-protocol-signature"],
"keep-optional-client-parameters-in-constructor":
options["keep-optional-client-parameters-in-constructor"],
"model-namespace": options["model-namespace"],
"models-to-treat-empty-string-as-null":
options["models-to-treat-empty-string-as-null"],
Expand Down
5 changes: 5 additions & 0 deletions src/TypeSpec.Extension/Emitter.Csharp/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type NetEmitterOptions = {
"existing-project-folder"?: string;
"use-overloads-between-protocol-and-convenience"?: boolean;
"keep-non-overloadable-protocol-signature"?: boolean;
"keep-optional-client-parameters-in-constructor"?: boolean;
debug?: boolean;
"models-to-treat-empty-string-as-null"?: string[];
"additional-intrinsic-types-to-treat-empty-string-as-null"?: string[];
Expand Down Expand Up @@ -72,6 +73,10 @@ export const NetEmitterOptionsSchema: JSONSchemaType<NetEmitterOptions> = {
type: "boolean",
nullable: true
},
"keep-optional-client-parameters-in-constructor": {
type: "boolean",
nullable: true
},
debug: { type: "boolean", nullable: true },
"models-to-treat-empty-string-as-null": {
type: "array",
Expand Down
8 changes: 1 addition & 7 deletions src/assets/Azure.Core.Shared/RequestContentHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,7 @@ public static RequestContent FromObject(object value)
}
public static RequestContent FromObject(BinaryData value)
{
var content = new Utf8JsonRequestContent();
#if NET6_0_OR_GREATER
content.JsonWriter.WriteRawValue(value);
#else
JsonSerializer.Serialize(content.JsonWriter, JsonDocument.Parse(value).RootElement);
#endif
return content;
return value;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading