Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
6d603cd
implements the model reader writer functionalities
ArcturusZhang Dec 4, 2023
48f86d0
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Dec 7, 2023
caf7c9e
fix duplicated ExtendedLocationType
ArcturusZhang Dec 8, 2023
09d12c8
add a comment as description
ArcturusZhang Dec 8, 2023
75005df
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Dec 11, 2023
ff43409
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Dec 12, 2023
5888e23
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Dec 13, 2023
bc06ca3
add a config to turn the feature off
ArcturusZhang Dec 11, 2023
1b209e5
missing a place with configuration
ArcturusZhang Dec 13, 2023
15b9e26
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Dec 14, 2023
88000ed
update the comment
ArcturusZhang Dec 14, 2023
a50e9b2
update dependency
ArcturusZhang Dec 15, 2023
b0c69df
fix namespace in code
ArcturusZhang Dec 15, 2023
1573ad3
fix failures in test cases
ArcturusZhang Dec 15, 2023
e0b02e9
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Dec 15, 2023
a848d91
Regenerate all code (any successful run even without change will have…
actions-user Dec 15, 2023
aee2342
Merge remote-tracking branch 'origin/feature/v3' into public-serializ…
ArcturusZhang Dec 16, 2023
cb36a86
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Dec 18, 2023
80d30a3
introduce test cases to surface up the issue
ArcturusZhang Dec 18, 2023
46c3542
fix various issues
ArcturusZhang Dec 18, 2023
e0f3249
fix issues in spread cases
ArcturusZhang Dec 18, 2023
9d87c47
refine code
ArcturusZhang Dec 18, 2023
a9e1c62
Merge branch 'feature/v3' into fix-struct-issue-in-dpg
ArcturusZhang Dec 19, 2023
9113d8b
Merge remote-tracking branch 'forked/fix-struct-issue-in-dpg' into pu…
ArcturusZhang Dec 19, 2023
8c7e6db
fix the issues in structs
ArcturusZhang Dec 19, 2023
6ba738f
regen
ArcturusZhang Dec 19, 2023
aa86cca
Merge remote-tracking branch 'origin/feature/v3' into public-serializ…
ArcturusZhang Dec 19, 2023
37655a4
Merge remote-tracking branch 'origin/feature/v3' into public-serializ…
ArcturusZhang Dec 19, 2023
c5e02f0
resolve comments
ArcturusZhang Dec 20, 2023
2ceeba3
resolve comments
ArcturusZhang Dec 20, 2023
e61d6f5
regenerate
ArcturusZhang Dec 20, 2023
96e751e
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Dec 22, 2023
07217a2
Merge remote-tracking branch 'origin/feature/v3' into public-serializ…
ArcturusZhang Dec 26, 2023
21d2927
Merge remote-tracking branch 'origin/feature/v3' into public-serializ…
ArcturusZhang Dec 26, 2023
aa49fb5
regen but the additional properties project has some issues
ArcturusZhang Dec 26, 2023
d147c45
fix issuse in additional properties test project
ArcturusZhang Dec 27, 2023
287783c
enable model reader writer to additional properties project to ensure…
ArcturusZhang Dec 27, 2023
2fcb965
revert some changes in schemaobjecttype to align the changes in model…
ArcturusZhang Dec 27, 2023
81a345d
Regenerate all code (any successful run even without change will have…
actions-user Dec 27, 2023
aa4fda8
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Jan 2, 2024
358e278
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Jan 2, 2024
5ab8ee1
enable the feature on a xml test project to verify
ArcturusZhang Jan 2, 2024
f7c6305
Merge remote-tracking branch 'origin/feature/v3' into public-serializ…
ArcturusZhang Jan 3, 2024
fb5ef37
change the exception back to format exception
ArcturusZhang Jan 3, 2024
ba1e0bb
Regenerate all code (any successful run even without change will have…
actions-user Jan 3, 2024
33fdfd9
update the version to an official beta version
ArcturusZhang Jan 4, 2024
704cdd7
Merge branch 'feature/v3' into public-serialization
ArcturusZhang Jan 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion Packages.Data.props
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<!-- All csproj dependencies. -->
<ItemGroup>
<PackageReference Update="NUnit" Version="3.13.2" />
<PackageReference Update="System.Net.ClientModel" Version="1.0.0-beta.1" />
<PackageReference Update="System.ClientModel" Version="1.0.0-beta.3" />
<PackageReference Update="Azure.Core" Version="1.36.0" />
<PackageReference Update="Azure.Core.Experimental" Version="0.1.0-preview.18" />
<PackageReference Update="Azure.ResourceManager" Version="1.9.0" />
Expand Down
2 changes: 1 addition & 1 deletion eng/DownloadSharedSource.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ $files = @('AsyncLockWithValue.cs', 'CallerShouldAuditAttribute.cs', 'ClientDiag
'OperationInternalBase.cs', 'OperationInternal.cs', 'OperationInternalOfT.cs', 'TaskExtensions.cs', 'Argument.cs', 'Multipart/MultipartFormDataContent.cs',
'Multipart/MultipartContent.cs', 'AzureKeyCredentialPolicy.cs', 'AppContextSwitchHelper.cs',
'OperationPoller.cs', 'FixedDelayWithNoJitterStrategy.cs', 'SequentialDelayStrategy.cs',
'ForwardsClientCallsAttribute.cs', 'AsyncLockWithValue.cs', 'VoidValue.cs', 'AzureResourceProviderNamespaceAttribute.cs',
'ForwardsClientCallsAttribute.cs', 'VoidValue.cs', 'AzureResourceProviderNamespaceAttribute.cs',
'ChangeTrackingDictionary.cs',
'ChangeTrackingList.cs',
'FormUrlEncodedContent.cs',
Expand Down
3 changes: 2 additions & 1 deletion eng/Generate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ function Add-TestServer-Swagger ([string]$testName, [string]$projectSuffix, [str
}
$inputFile = Join-Path $testServerSwaggerPath "$testName.json"
$inputReadme = Join-Path $projectDirectory "readme.md"
Add-Swagger "$testName$projectSuffix" $projectDirectory "--require=$configurationPath --try-require=$inputReadme --input-file=$inputFile $additionalArgs --clear-output-folder=true"
# TODO -- remove the flag when the feature is generally available
Add-Swagger "$testName$projectSuffix" $projectDirectory "--require=$configurationPath --try-require=$inputReadme --input-file=$inputFile $additionalArgs --clear-output-folder=true --use-model-reader-writer=true"
}

function Add-CadlRanch-TypeSpec([string]$testName, [string]$projectPrefix, [string]$cadlRanchProjectsDirectory, [string]$outputProjectDir = "") {
Expand Down
1 change: 1 addition & 0 deletions samples/AnomalyDetector/src/AnomalyDetector.csproj

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

2 changes: 1 addition & 1 deletion src/AutoRest.CSharp/AutoRest.CSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<PackageReference Include="nunit" />
<!-- Any stable version of System.Memory should work here. -->
<PackageReference Include="System.Memory" />
<PackageReference Include="System.Net.ClientModel" />
<PackageReference Include="System.ClientModel" />
</ItemGroup>

<!-- Enable SourceLink -->
Expand Down
10 changes: 10 additions & 0 deletions src/AutoRest.CSharp/Common/AutoRest/Plugins/CSharpProj.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ private string GetCSProj()
builder.PackageReferences.Add(new("Azure.Core.Experimental"));
}

if (Configuration.UseModelReaderWriter)
{
builder.PackageReferences.Add(new("System.ClientModel"));
}

if (_needAzureKeyAuth)
{
builder.CompileIncludes.Add(new("$(AzureCoreSharedSources)AzureKeyCredentialPolicy.cs", "Shared/Core"));
Expand Down Expand Up @@ -161,6 +166,11 @@ private string GetExternalCSProj()
writer.PackageReferences.Add(new("Azure.Core.Expressions.DataFactory"));
}

if (Configuration.UseModelReaderWriter)
{
writer.PackageReferences.Add(new("System.ClientModel"));
}

var version = GetVersion();

writer.PrivatePackageReferences.Add(new("Microsoft.Azure.AutoRest.CSharp", version));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.ClientModel;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.ClientModel;
using System.Threading;
using System.Threading.Tasks;
using AutoRest.CSharp.Common.AutoRest.Plugins;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,11 @@ private string GetBrandedSrcCSProj()
{
builder.PackageReferences.Add(packages);
}
// TODO -- add this to _brandedDependencyPackages when we remove this flag
if (Configuration.UseModelReaderWriter)
{
builder.PackageReferences.Add(new("System.ClientModel"));
}

return builder.Write();
}
Expand Down Expand Up @@ -335,7 +340,7 @@ private string GetUnbrandedSrcCSProj()
};
private static readonly IReadOnlyList<CSProjWriter.CSProjDependencyPackage> _unbrandedDependencyPackages = new CSProjWriter.CSProjDependencyPackage[]
{
new("System.Net.ClientModel", "1.0.0-beta.1"),
new("System.ClientModel", "1.0.0-beta.3"),
new("System.Text.Json", "4.7.2")
};

Expand Down
9 changes: 5 additions & 4 deletions src/AutoRest.CSharp/Common/Decorator/DefaultDerivedSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AutoRest.CSharp.Common.Input;
using AutoRest.CSharp.Input;
using AutoRest.CSharp.Output.Models.Types;

namespace AutoRest.CSharp.Common.Decorator
{
internal static class DefaultDerivedSchema
{
public const string DefaultDerivedExtension = "x-ms-autorest-defaultDerivedSchema";
private const string DefaultDerivedExtension = "x-ms-autorest-defaultDerivedSchema";

public static void AddDefaultDerivedSchemas(CodeModel codeModel)
{
Expand Down Expand Up @@ -52,8 +51,9 @@ private static void BuildInternalDefaultDerivedType(ObjectSchema schema, Diction
throw new InvalidOperationException($"Found a child poly {schema.Language.Default.Name} that we weren't able to determine its base poly from {string.Join(',', schema.Parents?.Immediate.Select(p => p.Name) ?? Array.Empty<string>())}");

//Since the unknown type is used for deserialization only we don't need to create if its an input only model
// TODO -- remove this condition completely when remove the UseModelReaderWriter flag
var hasXCsharpUsageOutput = !actualBaseSchema.Extensions?.Usage?.Contains("output", StringComparison.OrdinalIgnoreCase);
if (!actualBaseSchema.Usage.Contains(SchemaContext.Output) &&
if (!Configuration.UseModelReaderWriter && !actualBaseSchema.Usage.Contains(SchemaContext.Output) &&
!actualBaseSchema.Usage.Contains(SchemaContext.Exception) &&
(!hasXCsharpUsageOutput.HasValue ||
hasXCsharpUsageOutput.Value))
Expand Down Expand Up @@ -96,6 +96,7 @@ private static void BuildInternalDefaultDerivedType(ObjectSchema schema, Diction
},
DiscriminatorValue = "Unknown",
SerializationFormats = { KnownMediaType.Json },
IsUnknownDiscriminatorModel = true
};

if (actualBaseSchema.Parents is not null)
Expand Down
4 changes: 4 additions & 0 deletions src/AutoRest.CSharp/Common/Generation/Writers/CodeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Linq;
using System.Text;
using AutoRest.CSharp.Common.Input;
using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions;
using AutoRest.CSharp.Generation.Types;
using AutoRest.CSharp.Utilities;
using Microsoft.CodeAnalysis.CSharp;
Expand Down Expand Up @@ -175,6 +176,9 @@ public CodeWriter Append(FormattableString formattableString)
case CodeWriterDeclaration declaration:
Append(declaration);
break;
case ValueExpression expression:
this.WriteValueExpression(expression);
break;
case var _ when isLiteralFormat:
Literal(argument);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,12 @@ public static void WriteValueExpression(this CodeWriter writer, ValueExpression
switch (expression)
{
case CastExpression cast:
// wrap the cast expression with parenthesis, so that it would not cause ambiguity for leading recursive calls
// if the parenthesis are not needed, the roslyn reducer will remove it.
writer.AppendRaw("(");
writer.Append($"({cast.Type})");
writer.WriteValueExpression(cast.Inner);
writer.AppendRaw(")");
break;
case CollectionInitializerExpression(var items):
writer.AppendRaw("{ ");
Expand Down Expand Up @@ -570,9 +574,12 @@ public static void WriteValueExpression(this CodeWriter writer, ValueExpression
writer.AppendRawIf(op, operandOnTheLeft);
break;
case BinaryOperatorExpression(var op, var left, var right):
// we should always write parenthesis around this expression since some or the logic operator has lower priority, and we might get trouble when there is a chain of binary operator expression, for instance (a || b) && c.
writer.AppendRaw("(");
writer.WriteValueExpression(left);
writer.AppendRaw(" ").AppendRaw(op).AppendRaw(" ");
writer.WriteValueExpression(right);
writer.AppendRaw(")");
break;
case TernaryConditionalOperator ternary:
writer.WriteValueExpression(ternary.Condition);
Expand All @@ -585,8 +592,9 @@ public static void WriteValueExpression(this CodeWriter writer, ValueExpression
writer.Append($"{parameterName}: ");
writer.WriteValueExpression(value);
break;
case ParameterReference parameterReference:
writer.Append($"{parameterReference.Parameter.Name:I}");
case ParameterReference(var parameter):
writer.AppendRawIf("ref ", parameter.IsRef);
writer.Append($"{parameter.Name:I}");
break;
case FormattableStringToExpression formattableString:
writer.Append(formattableString.Value);
Expand Down Expand Up @@ -639,6 +647,10 @@ public static void WriteValueExpression(this CodeWriter writer, ValueExpression
writer.WriteValueExpression(index);
writer.AppendRaw("]");
break;
case DeclarationExpression(var variable, var isOut):
writer.AppendRawIf("out ", isOut);
writer.Append($"{variable.Type} {variable.Declaration:D}");
break;
}

static void WriteArguments(CodeWriter writer, IEnumerable<ValueExpression> arguments)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ private static IDisposable WriteMethodDeclarationNoScope(this CodeWriter writer,
writer.AppendRaw(isBase ? ": base(" : ": this(");
foreach (var argument in arguments)
{
writer.WriteValueExpression(new FormattableStringToExpression(argument));
writer.WriteValueExpression(argument);
writer.AppendRaw(", ");
}
writer.RemoveTrailingComma();
Expand Down Expand Up @@ -321,6 +321,8 @@ public static void WriteParameter(this CodeWriter writer, Parameter clientParame
writer.AppendRaw("]");
}

writer.AppendRawIf("ref ", clientParameter.IsRef);

writer.Append($"{clientParameter.Type} {clientParameter.Name:D}");
if (clientParameter.DefaultValue != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ private static void WriteCreateResultBody(CodeWriter writer, LongRunningOperatio
var scopeName = operation.Diagnostics.ScopeName;
var nextLinkName = pagingResponse.NextLinkPropertyName;
var itemName = pagingResponse.ItemPropertyName;
FormattableString returnValue = $"{typeof(GeneratorPageableHelpers)}.{nameof(GeneratorPageableHelpers.CreateAsyncPageable)}({responseVariable}, _nextPageFunc, Product.DeserializeProduct, _clientDiagnostics, _pipeline, {scopeName:L}, {itemName:L}, {nextLinkName:L}, cancellationToken)";
// TODO -- why we have a hard-coded Product.DeserializeProduct here???
FormattableString returnValue = $"{typeof(GeneratorPageableHelpers)}.{nameof(GeneratorPageableHelpers.CreateAsyncPageable)}({responseVariable}, _nextPageFunc, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, {scopeName:L}, {itemName:L}, {nextLinkName:L}, cancellationToken)";
WriteCreateResultReturnValue(writer, resultType, returnValue, async);
}
else if (operation.ResultSerialization != null)
Expand Down
21 changes: 21 additions & 0 deletions src/AutoRest.CSharp/Common/Generation/Writers/ModelWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using AutoRest.CSharp.Common.Output.Models.Types;
using AutoRest.CSharp.Generation.Types;
using AutoRest.CSharp.Output.Models;
using AutoRest.CSharp.Output.Models.Types;
Expand Down Expand Up @@ -69,6 +70,8 @@ private void WriteObjectSchema(CodeWriter writer, ObjectType schema)
writer.Line();
using (writer.Scope())
{
WritePrivateRawDataField(writer, schema);

WriteConstructor(writer, schema);

WriteProperties(writer, schema);
Expand All @@ -78,15 +81,33 @@ private void WriteObjectSchema(CodeWriter writer, ObjectType schema)

protected virtual void WriteProperties(CodeWriter writer, ObjectType schema)
{
var rawDataField = (schema as SerializableObjectType)?.RawDataField;
foreach (var property in schema.Properties)
{
if (property == rawDataField)
continue;

WriteProperty(writer, property);

if (property.FlattenedProperty != null)
WriteProperty(writer, property.FlattenedProperty);
}
}

// TODO -- this is workaround because we are declaring fields and properties in different way, and this raw data field and AdditionalProperties property could be converted from each other.
private void WritePrivateRawDataField(CodeWriter writer, ObjectType schema)
{
if ((schema as SerializableObjectType)?.RawDataField is not { } rawDataField)
return;

writer.WriteXmlDocumentationSummary($"{rawDataField.Description}");
writer.Append($"{rawDataField.Declaration.Accessibility} ")
.AppendRawIf("readonly ", schema.IsStruct)
.Line($"{rawDataField.Declaration.Type} {rawDataField.Declaration.Name};");

writer.Line();
}

private void WriteFieldModifiers(CodeWriter writer, FieldModifiers modifiers)
{
writer.AppendRawIf("public ", modifiers.HasFlag(FieldModifiers.Public))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,13 @@ private static FormattableString GetValueFactory(CSharpType? pageItemType)
return $"e => {BinaryDataType}.{nameof(BinaryData.FromString)}(e.{nameof(JsonElement.GetRawText)}())";
}

if (!pageItemType.IsFrameworkType && pageItemType.Implementation is SerializableObjectType { JsonSerialization: { }, IncludeDeserializer: true } type)
if (!pageItemType.IsFrameworkType && pageItemType.Implementation is SerializableObjectType { JsonSerialization: { } } type)
{
return $"{type.Type}.Deserialize{type.Declaration.Name}";
// TODO -- we no longer need this once we remove the UseModelReaderWriter flag
if (Configuration.UseModelReaderWriter)
return $"e => {type.Type}.Deserialize{type.Declaration.Name}(e)";
else
return $"{type.Type}.Deserialize{type.Declaration.Name}";
}

var deserializeImplementation = JsonCodeWriterExtensions.GetDeserializeValueFormattable($"e", pageItemType);
Expand Down
Loading