diff --git a/Packages.Data.props b/Packages.Data.props index 931e6970b23..8046b78f1f2 100644 --- a/Packages.Data.props +++ b/Packages.Data.props @@ -26,7 +26,7 @@ - + diff --git a/eng/DownloadSharedSource.ps1 b/eng/DownloadSharedSource.ps1 index 29e01e01782..bdf1db52c5c 100644 --- a/eng/DownloadSharedSource.ps1 +++ b/eng/DownloadSharedSource.ps1 @@ -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', diff --git a/eng/Generate.ps1 b/eng/Generate.ps1 index 6f67e3dd76d..f46cbce18b4 100644 --- a/eng/Generate.ps1 +++ b/eng/Generate.ps1 @@ -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 = "") { diff --git a/samples/AnomalyDetector/src/AnomalyDetector.csproj b/samples/AnomalyDetector/src/AnomalyDetector.csproj index fdef1360e01..abe323bb6ac 100644 --- a/samples/AnomalyDetector/src/AnomalyDetector.csproj +++ b/samples/AnomalyDetector/src/AnomalyDetector.csproj @@ -15,6 +15,7 @@ + diff --git a/src/AutoRest.CSharp/AutoRest.CSharp.csproj b/src/AutoRest.CSharp/AutoRest.CSharp.csproj index 23feae6672d..514290a42d0 100644 --- a/src/AutoRest.CSharp/AutoRest.CSharp.csproj +++ b/src/AutoRest.CSharp/AutoRest.CSharp.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/AutoRest.CSharp/Common/AutoRest/Plugins/CSharpProj.cs b/src/AutoRest.CSharp/Common/AutoRest/Plugins/CSharpProj.cs index 9137da71be1..5d88169e098 100644 --- a/src/AutoRest.CSharp/Common/AutoRest/Plugins/CSharpProj.cs +++ b/src/AutoRest.CSharp/Common/AutoRest/Plugins/CSharpProj.cs @@ -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")); @@ -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)); diff --git a/src/AutoRest.CSharp/Common/AutoRest/Plugins/GeneratedCodeWorkspace.cs b/src/AutoRest.CSharp/Common/AutoRest/Plugins/GeneratedCodeWorkspace.cs index 8b8d13c3b8b..2f7916809f9 100644 --- a/src/AutoRest.CSharp/Common/AutoRest/Plugins/GeneratedCodeWorkspace.cs +++ b/src/AutoRest.CSharp/Common/AutoRest/Plugins/GeneratedCodeWorkspace.cs @@ -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; diff --git a/src/AutoRest.CSharp/Common/AutoRest/Plugins/NewProjectScaffolding.cs b/src/AutoRest.CSharp/Common/AutoRest/Plugins/NewProjectScaffolding.cs index fd5588df61e..81be16aaf78 100644 --- a/src/AutoRest.CSharp/Common/AutoRest/Plugins/NewProjectScaffolding.cs +++ b/src/AutoRest.CSharp/Common/AutoRest/Plugins/NewProjectScaffolding.cs @@ -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(); } @@ -335,7 +340,7 @@ private string GetUnbrandedSrcCSProj() }; private static readonly IReadOnlyList _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") }; diff --git a/src/AutoRest.CSharp/Common/Decorator/DefaultDerivedSchema.cs b/src/AutoRest.CSharp/Common/Decorator/DefaultDerivedSchema.cs index 1bf9b544aa0..6af03ddd497 100644 --- a/src/AutoRest.CSharp/Common/Decorator/DefaultDerivedSchema.cs +++ b/src/AutoRest.CSharp/Common/Decorator/DefaultDerivedSchema.cs @@ -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) { @@ -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())}"); //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)) @@ -96,6 +96,7 @@ private static void BuildInternalDefaultDerivedType(ObjectSchema schema, Diction }, DiscriminatorValue = "Unknown", SerializationFormats = { KnownMediaType.Json }, + IsUnknownDiscriminatorModel = true }; if (actualBaseSchema.Parents is not null) diff --git a/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriter.cs b/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriter.cs index 66c75df7874..29f13bb5317 100644 --- a/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriter.cs +++ b/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriter.cs @@ -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; @@ -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; diff --git a/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriterExtensions.Methods.cs b/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriterExtensions.Methods.cs index ab34693e0ab..74b512c941d 100644 --- a/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriterExtensions.Methods.cs +++ b/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriterExtensions.Methods.cs @@ -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("{ "); @@ -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); @@ -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); @@ -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 arguments) diff --git a/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriterExtensions.cs b/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriterExtensions.cs index 410d6aae06b..5aa6b0167fe 100644 --- a/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriterExtensions.cs +++ b/src/AutoRest.CSharp/Common/Generation/Writers/CodeWriterExtensions.cs @@ -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(); @@ -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) { diff --git a/src/AutoRest.CSharp/Common/Generation/Writers/LongRunningOperationWriter.cs b/src/AutoRest.CSharp/Common/Generation/Writers/LongRunningOperationWriter.cs index d35435b78a2..c7a15fcb69e 100644 --- a/src/AutoRest.CSharp/Common/Generation/Writers/LongRunningOperationWriter.cs +++ b/src/AutoRest.CSharp/Common/Generation/Writers/LongRunningOperationWriter.cs @@ -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) diff --git a/src/AutoRest.CSharp/Common/Generation/Writers/ModelWriter.cs b/src/AutoRest.CSharp/Common/Generation/Writers/ModelWriter.cs index 896bf0e5b8e..e4933e3ef71 100644 --- a/src/AutoRest.CSharp/Common/Generation/Writers/ModelWriter.cs +++ b/src/AutoRest.CSharp/Common/Generation/Writers/ModelWriter.cs @@ -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; @@ -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); @@ -78,8 +81,12 @@ 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) @@ -87,6 +94,20 @@ protected virtual void WriteProperties(CodeWriter writer, ObjectType schema) } } + // 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)) diff --git a/src/AutoRest.CSharp/Common/Generation/Writers/PageableMethodsWriterExtensions.cs b/src/AutoRest.CSharp/Common/Generation/Writers/PageableMethodsWriterExtensions.cs index 1de514d9beb..f59fd69b2e2 100644 --- a/src/AutoRest.CSharp/Common/Generation/Writers/PageableMethodsWriterExtensions.cs +++ b/src/AutoRest.CSharp/Common/Generation/Writers/PageableMethodsWriterExtensions.cs @@ -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); diff --git a/src/AutoRest.CSharp/Common/Generation/Writers/SerializationWriter.cs b/src/AutoRest.CSharp/Common/Generation/Writers/SerializationWriter.cs index 3c3f8d6a8ab..d2212dca9df 100644 --- a/src/AutoRest.CSharp/Common/Generation/Writers/SerializationWriter.cs +++ b/src/AutoRest.CSharp/Common/Generation/Writers/SerializationWriter.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using System.ClientModel.Primitives; using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; @@ -22,10 +23,10 @@ public void WriteSerialization(CodeWriter writer, TypeProvider schema) { switch (schema) { - case SerializableObjectType objectSchema: - if (objectSchema.IncludeSerializer || objectSchema.IncludeDeserializer) + case SerializableObjectType obj: + if (obj.IncludeSerializer || obj.IncludeDeserializer) { - WriteObjectSerialization(writer, objectSchema); + WriteObjectSerialization(writer, obj); } break; case EnumType { IsExtensible: false } sealedChoiceSchema: @@ -35,64 +36,61 @@ public void WriteSerialization(CodeWriter writer, TypeProvider schema) } private void WriteObjectSerialization(CodeWriter writer, SerializableObjectType model) - => WriteObjectSerialization(writer, model, model.Declaration, model.JsonSerialization, model.XmlSerialization, model.IsStruct, model.IncludeSerializer, model.IncludeDeserializer); - - private void WriteObjectSerialization(CodeWriter writer, SerializableObjectType model, TypeDeclarationOptions declaration, JsonObjectSerialization? jsonSerialization, XmlObjectSerialization? xmlSerialization, bool isStruct, bool includeSerializer, bool includeDeserializer) { - var hasJson = jsonSerialization != null; - var hasXml = xmlSerialization != null; + var declaration = model.Declaration; + var json = model.JsonSerialization; + var xml = model.XmlSerialization; - if (!hasJson && !hasXml) + if (json == null && xml == null) { return; } using (writer.Namespace(declaration.Namespace)) { - if (jsonSerialization is { IncludeConverter: true }) + if (json is { IncludeConverter: true }) { writer.Append($"[{typeof(JsonConverter)}(typeof({declaration.Name}Converter))]"); } + // write the serialization proxy attribute if the model is abstract + if (Configuration.UseModelReaderWriter && declaration.IsAbstract && model.Discriminator is { } discriminator) + { + var unknown = discriminator.DefaultObjectType; + writer.Append($"[{typeof(PersistableModelProxyAttribute)}(typeof({unknown.Type}))]"); + } - writer.Append($"{declaration.Accessibility} partial {(isStruct ? "struct" : "class")} {declaration.Name}"); + writer.Append($"{declaration.Accessibility} partial {(model.IsStruct ? "struct" : "class")} {declaration.Name}") + .AppendRawIf(" : ", model.IncludeSerializer); - if (includeSerializer) + if (json != null && model.IncludeSerializer) + { + writer.Append($"{json.IJsonInterface}, ") + .AppendIf($"{json.IJsonModelInterface}, ", Configuration.UseModelReaderWriter); + if (Configuration.UseModelReaderWriter && json.IJsonModelObjectInterface is { } jsonModelObjectInterface) + writer.Append($"{jsonModelObjectInterface}, "); + } + if (xml != null && model.IncludeSerializer) { - writer - .AppendIf($": ", hasJson || hasXml) - .AppendIf($"{Configuration.ApiTypes.IUtf8JsonSerializableType}, ", hasJson) - .AppendIf($"{typeof(IXmlSerializable)}, ", hasXml) - .RemoveTrailingComma(); + writer.Append($"{xml.IXmlInterface}, ") + .AppendIf($"{xml.IPersistableModelTInterface}, ", Configuration.UseModelReaderWriter); } + writer.RemoveTrailingComma(); + writer.Line(); using (writer.Scope()) { - if (xmlSerialization != null) + if (xml != null) { - if (includeSerializer) - { - WriteXmlSerialize(writer, xmlSerialization); - } - - if (includeDeserializer) - { - WriteXmlDeserialize(writer, declaration, xmlSerialization); - } + WriteXmlSerialization(writer, model, xml); } - if (jsonSerialization != null) + if (json != null) { - if (includeSerializer) - { - WriteJsonSerialize(writer, jsonSerialization); - } - - if (includeDeserializer) - { - WriteJsonDeserialize(writer, declaration, jsonSerialization, model); - } + WriteJsonSerialization(writer, model, json); } + WriteIModelImplementations(writer, model, json, xml); + foreach (var method in model.Methods) { writer.WriteXmlDocumentationSummary(method.Signature.Description); @@ -100,9 +98,9 @@ private void WriteObjectSerialization(CodeWriter writer, SerializableObjectType writer.WriteMethod(method); } - if (jsonSerialization is { IncludeConverter: true }) + if (json is { IncludeConverter: true }) { - WriteCustomJsonConverter(writer, declaration, jsonSerialization.Type, includeSerializer, includeDeserializer); + WriteCustomJsonConverter(writer, declaration, json.Type, model.IncludeSerializer, model.IncludeDeserializer); } } } @@ -113,7 +111,7 @@ private static void WriteCustomJsonConverter(CodeWriter writer, TypeDeclarationO writer.Append($"internal partial class {declaration.Name}Converter : {typeof(JsonConverter)}<{type}>"); using (writer.Scope()) { - using (writer.Scope($"public override void Write({typeof(Utf8JsonWriter)} writer, {type} model, {typeof(JsonSerializerOptions)} options)")) + using (writer.Scope($"public override void Write({typeof(Utf8JsonWriter)} writer, {type} model, {typeof(JsonSerializerOptions)} options)")) { if (includeSerializer) { @@ -141,27 +139,68 @@ private static void WriteCustomJsonConverter(CodeWriter writer, TypeDeclarationO } } - private static void WriteXmlSerialize(CodeWriter writer, XmlObjectSerialization serialization) + /// + /// This method writes the implementation of IXmlSerializable and the static deserialization method + /// + /// + /// + /// + private static void WriteXmlSerialization(CodeWriter writer, SerializableObjectType model, XmlObjectSerialization xml) { - writer.WriteMethod(XmlSerializationMethodsBuilder.BuildXmlSerializableWrite(serialization)); - } + if (model.IncludeSerializer) + { + foreach (var method in XmlSerializationMethodsBuilder.BuildXmlSerializationMethods(xml)) + { + writer.WriteMethod(method); + } + } - private static void WriteXmlDeserialize(CodeWriter writer, TypeDeclarationOptions declaration, XmlObjectSerialization serialization) - { - writer.WriteMethod(XmlSerializationMethodsBuilder.BuildDeserialize(declaration, serialization)); + if (model.IncludeDeserializer) + writer.WriteMethod(XmlSerializationMethodsBuilder.BuildDeserialize(model.Declaration, xml)); } - private static void WriteJsonDeserialize(CodeWriter writer, TypeDeclarationOptions declaration, JsonObjectSerialization serialization, SerializableObjectType model) + /// + /// This method writes the implementation of IUtf8JsonSerializable, IJsonModel{T} and the static deserialization method + /// If the model is defined as a struct, including the implementation of IJsonModel{object} + /// NOTE: the inherited methods from IModel{T} and IModel{object} is excluded + /// + /// + /// + /// + private static void WriteJsonSerialization(CodeWriter writer, SerializableObjectType model, JsonObjectSerialization json) { - if (JsonSerializationMethodsBuilder.BuildDeserialize(declaration, serialization, model.GetExistingType()) is {} deserialize) + // the methods that implement the interface IJsonModel (and IJsonModel if eligible) (do not include the methods inherited from IModel or IModel) + if (model.IncludeSerializer) + { + foreach (var method in JsonSerializationMethodsBuilder.BuildJsonSerializationMethods(model, json)) + { + writer.WriteMethod(method); + } + } + + // the deserialize static method + if (model.IncludeDeserializer) { - writer.WriteMethod(deserialize); + if (JsonSerializationMethodsBuilder.BuildDeserialize(model.Declaration, json, model.GetExistingType()) is { } deserialize) + { + writer.WriteMethod(deserialize); + } } } - private static void WriteJsonSerialize(CodeWriter writer, JsonObjectSerialization jsonSerialization) + /// + /// This method writes the implementation of IModel{T} + /// + /// + /// + /// + /// + private static void WriteIModelImplementations(CodeWriter writer, SerializableObjectType model, JsonObjectSerialization? json, XmlObjectSerialization? xml) { - writer.WriteMethod(JsonSerializationMethodsBuilder.BuildUtf8JsonSerializableWrite(jsonSerialization)); + foreach (var method in JsonSerializationMethodsBuilder.BuildIModelMethods(model, json, xml)) + { + writer.WriteMethod(method); + } } public static void WriteEnumSerialization(CodeWriter writer, EnumType enumType) diff --git a/src/AutoRest.CSharp/Common/Input/ApiTypes.cs b/src/AutoRest.CSharp/Common/Input/ApiTypes.cs index f92db3920a8..a0fa5e617bf 100644 --- a/src/AutoRest.CSharp/Common/Input/ApiTypes.cs +++ b/src/AutoRest.CSharp/Common/Input/ApiTypes.cs @@ -2,9 +2,9 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Threading.Tasks; using AutoRest.CSharp.Common.Output.Expressions; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; @@ -85,6 +85,7 @@ public FormattableString GetHttpPipelineKeyCredentialString(string pipelineField public abstract string RequestContentCreateName { get; } public abstract Type IUtf8JsonSerializableType { get; } + public abstract Type IXmlSerializableType { get; } public string IUtf8JsonSerializableWriteName => nameof(IUtf8JsonWriteable.Write); public abstract Type Utf8JsonWriterExtensionsType { get; } diff --git a/src/AutoRest.CSharp/Common/Input/AzureApiTypes.cs b/src/AutoRest.CSharp/Common/Input/AzureApiTypes.cs index 24f65dca13b..83e5fe497f2 100644 --- a/src/AutoRest.CSharp/Common/Input/AzureApiTypes.cs +++ b/src/AutoRest.CSharp/Common/Input/AzureApiTypes.cs @@ -68,6 +68,8 @@ public override FormattableString GetSetContentString(string requestName, string public override Type IUtf8JsonSerializableType => typeof(IUtf8JsonSerializable); + public override Type IXmlSerializableType => typeof(IXmlSerializable); + public override Type Utf8JsonWriterExtensionsType => typeof(Utf8JsonWriterExtensions); public override Type OptionalType => typeof(Optional); diff --git a/src/AutoRest.CSharp/Common/Input/CodeModelPartials.cs b/src/AutoRest.CSharp/Common/Input/CodeModelPartials.cs index c43e015ac07..b0da84e83f4 100644 --- a/src/AutoRest.CSharp/Common/Input/CodeModelPartials.cs +++ b/src/AutoRest.CSharp/Common/Input/CodeModelPartials.cs @@ -261,6 +261,8 @@ public ObjectSchema() Parents = new Relations(); Children = new Relations(); } + + public bool IsUnknownDiscriminatorModel { get; init; } } // redefined manually to inherit from ObjectSchema diff --git a/src/AutoRest.CSharp/Common/Input/Configuration.cs b/src/AutoRest.CSharp/Common/Input/Configuration.cs index 0be6ea47d5f..28de9815d11 100644 --- a/src/AutoRest.CSharp/Common/Input/Configuration.cs +++ b/src/AutoRest.CSharp/Common/Input/Configuration.cs @@ -54,6 +54,8 @@ public static class Options public const string UseCoreDataFactoryReplacements = "use-core-datafactory-replacements"; public const string Branded = "branded"; public const string GenerateTestProject = "generateTestProject"; + // TODO - this configuration only exists here because we would like a rolling update for all libraries for this feature since it changes so many files. + public const string UseModelReaderWriter = "use-model-reader-writer"; } public enum UnreferencedTypesHandlingOption @@ -83,6 +85,7 @@ public static void Initialize( bool publicDiscriminatorProperty, bool deserializeNullCollectionAsNullValue, bool useCoreDataFactoryReplacements, + bool useModelReaderWriter, IReadOnlyList modelFactoryForHlc, UnreferencedTypesHandlingOption unreferencedTypesHandling, bool keepNonOverloadableProtocolSignature, @@ -119,6 +122,7 @@ public static void Initialize( KeepNonOverloadableProtocolSignature = keepNonOverloadableProtocolSignature; ShouldTreatBase64AsBinaryData = !azureArm && !generation1ConvenienceClient ? shouldTreatBase64AsBinaryData : false; UseCoreDataFactoryReplacements = useCoreDataFactoryReplacements; + UseModelReaderWriter = useModelReaderWriter; projectFolder ??= ProjectFolderDefault; (_absoluteProjectFolder, _relativeProjectFolder) = ParseProjectFolders(outputFolder, projectFolder); @@ -222,6 +226,8 @@ internal static (string AbsoluteProjectFolder, string RelativeProjectFolder) Par public static bool UseCoreDataFactoryReplacements { get; private set; } + public static bool UseModelReaderWriter { get; private set; } + private static string? _outputFolder; public static string OutputFolder => _outputFolder ?? throw new InvalidOperationException("Configuration has not been initialized"); public static string? ExistingProjectFolder { get; private set; } @@ -319,6 +325,7 @@ public static void Initialize(IPluginCommunication autoRest, string defaultNames unreferencedTypesHandling: GetOptionEnumValue(autoRest, Options.UnreferencedTypesHandling), keepNonOverloadableProtocolSignature: GetOptionBoolValue(autoRest, Options.KeepNonOverloadableProtocolSignature), useCoreDataFactoryReplacements: GetOptionBoolValue(autoRest, Options.UseCoreDataFactoryReplacements), + useModelReaderWriter: GetOptionBoolValue(autoRest, Options.UseModelReaderWriter), projectFolder: GetProjectFolderOption(autoRest), existingProjectFolder: autoRest.GetValue(Options.ExistingProjectfolder).GetAwaiter().GetResult(), protocolMethodList: autoRest.GetValue(Options.ProtocolMethodList).GetAwaiter().GetResult() ?? Array.Empty(), @@ -403,6 +410,8 @@ private static bool GetOptionBoolValue(IPluginCommunication autoRest, string opt return true; case Options.GenerateTestProject: return true; + case Options.UseModelReaderWriter: + return false; default: return null; } @@ -475,6 +484,7 @@ internal static void LoadConfiguration(JsonElement root, string? projectPath, st ReadOption(root, Options.PublicDiscriminatorProperty), ReadOption(root, Options.DeserializeNullCollectionAsNullValue), ReadOption(root, Options.UseCoreDataFactoryReplacements), + ReadOption(root, Options.UseModelReaderWriter), oldModelFactoryEntries, ReadEnumOption(root, Options.UnreferencedTypesHandling), ReadOption(root, Options.KeepNonOverloadableProtocolSignature), @@ -535,6 +545,7 @@ private static void WriteConfiguration(Utf8JsonWriter writer) WriteIfNotDefault(writer, Options.UnreferencedTypesHandling, UnreferencedTypesHandling); WriteIfNotDefault(writer, Options.ProjectFolder, RelativeProjectFolder); WriteIfNotDefault(writer, Options.UseCoreDataFactoryReplacements, UseCoreDataFactoryReplacements); + WriteIfNotDefault(writer, Options.UseModelReaderWriter, UseModelReaderWriter); writer.WriteNonEmptyArray(Options.ProtocolMethodList, ProtocolMethodList); writer.WriteNonEmptyArray(Options.SuppressAbstractBaseClasses, SuppressAbstractBaseClasses); writer.WriteNonEmptyArray(Options.ModelsToTreatEmptyStringAsNull, ModelsToTreatEmptyStringAsNull.ToList()); diff --git a/src/AutoRest.CSharp/Common/Input/SystemApiTypes.cs b/src/AutoRest.CSharp/Common/Input/SystemApiTypes.cs index 89e6aba1200..41f9a3ebd7b 100644 --- a/src/AutoRest.CSharp/Common/Input/SystemApiTypes.cs +++ b/src/AutoRest.CSharp/Common/Input/SystemApiTypes.cs @@ -2,10 +2,10 @@ // Licensed under the MIT License. using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using AutoRest.CSharp.Common.Output.Expressions; using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions; using AutoRest.CSharp.Common.Output.Expressions.System; @@ -14,7 +14,7 @@ using AutoRest.CSharp.Output.Models; using AutoRest.CSharp.Output.Models.Requests; using Azure.Core.Pipeline; //needed because BearerTokenAuthenticationPolicy doesn't exist in System.ServiceModel.Rest yet -using RequestBody = System.Net.ClientModel.Core.RequestBody; +using RequestBody = System.ClientModel.Primitives.RequestBody; namespace AutoRest.CSharp.Common.Input { @@ -80,6 +80,8 @@ public override FormattableString GetSetContentString(string requestName, string public override Type IUtf8JsonSerializableType => typeof(IUtf8JsonWriteable); + public override Type IXmlSerializableType => throw new NotSupportedException("Xml serialization is not supported in non-branded libraries yet"); + public override Type Utf8JsonWriterExtensionsType => typeof(ModelSerializationExtensions); public override Type OptionalType => typeof(OptionalProperty); diff --git a/src/AutoRest.CSharp/Common/Output/Builders/JsonSerializationMethodsBuilder.cs b/src/AutoRest.CSharp/Common/Output/Builders/JsonSerializationMethodsBuilder.cs index 401be992230..2ab07a66f3a 100644 --- a/src/AutoRest.CSharp/Common/Output/Builders/JsonSerializationMethodsBuilder.cs +++ b/src/AutoRest.CSharp/Common/Output/Builders/JsonSerializationMethodsBuilder.cs @@ -2,12 +2,18 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using System.ClientModel; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Text.Json; using System.Text.Json.Serialization; +using System.Xml; using AutoRest.CSharp.Common.Input; using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions; using AutoRest.CSharp.Common.Output.Expressions.Statements; @@ -22,53 +28,296 @@ using AutoRest.CSharp.Output.Models; using AutoRest.CSharp.Output.Models.Serialization; using AutoRest.CSharp.Output.Models.Serialization.Json; +using AutoRest.CSharp.Output.Models.Serialization.Xml; using AutoRest.CSharp.Output.Models.Shared; using AutoRest.CSharp.Output.Models.Types; using AutoRest.CSharp.Utilities; using Azure; using Azure.Core; +using Azure.ResourceManager.Resources.Models; using Microsoft.CodeAnalysis; using static AutoRest.CSharp.Common.Output.Models.Snippets; +using SerializationFormat = AutoRest.CSharp.Output.Models.Serialization.SerializationFormat; namespace AutoRest.CSharp.Common.Output.Builders { internal static class JsonSerializationMethodsBuilder { - public static Method BuildUtf8JsonSerializableWrite(JsonObjectSerialization jsonObjectSerialization) + public static IEnumerable BuildJsonSerializationMethods(SerializableObjectType model, JsonObjectSerialization json) { - var utf8JsonWriter = new Parameter("writer", null, typeof(Utf8JsonWriter), null, ValidationType.None, null); - return new Method + var jsonModelInterface = json.IJsonModelInterface; + var typeOfT = jsonModelInterface.Arguments[0]; + + var useModelReaderWriter = Configuration.UseModelReaderWriter; + + // void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + var writer = new Utf8JsonWriterExpression(KnownParameters.Serializations.Utf8JsonWriter); + if (useModelReaderWriter) + { + yield return new + ( + new MethodSignature(Configuration.ApiTypes.IUtf8JsonSerializableWriteName, null, null, MethodSignatureModifiers.None, null, null, new[] { KnownParameters.Serializations.Utf8JsonWriter }, ExplicitInterface: Configuration.ApiTypes.IUtf8JsonSerializableType), + This.CastTo(jsonModelInterface).Invoke(nameof(IJsonModel.Write), writer, ModelReaderWriterOptionsExpression.Wire) + ); + } + else + { + yield return new + ( + new MethodSignature(Configuration.ApiTypes.IUtf8JsonSerializableWriteName, null, null, MethodSignatureModifiers.None, null, null, new[] { KnownParameters.Serializations.Utf8JsonWriter }, ExplicitInterface: Configuration.ApiTypes.IUtf8JsonSerializableType), + WriteObject(json, writer, null) + ); + } + + if (useModelReaderWriter) + { + // void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + var options = new ModelReaderWriterOptionsExpression(KnownParameters.Serializations.Options); + yield return new + ( + new MethodSignature(nameof(IJsonModel.Write), null, null, MethodSignatureModifiers.None, null, null, new[] { KnownParameters.Serializations.Utf8JsonWriter, KnownParameters.Serializations.Options }, ExplicitInterface: jsonModelInterface), + WriteObject(json, writer, options) + ); + + // T IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + var reader = (ValueExpression)KnownParameters.Serializations.Utf8JsonReader; + yield return new + ( + new MethodSignature(nameof(IJsonModel.Create), null, null, MethodSignatureModifiers.None, typeOfT, null, new[] { KnownParameters.Serializations.Utf8JsonReader, KnownParameters.Serializations.Options }, ExplicitInterface: jsonModelInterface), + new MethodBodyStatement[] + { + Serializations.ValidateJsonFormat(options, json.IPersistableModelTInterface), + // using var document = JsonDocument.ParseValue(ref reader); + UsingDeclare("document", JsonDocumentExpression.ParseValue(reader), out var docVariable), + // return DeserializeXXX(doc.RootElement, options); + Return(SerializableObjectTypeExpression.Deserialize(model, docVariable.RootElement, options)) + } + ); + + // if the model is a struct, it needs to implement IJsonModel as well which leads to another 2 methods + if (json.IJsonModelObjectInterface is { } jsonModelObjectInterface) + { + // void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + yield return new + ( + new MethodSignature(nameof(IJsonModel.Write), null, null, MethodSignatureModifiers.None, null, null, new[] { KnownParameters.Serializations.Utf8JsonWriter, KnownParameters.Serializations.Options }, ExplicitInterface: jsonModelObjectInterface), + This.CastTo(jsonModelInterface).Invoke(nameof(IJsonModel.Write), writer, options) + ); + + // object IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + yield return new + ( + new MethodSignature(nameof(IJsonModel.Create), null, null, MethodSignatureModifiers.None, typeof(object), null, new[] { KnownParameters.Serializations.Utf8JsonReader, KnownParameters.Serializations.Options }, ExplicitInterface: jsonModelObjectInterface), + This.CastTo(jsonModelInterface).Invoke(nameof(IJsonModel.Create), reader, options) + ); + } + } + } + + public static IEnumerable BuildIModelMethods(SerializableObjectType model, JsonObjectSerialization? json, XmlObjectSerialization? xml) + { + // we do not need this if model reader writer feature is not enabled + if (!Configuration.UseModelReaderWriter) + yield break; + + var iModelTInterface = json?.IPersistableModelTInterface ?? xml?.IPersistableModelTInterface; + var iModelObjectInterface = json?.IPersistableModelObjectInterface ?? xml?.IPersistableModelObjectInterface; + // if we have json serialization, we must have this interface. + // if we have xml serialization, we must have this interface. + // therefore this type should never be null - because we cannot get here when json and xml both are null + Debug.Assert(iModelTInterface != null); + + var typeOfT = iModelTInterface.Arguments[0]; + var options = new ModelReaderWriterOptionsExpression(KnownParameters.Serializations.Options); + // BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + yield return new ( - new MethodSignature(Configuration.ApiTypes.IUtf8JsonSerializableWriteName, null, null, MethodSignatureModifiers.None, null, null, new[] { utf8JsonWriter }, ExplicitInterface: Configuration.ApiTypes.IUtf8JsonSerializableType), - WriteObject(new Utf8JsonWriterExpression(utf8JsonWriter), jsonObjectSerialization) + new MethodSignature(nameof(IPersistableModel.Write), null, null, MethodSignatureModifiers.None, typeof(BinaryData), null, new[] { KnownParameters.Serializations.Options }, ExplicitInterface: iModelTInterface), + BuildModelWriteMethodBody(json, xml, options, iModelTInterface).ToArray() ); + + // T IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + var data = new BinaryDataExpression(KnownParameters.Serializations.Data); + yield return new + ( + new MethodSignature(nameof(IPersistableModel.Create), null, null, MethodSignatureModifiers.None, typeOfT, null, new[] { KnownParameters.Serializations.Data, KnownParameters.Serializations.Options }, ExplicitInterface: iModelTInterface), + BuildModelCreateMethodBody(model, json != null, xml != null, data, options, iModelTInterface).ToArray() + ); + + // ModelReaderWriterFormat IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) + yield return new + ( + new MethodSignature(nameof(IPersistableModel.GetFormatFromOptions), null, null, MethodSignatureModifiers.None, typeof(string), null, new[] { KnownParameters.Serializations.Options }, ExplicitInterface: iModelTInterface), + xml != null ? Serializations.XmlFormat : Serializations.JsonFormat + ); + + // if the model is a struct, it needs to implement IPersistableModel as well which leads to another 2 methods + if (iModelObjectInterface is not null) + { + // BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + yield return new + ( + new MethodSignature(nameof(IPersistableModel.Write), null, null, MethodSignatureModifiers.None, typeof(BinaryData), null, new[] { KnownParameters.Serializations.Options }, ExplicitInterface: iModelObjectInterface), + // => (IPersistableModelthis).Write(options); + This.CastTo(iModelTInterface).Invoke(nameof(IPersistableModel.Write), options) + ); + + // object IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + yield return new + ( + new MethodSignature(nameof(IPersistableModel.Create), null, null, MethodSignatureModifiers.None, typeof(object), null, new[] { KnownParameters.Serializations.Data, KnownParameters.Serializations.Options }, ExplicitInterface: iModelObjectInterface), + // => (IPersistableModelthis).Read(options); + This.CastTo(iModelTInterface).Invoke(nameof(IPersistableModel.Create), data, options) + ); + + // ModelReaderWriterFormat IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) + yield return new + ( + new MethodSignature(nameof(IPersistableModel.GetFormatFromOptions), null, null, MethodSignatureModifiers.None, typeof(string), null, new[] { KnownParameters.Serializations.Options }, ExplicitInterface: iModelObjectInterface), + // => (IPersistableModelthis).GetFormatFromOptions(options); + This.CastTo(iModelTInterface).Invoke(nameof(IPersistableModel.GetFormatFromOptions), options) + ); + } + + static IEnumerable BuildModelWriteMethodBody(JsonObjectSerialization? json, XmlObjectSerialization? xml, ModelReaderWriterOptionsExpression options, CSharpType iModelTInterface) + { + // var format = options.Format == "W" ? GetFormatFromOptions(options) : options.Format; + yield return Serializations.GetConcreteFormat(options, iModelTInterface, out var format); + + yield return EmptyLine; + + var switchStatement = new SwitchStatement(format); + + if (json != null) + { + var jsonCase = new SwitchCase(Serializations.JsonFormat, + Return(new InvokeStaticMethodExpression(typeof(ModelReaderWriter), nameof(ModelReaderWriter.Write), new[] { This, options })) + ); + switchStatement.Add(jsonCase); + } + + if (xml != null) + { + /* using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + ((IXmlSerializable)this).Write(writer, null); + writer.Flush(); + // in the implementation of MemoryStream, `stream.Position` could never exceed `int.MaxValue`, therefore this if is redundant, we just need to keep the else branch + //if (stream.Position > int.MaxValue) + //{ + // return BinaryData.FromStream(stream); + //} + //else + //{ + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + //} + */ + var xmlCase = new SwitchCase(Serializations.XmlFormat, + new MethodBodyStatement[] + { + UsingDeclare("stream", typeof(MemoryStream), New.Instance(typeof(MemoryStream)), out var stream), + UsingDeclare("writer", typeof(XmlWriter), new InvokeStaticMethodExpression(typeof(XmlWriter), nameof(XmlWriter.Create), new[] { stream }), out var xmlWriter), + new InvokeInstanceMethodStatement(null, xml.WriteXmlMethodName, new[] { xmlWriter, Null, options }, false), + xmlWriter.Invoke(nameof(XmlWriter.Flush)).ToStatement(), + // return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + Return(New.Instance(typeof(BinaryData), + InvokeStaticMethodExpression.Extension( + typeof(MemoryExtensions), + nameof(MemoryExtensions.AsMemory), + stream.Invoke(nameof(MemoryStream.GetBuffer)), + new[] { Int(0), stream.Property(nameof(Stream.Position)).CastTo(typeof(int)) } + ))) + }, addScope: true); // using statement must have a scope, if we do not have the addScope parameter here, the generated code will not compile + switchStatement.Add(xmlCase); + } + + // default case + /* + * throw new FormatException($"The model {nameof(T)} does not support '{options.Format}' format."); + */ + var typeOfT = iModelTInterface.Arguments[0]; + var defaultCase = SwitchCase.Default( + Serializations.ThrowValidationFailException(options.Format, typeOfT) + ); + switchStatement.Add(defaultCase); + + yield return switchStatement; + } + + static IEnumerable BuildModelCreateMethodBody(SerializableObjectType model, bool hasJson, bool hasXml, BinaryDataExpression data, ModelReaderWriterOptionsExpression options, CSharpType iModelTInterface) + { + // var format = options.Format == "W" ? GetFormatFromOptions(options) : options.Format; + yield return Serializations.GetConcreteFormat(options, iModelTInterface, out var format); + + yield return EmptyLine; + + var switchStatement = new SwitchStatement(format); + + if (hasJson) + { + /* using var document = JsonDocument.ParseValue(ref reader); + * return DeserializeXXX(doc.RootElement, options); + */ + var jsonCase = new SwitchCase(Serializations.JsonFormat, + new MethodBodyStatement[] + { + UsingDeclare("document", JsonDocumentExpression.Parse(data), out var docVariable), + Return(SerializableObjectTypeExpression.Deserialize(model, docVariable.RootElement, options)) + }, addScope: true); // using statement must have a scope, if we do not have the addScope parameter here, the generated code will not compile + switchStatement.Add(jsonCase); + } + + if (hasXml) + { + // return DeserializeXmlCollection(XElement.Load(data.ToStream()), options); + var xmlCase = new SwitchCase(Serializations.XmlFormat, + Return(SerializableObjectTypeExpression.Deserialize(model, XElementExpression.Load(data.ToStream()), options))); + switchStatement.Add(xmlCase); + } + + // default case + /* + * throw new InvalidOperationException($"The model {nameof(T)} does not support '{options.Format}' format."); + */ + var typeOfT = iModelTInterface.Arguments[0]; + var defaultCase = SwitchCase.Default( + Serializations.ThrowValidationFailException(options.Format, typeOfT) + ); + switchStatement.Add(defaultCase); + + yield return switchStatement; + } } - public static MethodBodyStatement[] WriteObject(Utf8JsonWriterExpression utf8JsonWriter, JsonObjectSerialization serialization) + // TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag. + private static MethodBodyStatement[] WriteObject(JsonObjectSerialization serialization, Utf8JsonWriterExpression utf8JsonWriter, ModelReaderWriterOptionsExpression? options) => new[] { + Serializations.ValidateJsonFormat(options, serialization.IPersistableModelTInterface), utf8JsonWriter.WriteStartObject(), - WriteProperties(utf8JsonWriter, serialization.Properties).ToArray(), - SerializeAdditionalProperties(utf8JsonWriter, serialization.AdditionalProperties), + WriteProperties(utf8JsonWriter, serialization.Properties, options).ToArray(), + SerializeAdditionalProperties(utf8JsonWriter, options, serialization.AdditionalProperties), utf8JsonWriter.WriteEndObject() }; - public static IEnumerable WriteProperties(Utf8JsonWriterExpression utf8JsonWriter, IEnumerable properties) + // TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag. + private static IEnumerable WriteProperties(Utf8JsonWriterExpression utf8JsonWriter, IEnumerable properties, ModelReaderWriterOptionsExpression? options) { foreach (JsonPropertySerialization property in properties) { - if (property.ShouldSkipSerialization) - { - continue; - } - if (property.ValueSerialization == null) { // Flattened property - yield return utf8JsonWriter.WritePropertyName(property.SerializedName); - yield return utf8JsonWriter.WriteStartObject(); - yield return WriteProperties(utf8JsonWriter, property.PropertySerializations!).ToArray(); - yield return utf8JsonWriter.WriteEndObject(); + yield return Serializations.WrapInCheckNotWire( + property, + options?.Format, + new[] + { + utf8JsonWriter.WritePropertyName(property.SerializedName), + utf8JsonWriter.WriteStartObject(), + WriteProperties(utf8JsonWriter, property.PropertySerializations!, options).ToArray(), + utf8JsonWriter.WriteEndObject(), + }); } else if (property.SerializedType is { IsNullable: true }) { @@ -76,22 +325,28 @@ public static IEnumerable WriteProperties(Utf8JsonWriterExp ? And(NotEqual(property.Value, Null), InvokeOptional.IsCollectionDefined(property.Value)) : NotEqual(property.Value, Null); - yield return InvokeOptional.WrapInIsDefined( + yield return Serializations.WrapInCheckNotWire( property, - new IfElseStatement(checkPropertyIsInitialized, - WriteProperty(utf8JsonWriter, property), - utf8JsonWriter.WriteNull(property.SerializedName) - ) + options?.Format, + InvokeOptional.WrapInIsDefined( + property, + new IfElseStatement(checkPropertyIsInitialized, + WritePropertySerialization(utf8JsonWriter, property), + utf8JsonWriter.WriteNull(property.SerializedName) + )) ); } else { - yield return InvokeOptional.WrapInIsDefined(property, WriteProperty(utf8JsonWriter, property)); + yield return Serializations.WrapInCheckNotWire( + property, + options?.Format, + InvokeOptional.WrapInIsDefined(property, WritePropertySerialization(utf8JsonWriter, property))); } } } - private static MethodBodyStatement WriteProperty(Utf8JsonWriterExpression utf8JsonWriter, JsonPropertySerialization serialization) + private static MethodBodyStatement WritePropertySerialization(Utf8JsonWriterExpression utf8JsonWriter, JsonPropertySerialization serialization) { return new[] { @@ -102,7 +357,8 @@ serialization.CustomSerializationMethodName is {} serializationMethodName }; } - private static MethodBodyStatement SerializeAdditionalProperties(Utf8JsonWriterExpression utf8JsonWriter, JsonAdditionalPropertiesSerialization? additionalProperties) + // TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag. + private static MethodBodyStatement SerializeAdditionalProperties(Utf8JsonWriterExpression utf8JsonWriter, ModelReaderWriterOptionsExpression? options, JsonAdditionalPropertiesSerialization? additionalProperties) { if (additionalProperties is null) { @@ -110,11 +366,24 @@ private static MethodBodyStatement SerializeAdditionalProperties(Utf8JsonWriterE } var additionalPropertiesExpression = new DictionaryExpression(additionalProperties.Type.Arguments[0], additionalProperties.Type.Arguments[1], additionalProperties.Value); - return new ForeachStatement("item", additionalPropertiesExpression, out KeyValuePairExpression item) + MethodBodyStatement statement = new ForeachStatement("item", additionalPropertiesExpression, out KeyValuePairExpression item) { utf8JsonWriter.WritePropertyName(item.Key), SerializeExpression(utf8JsonWriter, additionalProperties.ValueSerialization, item.Value) }; + + // if it should be excluded in wire serialization, it is a raw data field and we need to check if it is null + // otherwise it is the public AdditionalProperties property, we always instantiate it therefore we do not need to check null. + statement = additionalProperties.ShouldExcludeInWireSerialization ? + new IfStatement(NotEqual(additionalPropertiesExpression, Null)) + { + statement + } : statement; + + return Serializations.WrapInCheckNotWire( + additionalProperties, + options?.Format, + statement); } public static MethodBodyStatement SerializeExpression(Utf8JsonWriterExpression utf8JsonWriter, JsonSerialization? serialization, ValueExpression expression) @@ -192,9 +461,10 @@ private static MethodBodyStatement SerializeValue(Utf8JsonWriterExpression utf8J case EnumType enumType: return utf8JsonWriter.WriteStringValue(new EnumExpression(enumType, value.NullableStructValue(valueSerialization.Type)).ToSerial()); - } - throw new NotSupportedException(); + default: + throw new NotSupportedException($"Cannot build serialization expression for type {valueSerialization.Type}, please add `CodeGenMemberSerializationHooks` to specify the serialization of this type with the customized property"); + } } private static MethodBodyStatement SerializeFrameworkTypeValue(Utf8JsonWriterExpression utf8JsonWriter, JsonValueSerialization valueSerialization, ValueExpression value, Type valueType) @@ -221,7 +491,8 @@ private static MethodBodyStatement SerializeFrameworkTypeValue(Utf8JsonWriterExp return utf8JsonWriter.WriteObjectValue(value); } - if (valueType == typeof(string) || valueType == typeof(char) || valueType == typeof(Guid) || valueType == typeof(ResourceIdentifier) || valueType == typeof(ResourceType) || valueType == typeof(RequestMethod) || valueType == typeof(AzureLocation)) + // These are string-like types that could implicitly convert to string type + if (valueType == typeof(string) || valueType == typeof(char) || valueType == typeof(Guid) || valueType == typeof(ResourceIdentifier) || valueType == typeof(ResourceType) || valueType == typeof(AzureLocation)) { return utf8JsonWriter.WriteStringValue(value); } @@ -259,7 +530,8 @@ private static MethodBodyStatement SerializeFrameworkTypeValue(Utf8JsonWriterExp : utf8JsonWriter.WriteStringValue(value); } - if (valueType == typeof(ETag) || valueType == typeof(ContentType) || valueType == typeof(IPAddress)) + // These are string-like types that cannot implicitly convert to string type, therefore we need to call ToString on them + if (valueType == typeof(ETag) || valueType == typeof(ContentType) || valueType == typeof(IPAddress) || valueType == typeof(RequestMethod) || valueType == typeof(ExtendedLocationType)) { return utf8JsonWriter.WriteStringValue(value.InvokeToString()); } @@ -293,7 +565,7 @@ private static MethodBodyStatement SerializeFrameworkTypeValue(Utf8JsonWriterExp return InvokeJsonSerializerSerializeMethod(utf8JsonWriter, value); } - throw new NotSupportedException($"Framework type {valueType} serialization not supported"); + throw new NotSupportedException($"Framework type {valueType} serialization not supported, please add `CodeGenMemberSerializationHooks` to specify the serialization of this type with the customized property"); } private static MethodBodyStatement CheckCollectionItemForNull(Utf8JsonWriterExpression utf8JsonWriter, JsonSerialization valueSerialization, ValueExpression value) @@ -304,19 +576,30 @@ private static MethodBodyStatement CheckCollectionItemForNull(Utf8JsonWriterExpr public static Method? BuildDeserialize(TypeDeclarationOptions declaration, JsonObjectSerialization serialization, INamedTypeSymbol? existingType) { var methodName = $"Deserialize{declaration.Name}"; - var element = new Parameter("element", null, typeof(JsonElement), null, ValidationType.None, null); - var signature = new MethodSignature(methodName, null, null, MethodSignatureModifiers.Internal | MethodSignatureModifiers.Static, serialization.Type, null, new[] { element }); + var signature = Configuration.UseModelReaderWriter ? + new MethodSignature(methodName, null, null, MethodSignatureModifiers.Internal | MethodSignatureModifiers.Static, serialization.Type, null, new[] { KnownParameters.Serializations.JsonElement, KnownParameters.Serializations.OptionalOptions }) : + new MethodSignature(methodName, null, null, MethodSignatureModifiers.Internal | MethodSignatureModifiers.Static, serialization.Type, null, new[] { KnownParameters.Serializations.JsonElement }); if (SourceInputHelper.TryGetExistingMethod(existingType, signature, out _)) { return null; } - return new Method(signature, BuildDeserializeBody(element, serialization).ToArray()); + return Configuration.UseModelReaderWriter ? + new Method(signature, BuildDeserializeBody(serialization, new JsonElementExpression(KnownParameters.Serializations.JsonElement), new ModelReaderWriterOptionsExpression(KnownParameters.Serializations.OptionalOptions)).ToArray()) : + new Method(signature, BuildDeserializeBody(serialization, new JsonElementExpression(KnownParameters.Serializations.JsonElement), null).ToArray()); } - private static IEnumerable BuildDeserializeBody(Parameter element, JsonObjectSerialization serialization) + // TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag. + private static IEnumerable BuildDeserializeBody(JsonObjectSerialization serialization, JsonElementExpression jsonElement, ModelReaderWriterOptionsExpression? options) { - var jsonElement = new JsonElementExpression(element); + // fallback to Default options if it is null + if (options != null) + { + yield return AssignIfNull(options, ModelReaderWriterOptionsExpression.Wire); + + yield return EmptyLine; + } + if (!serialization.Type.IsValueType) // only return null for reference type (e.g. no enum) { yield return new IfStatement(jsonElement.ValueKindEqualsNull()) @@ -328,7 +611,7 @@ private static IEnumerable BuildDeserializeBody(Parameter e var discriminator = serialization.Discriminator; if (discriminator is not null && discriminator.HasDescendants) { - yield return new IfStatement(jsonElement.TryGetProperty(element.Name, discriminator.SerializedName, out var discriminatorElement)) + yield return new IfStatement(jsonElement.TryGetProperty(discriminator.SerializedName, out var discriminatorElement)) { new SwitchStatement(discriminatorElement.GetString(), GetDiscriminatorCases(jsonElement, discriminator).ToArray()) }; @@ -341,7 +624,7 @@ private static IEnumerable BuildDeserializeBody(Parameter e } else { - yield return WriteObjectInitialization(jsonElement, serialization).ToArray(); + yield return WriteObjectInitialization(serialization, jsonElement, options).ToArray(); } } @@ -353,7 +636,8 @@ private static IEnumerable GetDiscriminatorCases(JsonElementExpressi } } - private static IEnumerable WriteObjectInitialization(JsonElementExpression element, JsonObjectSerialization serialization) + // TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag. + private static IEnumerable WriteObjectInitialization(JsonObjectSerialization serialization, JsonElementExpression element, ModelReaderWriterOptionsExpression? options) { // this is the first level of object hierarchy // collect all properties and initialize the dictionary @@ -381,7 +665,7 @@ serialization.Discriminator.Value is not null && } else { - yield return Declare(variable.Value, Snippets.Default); + yield return Declare(variable.Value, Default); } } @@ -393,9 +677,9 @@ serialization.Discriminator.Value is not null && yield return Declare(dictionary, New.Instance(objAdditionalProperties.Type)); yield return new ForeachStatement("property", element.EnumerateObject(), out var property) { - DeserializeIntoObjectProperties(serialization.Properties, objAdditionalProperties.ValueSerialization, new JsonPropertyExpression(property), new DictionaryExpression(objAdditionalProperties.Type.Arguments[0], objAdditionalProperties.Type.Arguments[1], dictionary), propertyVariables, shouldTreatEmptyStringAsNull) + DeserializeIntoObjectProperties(serialization.Properties, objAdditionalProperties, new JsonPropertyExpression(property), new DictionaryExpression(objAdditionalProperties.Type.Arguments[0], objAdditionalProperties.Type.Arguments[1], dictionary), options, propertyVariables, shouldTreatEmptyStringAsNull).ToArray() }; - yield return new AssignValueStatement(propertyVariables[objAdditionalProperties], dictionary); + yield return Assign(propertyVariables[objAdditionalProperties], dictionary); } else { @@ -413,24 +697,22 @@ serialization.Discriminator.Value is not null && yield return Return(New.Instance(serialization.Type, parameters)); } - private static MethodBodyStatement DeserializeIntoObjectProperties(IEnumerable propertySerializations, JsonSerialization? additionalPropertiesSerialization, JsonPropertyExpression jsonProperty, DictionaryExpression dictionary, IReadOnlyDictionary propertyVariables, bool shouldTreatEmptyStringAsNull) + // TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag. + private static IEnumerable DeserializeIntoObjectProperties(IEnumerable propertySerializations, JsonAdditionalPropertiesSerialization additionalPropertiesSerialization, JsonPropertyExpression jsonProperty, DictionaryExpression dictionary, ModelReaderWriterOptionsExpression? options, IReadOnlyDictionary propertyVariables, bool shouldTreatEmptyStringAsNull) { - if (additionalPropertiesSerialization is null) - { - return DeserializeIntoObjectProperties(propertySerializations, jsonProperty, propertyVariables, shouldTreatEmptyStringAsNull); - } - - return new[] - { - DeserializeIntoObjectProperties(propertySerializations, jsonProperty, propertyVariables, shouldTreatEmptyStringAsNull), - DeserializeValue(additionalPropertiesSerialization, jsonProperty.Value, out var value), - dictionary.Add(jsonProperty.Name, value) - }; + yield return DeserializeIntoObjectProperties(propertySerializations, jsonProperty, propertyVariables, shouldTreatEmptyStringAsNull); + // in the case here, this line returns an empty statement, we only want the value here + yield return DeserializeValue(additionalPropertiesSerialization.ValueSerialization!, jsonProperty.Value, out var value); + var additionalPropertiesStatement = dictionary.Add(jsonProperty.Name, value); + + yield return Serializations.WrapInCheckNotWire( + additionalPropertiesSerialization, + options?.Format, + additionalPropertiesStatement); } private static MethodBodyStatement DeserializeIntoObjectProperties(IEnumerable propertySerializations, JsonPropertyExpression jsonProperty, IReadOnlyDictionary propertyVariables, bool shouldTreatEmptyStringAsNull) => propertySerializations - .Where(p => !p.ShouldSkipDeserialization) .Select(p => new IfStatement(jsonProperty.NameEquals(p.SerializedName)) { DeserializeIntoObjectProperty(p, jsonProperty, propertyVariables, shouldTreatEmptyStringAsNull) @@ -545,7 +827,7 @@ private static MethodBodyStatement CreatePropertyNullCheckStatement(JsonProperty return EmptyStatement; } - private static ValueExpression GetCheckEmptyPropertyValueExpression(JsonPropertyExpression jsonProperty, JsonPropertySerialization jsonPropertySerialization, bool shouldTreatEmptyStringAsNull) + private static BoolExpression GetCheckEmptyPropertyValueExpression(JsonPropertyExpression jsonProperty, JsonPropertySerialization jsonPropertySerialization, bool shouldTreatEmptyStringAsNull) { var jsonElement = jsonProperty.Value; if (!shouldTreatEmptyStringAsNull) @@ -570,7 +852,7 @@ private static ValueExpression GetCheckEmptyPropertyValueExpression(JsonProperty /// Collects a list of properties being read from all level of object hierarchy private static void CollectPropertiesForDeserialization(IDictionary propertyVariables, IEnumerable jsonProperties) { - foreach (JsonPropertySerialization jsonProperty in jsonProperties.Where(p => !p.ShouldSkipDeserialization)) + foreach (JsonPropertySerialization jsonProperty in jsonProperties) { if (jsonProperty.SerializedType is { } type) { @@ -757,13 +1039,13 @@ public static ValueExpression GetDeserializeImplementation(TypeProvider implemen case SystemObjectType systemObjectType when IsCustomJsonConverterAdded(systemObjectType.SystemType): return InvokeJsonSerializerDeserializeMethod(element, implementation.Type, serializerOptions); - case Resource { ResourceData: SerializableObjectType { IncludeDeserializer: true } resourceDataType } resource: + case Resource { ResourceData: SerializableObjectType resourceDataType } resource: return New.Instance(resource.Type, new MemberExpression(null, "Client"), SerializableObjectTypeExpression.Deserialize(resourceDataType, element)); case MgmtObjectType mgmtObjectType when TypeReferenceTypeChooser.HasMatch(mgmtObjectType.ObjectSchema): return InvokeJsonSerializerDeserializeMethod(element, implementation.Type); - case SerializableObjectType { IncludeDeserializer: true } type: + case SerializableObjectType type: return SerializableObjectTypeExpression.Deserialize(type, element); case EnumType clientEnum: @@ -815,7 +1097,8 @@ public static ValueExpression GetFrameworkTypeValueExpression(Type frameworkType frameworkType == typeof(ResourceType) || frameworkType == typeof(ContentType) || frameworkType == typeof(RequestMethod) || - frameworkType == typeof(AzureLocation)) + frameworkType == typeof(AzureLocation) || + frameworkType == typeof(ExtendedLocationType)) { return New.Instance(frameworkType, element.GetString()); } @@ -889,14 +1172,14 @@ public static ValueExpression GetFrameworkTypeValueExpression(Type frameworkType return element.GetTimeSpan(format.ToFormatSpecifier()); } - throw new NotSupportedException($"Framework type {frameworkType} is not supported"); + throw new NotSupportedException($"Framework type {frameworkType} is not supported, please add `CodeGenMemberSerializationHooks` to specify the serialization of this type with the customized property"); } private static MethodBodyStatement InvokeListAdd(ValueExpression list, ValueExpression value) => new InvokeInstanceMethodStatement(list, nameof(List.Add), value); private static MethodBodyStatement InvokeArrayElementAssignment(ValueExpression array, ValueExpression index, ValueExpression value) - => new AssignValueStatement(new ArrayElementExpression(array, index), value); + => Assign(new ArrayElementExpression(array, index), value); private static ValueExpression InvokeJsonSerializerDeserializeMethod(JsonElementExpression element, CSharpType serializationType, ValueExpression? options = null) { diff --git a/src/AutoRest.CSharp/Common/Output/Builders/SerializationBuilder.cs b/src/AutoRest.CSharp/Common/Output/Builders/SerializationBuilder.cs index 36675c2c30e..4e08627b435 100644 --- a/src/AutoRest.CSharp/Common/Output/Builders/SerializationBuilder.cs +++ b/src/AutoRest.CSharp/Common/Output/Builders/SerializationBuilder.cs @@ -8,6 +8,7 @@ using System.Text.Json; using AutoRest.CSharp.Common.Input; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; +using AutoRest.CSharp.Common.Output.Models.Types; using AutoRest.CSharp.Generation.Types; using AutoRest.CSharp.Generation.Writers; using AutoRest.CSharp.Input; @@ -122,7 +123,7 @@ private static XmlElementSerialization BuildXmlElementSerialization(Schema schem case DictionarySchema dictionarySchema: return new XmlDictionarySerialization( TypeFactory.GetImplementationType(type), - BuildXmlElementSerialization(dictionarySchema.ElementType,TypeFactory.GetElementType(type), null, false), + BuildXmlElementSerialization(dictionarySchema.ElementType, TypeFactory.GetElementType(type), null, false), xmlName); default: return new XmlElementValueSerialization(xmlName, BuildXmlValueSerialization(schema, type)); @@ -192,7 +193,7 @@ public static JsonSerialization BuildSerialization(Schema schema, CSharpType typ } } - public XmlObjectSerialization BuildXmlObjectSerialization(ObjectSchema objectSchema, ObjectType objectType) + public XmlObjectSerialization BuildXmlObjectSerialization(ObjectSchema objectSchema, SerializableObjectType objectType) { List elements = new List(); List attributes = new List(); @@ -252,7 +253,7 @@ public XmlObjectSerialization BuildXmlObjectSerialization(ObjectSchema objectSch return new XmlObjectSerialization( objectSchema.Serialization?.Xml?.Name ?? objectSchema.Language.Default.Name, - objectType.Type, elements.ToArray(), attributes.ToArray(), embeddedArrays.ToArray(), + objectType, elements.ToArray(), attributes.ToArray(), embeddedArrays.ToArray(), contentSerialization ); } @@ -270,7 +271,7 @@ private IEnumerable GetPropertySerializationsFromBag( var serializedName = schemaProperty.SerializedName; var isRequired = schemaProperty.IsRequired; - var isReadOnly = schemaProperty.IsReadOnly; + var shouldExcludeInWireSerialization = schemaProperty.IsReadOnly; var serialization = BuildSerialization(schemaProperty.Schema, property.Declaration.Type, false); var memberValueExpression = new TypedMemberExpression(null, property.Declaration.Name, property.Declaration.Type); @@ -288,8 +289,7 @@ private IEnumerable GetPropertySerializationsFromBag( property.ValueType, serialization, isRequired, - isReadOnly, - false, + shouldExcludeInWireSerialization, customSerializationMethodName: property.SerializationMapping?.SerializationValueHook, customDeserializationMethodName: property.SerializationMapping?.DeserializationValueHook, enumerableExpression: enumerableExpression); @@ -319,7 +319,7 @@ public JsonObjectSerialization BuildJsonObjectSerialization(ObjectSchema objectS PopulatePropertyBag(propertyBag, 0); var properties = GetPropertySerializationsFromBag(propertyBag, objectType).ToArray(); var additionalProperties = CreateAdditionalProperties(objectSchema, objectType); - return new JsonObjectSerialization(objectType.Type, objectType.SerializationConstructor.Signature.Parameters, properties, additionalProperties, objectType.Discriminator, objectType.IncludeConverter); + return new JsonObjectSerialization(objectType, objectType.SerializationConstructor.Signature.Parameters, properties, additionalProperties, objectType.Discriminator, objectType.IncludeConverter); } private class SerializationPropertyBag @@ -359,30 +359,41 @@ private static void PopulatePropertyBag(SerializationPropertyBag propertyBag, in private JsonAdditionalPropertiesSerialization? CreateAdditionalProperties(ObjectSchema objectSchema, ObjectType objectType) { var inheritedDictionarySchema = objectSchema.Parents!.All.OfType().FirstOrDefault(); - + bool shouldExcludeInWireSerialization = false; ObjectTypeProperty? additionalPropertiesProperty = null; foreach (var obj in objectType.EnumerateHierarchy()) { - additionalPropertiesProperty = obj.AdditionalPropertiesProperty; + additionalPropertiesProperty = obj.AdditionalPropertiesProperty ?? (obj as SerializableObjectType)?.RawDataField; if (additionalPropertiesProperty != null) { + // if this is a real "AdditionalProperties", we should NOT exclude it in wire + shouldExcludeInWireSerialization = additionalPropertiesProperty != obj.AdditionalPropertiesProperty; break; } } - if (inheritedDictionarySchema == null || additionalPropertiesProperty == null) + if (additionalPropertiesProperty == null) { return null; } var dictionaryValueType = additionalPropertiesProperty.Declaration.Type.Arguments[1]; Debug.Assert(!dictionaryValueType.IsNullable, $"{typeof(JsonCodeWriterExtensions)} implicitly relies on {additionalPropertiesProperty.Declaration.Name} dictionary value being non-nullable"); - var valueSerialization = BuildSerialization(inheritedDictionarySchema.ElementType, dictionaryValueType, false); + JsonSerialization valueSerialization; + if (inheritedDictionarySchema is not null) + { + valueSerialization = BuildSerialization(inheritedDictionarySchema.ElementType, dictionaryValueType, false); + } + else + { + valueSerialization = new JsonValueSerialization(dictionaryValueType, SerializationFormat.Default, true); + } return new JsonAdditionalPropertiesSerialization( additionalPropertiesProperty, valueSerialization, - new CSharpType(typeof(Dictionary<,>), additionalPropertiesProperty.Declaration.Type.Arguments)); + new CSharpType(typeof(Dictionary<,>), additionalPropertiesProperty.Declaration.Type.Arguments), + shouldExcludeInWireSerialization); } } } diff --git a/src/AutoRest.CSharp/Common/Output/Builders/XmlSerializationMethodsBuilder.cs b/src/AutoRest.CSharp/Common/Output/Builders/XmlSerializationMethodsBuilder.cs index d3d696e3d4f..1f0f367125f 100644 --- a/src/AutoRest.CSharp/Common/Output/Builders/XmlSerializationMethodsBuilder.cs +++ b/src/AutoRest.CSharp/Common/Output/Builders/XmlSerializationMethodsBuilder.cs @@ -4,14 +4,15 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Xml; using System.Xml.Linq; +using AutoRest.CSharp.Common.Input; using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions; using AutoRest.CSharp.Common.Output.Expressions.Statements; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using AutoRest.CSharp.Common.Output.Models; using AutoRest.CSharp.Common.Output.Models.Types; using AutoRest.CSharp.Generation.Types; +using AutoRest.CSharp.Input.Source; using AutoRest.CSharp.Output.Models; using AutoRest.CSharp.Output.Models.Serialization; using AutoRest.CSharp.Output.Models.Serialization.Xml; @@ -21,50 +22,81 @@ using Azure.Core; using Azure.ResourceManager.Models; using static AutoRest.CSharp.Common.Output.Models.Snippets; -using ValidationType = AutoRest.CSharp.Output.Models.Shared.ValidationType; namespace AutoRest.CSharp.Common.Output.Builders { internal static class XmlSerializationMethodsBuilder { - public static Method BuildXmlSerializableWrite(XmlObjectSerialization serialization) + public static IEnumerable BuildXmlSerializationMethods(XmlObjectSerialization serialization) { - var xmlWriter = new Parameter("writer", null, typeof(XmlWriter), null, ValidationType.None, null); - var nameHint = new Parameter("nameHint", null, typeof(string), null, ValidationType.None, null); - return new Method - ( - new MethodSignature(nameof(IXmlSerializable.Write), null, null, MethodSignatureModifiers.None, null, null, new[]{xmlWriter, nameHint}, ExplicitInterface: typeof(IXmlSerializable)), - SerializeExpression(new XmlWriterExpression(xmlWriter), serialization, nameHint).AsStatement() - ); + // a private helper method with the options to do the full xml serialization + var xmlWriter = new XmlWriterExpression(KnownParameters.Serializations.XmlWriter); + var nameHint = (ValueExpression)KnownParameters.Serializations.NameHint; + var options = new ModelReaderWriterOptionsExpression(KnownParameters.Serializations.Options); + if (Configuration.UseModelReaderWriter) + { + yield return new Method + ( + new MethodSignature(serialization.WriteXmlMethodName, null, null, MethodSignatureModifiers.Private, null, null, new[] { KnownParameters.Serializations.XmlWriter, KnownParameters.Serializations.NameHint, KnownParameters.Serializations.Options }), + WriteObject(serialization, xmlWriter, nameHint, options).ToArray() + ); + + yield return new Method + ( + new MethodSignature(nameof(IXmlSerializable.Write), null, null, MethodSignatureModifiers.None, null, null, new[] { KnownParameters.Serializations.XmlWriter, KnownParameters.Serializations.NameHint }, ExplicitInterface: typeof(IXmlSerializable)), + This.Invoke(serialization.WriteXmlMethodName, new[] { xmlWriter, nameHint, ModelReaderWriterOptionsExpression.Wire }) + ); + } + else + { + yield return new Method + ( + new MethodSignature(nameof(IXmlSerializable.Write), null, null, MethodSignatureModifiers.None, null, null, new[] { KnownParameters.Serializations.XmlWriter, KnownParameters.Serializations.NameHint }, ExplicitInterface: typeof(IXmlSerializable)), + WriteObject(serialization, xmlWriter, nameHint, null).ToArray() + ); + } } - public static IEnumerable SerializeExpression(XmlWriterExpression xmlWriter, XmlObjectSerialization objectSerialization, ValueExpression nameHint) + // TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag. + private static IEnumerable WriteObject(XmlObjectSerialization objectSerialization, XmlWriterExpression xmlWriter, ValueExpression nameHint, ModelReaderWriterOptionsExpression? options) { yield return xmlWriter.WriteStartElement(NullCoalescing(nameHint, Literal(objectSerialization.Name))); foreach (XmlObjectAttributeSerialization serialization in objectSerialization.Attributes) { - yield return InvokeOptional.WrapInIsDefined(serialization, WrapInNullCheck(serialization, new[] - { - xmlWriter.WriteStartAttribute(serialization.SerializedName), - SerializeValueExpression(xmlWriter, serialization.ValueSerialization, serialization.Value), - xmlWriter.WriteEndAttribute() - })); + yield return Serializations.WrapInCheckNotWire( + serialization, + options?.Format, + InvokeOptional.WrapInIsDefined(serialization, WrapInNullCheck(serialization, new[] + { + xmlWriter.WriteStartAttribute(serialization.SerializedName), + SerializeValueExpression(xmlWriter, serialization.ValueSerialization, serialization.Value), + xmlWriter.WriteEndAttribute() + }))); } foreach (XmlObjectElementSerialization serialization in objectSerialization.Elements) { - yield return InvokeOptional.WrapInIsDefined(serialization, WrapInNullCheck(serialization, SerializeExpression(xmlWriter, serialization.ValueSerialization, serialization.Value))); + yield return Serializations.WrapInCheckNotWire( + serialization, + options?.Format, + InvokeOptional.WrapInIsDefined(serialization, WrapInNullCheck(serialization, SerializeExpression(xmlWriter, serialization.ValueSerialization, serialization.Value)))); } foreach (XmlObjectArraySerialization serialization in objectSerialization.EmbeddedArrays) { - yield return InvokeOptional.WrapInIsDefined(serialization, WrapInNullCheck(serialization, SerializeExpression(xmlWriter, serialization.ArraySerialization, serialization.Value))); + yield return Serializations.WrapInCheckNotWire( + serialization, + options?.Format, + InvokeOptional.WrapInIsDefined(serialization, WrapInNullCheck(serialization, SerializeExpression(xmlWriter, serialization.ArraySerialization, serialization.Value)))); } if (objectSerialization.ContentSerialization is { } contentSerialization) { - yield return SerializeValueExpression(xmlWriter, contentSerialization.ValueSerialization, contentSerialization.Value); + yield return Serializations.WrapInCheckNotWire( + contentSerialization, + options?.Format, + SerializeValueExpression(xmlWriter, contentSerialization.ValueSerialization, contentSerialization.Value)); } yield return xmlWriter.WriteEndElement(); @@ -72,7 +104,7 @@ public static IEnumerable SerializeExpression(XmlWriterExpr private static MethodBodyStatement WrapInNullCheck(PropertySerialization serialization, MethodBodyStatement statement) { - if (serialization.SerializedType is {IsNullable: true} serializedType) + if (serialization.SerializedType is { IsNullable: true } serializedType) { if (TypeFactory.IsCollectionType(serializedType) && serialization.IsRequired) { @@ -170,16 +202,24 @@ private static MethodBodyStatement SerializeValueExpression(XmlWriterExpression public static Method BuildDeserialize(TypeDeclarationOptions declaration, XmlObjectSerialization serialization) { var methodName = $"Deserialize{declaration.Name}"; - var element = new Parameter("element", null, typeof(XElement), null, ValidationType.None, null); - return new Method - ( - new MethodSignature(methodName, null, null, MethodSignatureModifiers.Internal | MethodSignatureModifiers.Static, serialization.Type, null, new[]{element}), - BuildDeserializeBody(new XElementExpression(element), serialization).ToArray() - ); + var signature = Configuration.UseModelReaderWriter ? + new MethodSignature(methodName, null, null, MethodSignatureModifiers.Internal | MethodSignatureModifiers.Static, serialization.Type, null, new[] { KnownParameters.Serializations.XElement, KnownParameters.Serializations.OptionalOptions }) : + new MethodSignature(methodName, null, null, MethodSignatureModifiers.Internal | MethodSignatureModifiers.Static, serialization.Type, null, new[] { KnownParameters.Serializations.XElement }); + + return Configuration.UseModelReaderWriter ? + new Method(signature, BuildDeserializeBody(serialization, new XElementExpression(KnownParameters.Serializations.XElement), new ModelReaderWriterOptionsExpression(KnownParameters.Serializations.OptionalOptions)).ToArray()) : + new Method(signature, BuildDeserializeBody(serialization, new XElementExpression(KnownParameters.Serializations.XElement), null).ToArray()); } - private static IEnumerable BuildDeserializeBody(XElementExpression element, XmlObjectSerialization objectSerialization) + // TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag. + private static IEnumerable BuildDeserializeBody(XmlObjectSerialization objectSerialization, XElementExpression element, ModelReaderWriterOptionsExpression? options) { + if (options != null) + { + yield return AssignIfNull(options, ModelReaderWriterOptionsExpression.Wire); + yield return EmptyLine; + } + var propertyVariables = new Dictionary(); CollectProperties(propertyVariables, objectSerialization); @@ -215,11 +255,20 @@ private static IEnumerable BuildDeserializeBody(XElementExp var objectType = (ObjectType)objectSerialization.Type.Implementation; var parameterValues = propertyVariables.ToDictionary(v => v.Key.SerializationConstructorParameterName, v => (ValueExpression)v.Value); - var parameters = objectType.SerializationConstructor.Signature.Parameters - .Select(p => parameterValues[p.Name]) - .ToArray(); - yield return Return(New.Instance(objectSerialization.Type, parameters)); + var arguments = new List(); + foreach (var parameter in objectType.SerializationConstructor.Signature.Parameters) + { + if (parameterValues.TryGetValue(parameter.Name, out var argument)) + arguments.Add(argument); + else + { + // this must be the raw data property + arguments.Add(new PositionalParameterReference(parameter.Name, Null)); + } + } + + yield return Return(New.Instance(objectSerialization.Type, arguments)); } public static MethodBodyStatement BuildDeserializationForMethods(XmlElementSerialization serialization, ValueExpression? variable, StreamExpression stream) @@ -317,7 +366,7 @@ private static ValueExpression DeserializeValue(XmlValueSerialization serializat frameworkType == typeof(string) ) { - return new CastExpression(value, type); + return value.CastTo(type); } if (frameworkType == typeof(ResourceIdentifier)) @@ -333,19 +382,19 @@ private static ValueExpression DeserializeValue(XmlValueSerialization serializat if (frameworkType == typeof(ResourceType)) { - return new CastExpression(value, typeof(string)); + return value.CastTo(typeof(string)); } if (frameworkType == typeof(Guid)) { return value is XElementExpression xElement ? New.Instance(typeof(Guid), xElement.Value) - : new CastExpression(value, typeof(Guid)); + : value.CastTo(typeof(Guid)); } if (frameworkType == typeof(Uri)) { - return New.Instance(typeof(Uri), new CastExpression(value, typeof(string))); + return New.Instance(typeof(Uri), value.CastTo(typeof(string))); } if (value is XElementExpression element) @@ -405,7 +454,7 @@ private static void CollectProperties(Dictionary(Untyped) { + public static ResourceIdentifierExpression Root => new(new MemberExpression(typeof(ResourceIdentifier), nameof(ResourceIdentifier.Root))); + public StringExpression Name => new(Property(nameof(ResourceIdentifier.Name))); public ResourceIdentifierExpression Parent => new(Property(nameof(ResourceIdentifier.Parent))); public StringExpression Provider => new(Property(nameof(ResourceIdentifier.Provider))); diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/BinaryDataExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/BinaryDataExpression.cs index f684b529a88..00b192b5e27 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/BinaryDataExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/BinaryDataExpression.cs @@ -19,6 +19,14 @@ public static BinaryDataExpression FromStream(StreamExpression stream, bool asyn return new BinaryDataExpression(InvokeStatic(methodName, stream, async)); } + public static BinaryDataExpression FromStream(ValueExpression stream, bool async) + { + var methodName = async ? nameof(BinaryData.FromStreamAsync) : nameof(BinaryData.FromStream); + return new(InvokeStatic(methodName, stream, async)); + } + + public ValueExpression ToMemory() => Invoke(nameof(BinaryData.ToMemory)); + public StreamExpression ToStream() => new(Invoke(nameof(BinaryData.ToStream))); public ListExpression ToArray() => new(typeof(byte[]), Invoke(nameof(BinaryData.ToArray))); diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/IntExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/IntExpression.cs new file mode 100644 index 00000000000..5f003248583 --- /dev/null +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/IntExpression.cs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; +using AutoRest.CSharp.Common.Output.Models; +using AutoRest.CSharp.Output.Models.Types; + +namespace AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions +{ + internal sealed record IntExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) + { + public static IntExpression MaxValue => new(StaticProperty(nameof(int.MaxValue))); + } +} diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/JsonDocumentExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/JsonDocumentExpression.cs index ca9237b2310..f8b91b1cb22 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/JsonDocumentExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/JsonDocumentExpression.cs @@ -12,6 +12,8 @@ internal sealed record JsonDocumentExpression(ValueExpression Untyped) : TypedVa { public JsonElementExpression RootElement => new(Property(nameof(JsonDocument.RootElement))); + public static JsonDocumentExpression ParseValue(ValueExpression reader) => new(InvokeStatic(nameof(JsonDocument.ParseValue), reader)); + public static JsonDocumentExpression Parse(ValueExpression json) => new(InvokeStatic(nameof(JsonDocument.Parse), json)); public static JsonDocumentExpression Parse(BinaryDataExpression binaryData) => new(InvokeStatic(nameof(JsonDocument.Parse), binaryData)); public static JsonDocumentExpression Parse(StreamExpression stream) => new(InvokeStatic(nameof(JsonDocument.Parse), stream)); diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/JsonElementExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/JsonElementExpression.cs index bd4f90e52bc..43940e8a3b6 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/JsonElementExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/JsonElementExpression.cs @@ -42,11 +42,12 @@ public BoolExpression ValueKindEqualsString() public MethodBodyStatement WriteTo(ValueExpression writer) => new InvokeInstanceMethodStatement(Untyped, nameof(JsonElement.WriteTo), new[] { writer }, false); - public BoolExpression TryGetProperty(string elementName, string propertyName, out JsonElementExpression discriminator) + public BoolExpression TryGetProperty(string propertyName, out JsonElementExpression discriminator) { var discriminatorDeclaration = new VariableReference(typeof(JsonElement), "discriminator"); discriminator = new JsonElementExpression(discriminatorDeclaration); - return new BoolExpression(new FormattableStringToExpression($"{elementName}.{nameof(JsonElement.TryGetProperty)}({propertyName:L}, out {typeof(JsonElement)} {discriminatorDeclaration.Declaration:D})")); + var invocation = new InvokeInstanceMethodExpression(this, nameof(JsonElement.TryGetProperty), new ValueExpression[] { Literal(propertyName), new DeclarationExpression(discriminatorDeclaration, true) }, null, false); + return new BoolExpression(invocation); } } } diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/ModelReaderWriterOptionsExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/ModelReaderWriterOptionsExpression.cs new file mode 100644 index 00000000000..f134b21f3e0 --- /dev/null +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/ModelReaderWriterOptionsExpression.cs @@ -0,0 +1,16 @@ +// Copyright(c) Microsoft Corporation.All rights reserved. +// Licensed under the MIT License. + +using System.ClientModel.Primitives; +using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; +using static AutoRest.CSharp.Common.Output.Models.Snippets; + +namespace AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions +{ + internal record ModelReaderWriterOptionsExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) + { + public static readonly ModelReaderWriterOptionsExpression Wire = new(New.Instance(typeof(ModelReaderWriterOptions), Literal("W"))); + + public ValueExpression Format => new MemberExpression(this, nameof(ModelReaderWriterOptions.Format)); + } +} diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/SerializableObjectTypeExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/SerializableObjectTypeExpression.cs index 9ebbc4664bc..5f74039e9f7 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/SerializableObjectTypeExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/SerializableObjectTypeExpression.cs @@ -20,8 +20,11 @@ public static MemberExpression DeserializeDelegate(SerializableObjectType serial public static SerializableObjectTypeExpression FromResponse(SerializableObjectType serializableObjectType, ResponseExpression response) => new(serializableObjectType, new InvokeStaticMethodExpression(serializableObjectType.Type, Configuration.ApiTypes.FromResponseName, new[] { response })); - public static SerializableObjectTypeExpression Deserialize(SerializableObjectType serializableObjectType, ValueExpression element) - => new(serializableObjectType, new InvokeStaticMethodExpression(serializableObjectType.Type, $"Deserialize{serializableObjectType.Declaration.Name}", new[] { element })); + public static SerializableObjectTypeExpression Deserialize(SerializableObjectType model, ValueExpression element, ValueExpression? options = null) + { + var arguments = options == null ? new[] { element } : new[] { element, options }; + return new(model, new InvokeStaticMethodExpression(model.Type, $"Deserialize{model.Declaration.Name}", arguments)); + } public RequestContentExpression ToRequestContent() => new(Untyped.Invoke("ToRequestContent")); diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/StreamExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/StreamExpression.cs index 91956c5a5f2..45a54947614 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/StreamExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/StreamExpression.cs @@ -10,5 +10,7 @@ namespace AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions internal sealed record StreamExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) { public MethodBodyStatement CopyTo(StreamExpression destination) => new InvokeInstanceMethodStatement(Untyped, nameof(Stream.CopyTo), destination); + + public ValueExpression Position => new TypedMemberExpression(this, nameof(Stream.Position), typeof(long)); } } diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/MessagePipelineExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/MessagePipelineExpression.cs index 43167970fa2..805fba02cf4 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/MessagePipelineExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/MessagePipelineExpression.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System.ClientModel.Internal; +using System.ClientModel.Primitives.Pipeline; using System.Collections.Generic; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using AutoRest.CSharp.Common.Output.Models; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineMessageExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineMessageExpression.cs index f91d446bc21..70ed398577c 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineMessageExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineMessageExpression.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; namespace AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions.System diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineRequestExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineRequestExpression.cs index 7233a72128d..642e30518dd 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineRequestExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineRequestExpression.cs @@ -2,7 +2,7 @@ // Licensed under the MIT License. using System; -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using AutoRest.CSharp.Common.Output.Expressions.Statements; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using static AutoRest.CSharp.Common.Output.Models.Snippets; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineResponseExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineResponseExpression.cs index 4a914f1087f..b37078b8dab 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineResponseExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/PipelineResponseExpression.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; namespace AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions.System diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestBodyExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestBodyExpression.cs index 3433dfa65b1..58935bbf2a1 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestBodyExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestBodyExpression.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; namespace AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions.System diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestOptionsExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestOptionsExpression.cs index f4b95872b9d..86b48ef5222 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestOptionsExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestOptionsExpression.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Net.ClientModel; +using System.ClientModel; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using AutoRest.CSharp.Output.Models.Shared; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestUriExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestUriExpression.cs index f2acd9482fe..4f77ea8e8c4 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestUriExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/RequestUriExpression.cs @@ -2,7 +2,7 @@ // Licensed under the MIT License. using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; using AutoRest.CSharp.Common.Output.Expressions.Statements; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using AutoRest.CSharp.Output.Models.Serialization; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/ResultExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/ResultExpression.cs index f8624f7f3a0..c2cfc6e4ae8 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/ResultExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/ResultExpression.cs @@ -2,7 +2,7 @@ // Licensed under the MIT License. using System; -using System.Net.ClientModel; +using System.ClientModel; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using AutoRest.CSharp.Generation.Types; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/Utf8JsonRequestBodyExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/Utf8JsonRequestBodyExpression.cs index 32f257ee975..a2e84ec73f2 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/Utf8JsonRequestBodyExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/System/Utf8JsonRequestBodyExpression.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; namespace AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions.System diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/XAttributeExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/XAttributeExpression.cs new file mode 100644 index 00000000000..7c2a4538787 --- /dev/null +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/XAttributeExpression.cs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Xml.Linq; +using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; + +namespace AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions +{ + internal sealed record XAttributeExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) + { + public XNameExpression Name => new(Property(nameof(XAttribute.Name))); + public StringExpression Value => new(Property(nameof(XAttribute.Value))); + } +} diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/XElementExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/XElementExpression.cs index 7349a559d76..606be33183a 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/XElementExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/KnownValueExpressions/XElementExpression.cs @@ -19,11 +19,7 @@ public XAttributeExpression Attribute(string name) public ValueExpression GetDateTimeOffsetValue(string? format) => Extensible.XElement.GetDateTimeOffsetValue(this, format); public ValueExpression GetObjectValue(string? format) => Extensible.XElement.GetObjectValue(this, format); public ValueExpression GetTimeSpanValue(string? format) => Extensible.XElement.GetTimeSpanValue(this, format); - } - internal sealed record XAttributeExpression(ValueExpression Untyped) : TypedValueExpression(Untyped) - { - public XNameExpression Name => new(Property(nameof(XAttribute.Name))); - public StringExpression Value => new(Property(nameof(XAttribute.Value))); + public static XElementExpression Load(StreamExpression stream) => new(new InvokeStaticMethodExpression(typeof(XElement), nameof(XElement.Load), new[] { stream })); } } diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.DeclarationStatements.cs b/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.DeclarationStatements.cs index 7bf9a13181e..9b1af4a83cb 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.DeclarationStatements.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.DeclarationStatements.cs @@ -14,6 +14,16 @@ namespace AutoRest.CSharp.Common.Output.Models { internal static partial class Snippets { + public static DeclarationStatement UsingDeclare(string name, CSharpType type, ValueExpression value, out VariableReference variable) + { + var declaration = new CodeWriterDeclaration(name); + variable = new VariableReference(type, declaration); + return new UsingDeclareVariableStatement(type, declaration, value); + } + + public static DeclarationStatement UsingDeclare(string name, JsonDocumentExpression value, out JsonDocumentExpression variable) + => UsingDeclare(name, value, d => new JsonDocumentExpression(d), out variable); + public static DeclarationStatement UsingDeclare(string name, StreamExpression value, out StreamExpression variable) => UsingDeclare(name, value, d => new StreamExpression(d), out variable); diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.New.cs b/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.New.cs index bbf3c9e4fc7..9842cc9a680 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.New.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.New.cs @@ -49,6 +49,7 @@ public static DictionaryExpression Dictionary(CSharpType keyType, CSharpType val public static ValueExpression Anonymous(IReadOnlyDictionary? properties) => new KeywordExpression("new", new ObjectInitializerExpression(properties, IsInline: false)); public static ValueExpression Instance(ConstructorSignature ctorSignature, IReadOnlyList arguments, IReadOnlyDictionary? properties = null) => new NewInstanceExpression(ctorSignature.Type, arguments, properties != null ? new ObjectInitializerExpression(properties) : null); public static ValueExpression Instance(ConstructorSignature ctorSignature, IReadOnlyDictionary? properties = null) => Instance(ctorSignature, ctorSignature.Parameters.Select(p => (ValueExpression)p).ToArray(), properties); + public static ValueExpression Instance(CSharpType type, IReadOnlyList arguments) => new NewInstanceExpression(type, arguments); public static ValueExpression Instance(CSharpType type, params ValueExpression[] arguments) => new NewInstanceExpression(type, arguments); public static ValueExpression Instance(CSharpType type, IReadOnlyDictionary properties) => new NewInstanceExpression(type, System.Array.Empty(), new ObjectInitializerExpression(properties)); public static TypedValueExpression Instance(Type type, params ValueExpression[] arguments) => new FrameworkTypeExpression(type, new NewInstanceExpression(type, arguments)); diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.Pageable.cs b/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.Pageable.cs index a36fae8bb39..8e70d588b7d 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.Pageable.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.Pageable.cs @@ -118,7 +118,7 @@ private static ValueExpression GetValueFactory(CSharpType? pageItemType) return new FuncExpression(new[] { e.Declaration }, BinaryDataExpression.FromString(new JsonElementExpression(e).GetRawText())); } - if (pageItemType is { IsFrameworkType: false, Implementation: SerializableObjectType { JsonSerialization: { }, IncludeDeserializer: true } type }) + if (pageItemType is { IsFrameworkType: false, Implementation: SerializableObjectType { JsonSerialization: { } } type }) { return SerializableObjectTypeExpression.DeserializeDelegate(type); } diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.Serialization.cs b/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.Serialization.cs new file mode 100644 index 00000000000..b853c8248de --- /dev/null +++ b/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.Serialization.cs @@ -0,0 +1,124 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Linq; +using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions; +using AutoRest.CSharp.Common.Output.Expressions.Statements; +using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; +using AutoRest.CSharp.Generation.Types; +using AutoRest.CSharp.Output.Models.Serialization; + +namespace AutoRest.CSharp.Common.Output.Models +{ + internal static partial class Snippets + { + public static class Serializations + { + public static StringExpression WireFormat = Literal("W"); + public static StringExpression JsonFormat = Literal("J"); + public static StringExpression XmlFormat = Literal("X"); + + // TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag. + public static MethodBodyStatement WrapInCheckNotWire(PropertySerialization serialization, ValueExpression? format, MethodBodyStatement statement) + { + // if format is null, indicating the model reader writer is not enabled + if (format == null) + { + // when the model reader writer is not enabled, we just omit the serialization when it should not be included. + if (serialization.ShouldExcludeInWireSerialization) + { + return EmptyStatement; + } + else + { + return statement; + } + } + + if (!serialization.ShouldExcludeInWireSerialization) + return statement; + + // we need to wrap a check `format != "W"` around the statement + // if the statement is not an IfStatement, we just create an IfStatement and return + // if the statement is an IfStatement, we could add the condition to its condition which should simplify the generated code. + /* it looks like, if we have + * if (outer) + * { + * if (inner) { DoSomething(); } + * } + * we could always simplify this to: + * if (outer && inner) + * { + * DoSomething(); + * } + * these are exactly the same. + * 1. When outer is false, inner is never calculated, and DoSomething will not be execute + * 2. When outer is true, inner is calculated, and DoSomething will be execute when inner is true + * These hold true for both snippets + * + * These statements are only true when it is a IfStatement. If the statement is IfElseStatement with an else branch, they are no longer equivalent. + */ + + var isNotWireCondition = NotEqual(format, WireFormat); + if (statement is IfStatement ifStatement) + { + return ifStatement with + { + Condition = And(isNotWireCondition, ifStatement.Condition) + }; + } + + return new IfStatement(isNotWireCondition) + { + statement + }; + } + + public static MethodBodyStatement ValidateJsonFormat(ModelReaderWriterOptionsExpression? options, CSharpType iModelTInterface) + => ValidateFormat(options, JsonFormat, iModelTInterface).ToArray(); + + public static MethodBodyStatement ValidateXmlFormat(ModelReaderWriterOptionsExpression? options, CSharpType iModelTInterface) + => ValidateFormat(options, XmlFormat, iModelTInterface).ToArray(); + + // TODO -- make the options parameter non-nullable again when we remove the `UseModelReaderWriter` flag. + private static IEnumerable ValidateFormat(ModelReaderWriterOptionsExpression? options, ValueExpression formatValue, CSharpType iModelTInterface) + { + if (options == null) + yield break; // if options expression is null, we skip outputting the following statements + /* + var format = options.Format == "W" ? GetFormatFromOptions(options) : options.Format; + if (format != ) + { + throw new FormatException($"The model {nameof(ThisModel)} does not support '{format}' format."); + } + */ + yield return GetConcreteFormat(options, iModelTInterface, out var format); + + yield return new IfStatement(NotEqual(format, formatValue)) + { + ThrowValidationFailException(format, iModelTInterface.Arguments[0]) + }; + + yield return EmptyLine; // always outputs an empty line here because we will always have other statements after this + } + + public static MethodBodyStatement GetConcreteFormat(ModelReaderWriterOptionsExpression options, CSharpType iModelTInterface, out TypedValueExpression format) + => Var("format", new TypedTernaryConditionalOperator( + Equal(options.Format, WireFormat), + new StringExpression(This.CastTo(iModelTInterface).Invoke(nameof(IPersistableModel.GetFormatFromOptions), options)), + options.Format), out format); + + public static MethodBodyStatement ThrowValidationFailException(ValueExpression format, CSharpType typeOfT) + => Throw(New.Instance( + typeof(FormatException), + new FormattableStringExpression("The model {0} does not support '{1}' format.", new[] + { + Nameof(typeOfT), + format + }))); + } + } +} diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.cs b/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.cs index 4e7c657fefc..c661466071a 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/Snippets.cs @@ -59,6 +59,7 @@ public static TypedValueExpression RemoveAllNullConditional(TypedValueExpression public static StringExpression Literal(string? value) => new(value is null ? Null : new StringLiteralExpression(value, false)); public static StringExpression LiteralU8(string value) => new(new StringLiteralExpression(value, true)); + public static BoolExpression GreaterThan(ValueExpression left, ValueExpression right) => new(new BinaryOperatorExpression(">", left, right)); public static BoolExpression Equal(ValueExpression left, ValueExpression right) => new(new BinaryOperatorExpression("==", left, right)); public static BoolExpression NotEqual(ValueExpression left, ValueExpression right) => new(new BinaryOperatorExpression("!=", left, right)); public static BoolExpression Is(ValueExpression value, CSharpType type) => new(new BinaryOperatorExpression("is", value, type)); @@ -97,7 +98,7 @@ public static MethodBodyStatement InvokeCustomDeserializationMethod(string metho public static AssignValueStatement Assign(T variable, T expression) where T : ValueExpression => new(variable, expression); public static MethodBodyStatement AssignOrReturn(T? variable, T expression) where T : ValueExpression - => variable != null ? new AssignValueStatement(variable, expression) : Return(expression); + => variable != null ? Assign(variable, expression) : Return(expression); public static MethodBodyStatement InvokeConsoleWriteLine(ValueExpression expression) => new InvokeStaticMethodStatement(typeof(Console), nameof(Console.WriteLine), expression); diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/Statements/IfElseStatement.cs b/src/AutoRest.CSharp/Common/Output/Expressions/Statements/IfElseStatement.cs index 06cf3c3ab17..19e1ada32a6 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/Statements/IfElseStatement.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/Statements/IfElseStatement.cs @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; +using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions; namespace AutoRest.CSharp.Common.Output.Expressions.Statements { internal record IfElseStatement(IfStatement If, MethodBodyStatement? Else) : MethodBodyStatement { - public IfElseStatement(ValueExpression condition, MethodBodyStatement ifStatement, MethodBodyStatement? elseStatement, bool inline = false, bool addBraces = true) + public IfElseStatement(BoolExpression condition, MethodBodyStatement ifStatement, MethodBodyStatement? elseStatement, bool inline = false, bool addBraces = true) : this(new IfStatement(condition, inline, addBraces) { ifStatement }, elseStatement) {} } } diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/Statements/IfStatement.cs b/src/AutoRest.CSharp/Common/Output/Expressions/Statements/IfStatement.cs index c69ae4a95bb..01b45c34d98 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/Statements/IfStatement.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/Statements/IfStatement.cs @@ -3,11 +3,11 @@ using System.Collections; using System.Collections.Generic; -using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; +using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions; namespace AutoRest.CSharp.Common.Output.Expressions.Statements { - internal record IfStatement(ValueExpression Condition, bool Inline = false, bool AddBraces = true) : MethodBodyStatement, IEnumerable + internal record IfStatement(BoolExpression Condition, bool Inline = false, bool AddBraces = true) : MethodBodyStatement, IEnumerable { private readonly List _body = new(); public MethodBodyStatement Body => _body; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemArgumentSnippets.cs b/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemArgumentSnippets.cs index e177f149904..fbe4b7f7ceb 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemArgumentSnippets.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemArgumentSnippets.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; using AutoRest.CSharp.Common.Output.Expressions.Statements; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using static AutoRest.CSharp.Common.Output.Models.Snippets; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemJsonElementSnippets.cs b/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemJsonElementSnippets.cs index 886d8892cf5..1ae9e3200cf 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemJsonElementSnippets.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemJsonElementSnippets.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions; using AutoRest.CSharp.Common.Output.Expressions.Statements; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemModelSnippets.cs b/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemModelSnippets.cs index f5a7bcc2101..b42620582f8 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemModelSnippets.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemModelSnippets.cs @@ -2,8 +2,8 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using AutoRest.CSharp.Common.Input; using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions; using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions.System; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemRestOperationsSnippets.cs b/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemRestOperationsSnippets.cs index b58111b5522..7c101c0c634 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemRestOperationsSnippets.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/System/SystemExtensibleSnippets.SystemRestOperationsSnippets.cs @@ -2,10 +2,10 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Linq; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; using AutoRest.CSharp.Common.Input; using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions; using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions.Azure; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/DeclarationExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/DeclarationExpression.cs new file mode 100644 index 00000000000..98c76a45114 --- /dev/null +++ b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/DeclarationExpression.cs @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace AutoRest.CSharp.Common.Output.Expressions.ValueExpressions +{ + internal record DeclarationExpression(VariableReference Variable, bool IsOut) : ValueExpression; +} diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/FormattableStringExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/FormattableStringExpression.cs index d50985f57ef..a937da3e1f8 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/FormattableStringExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/FormattableStringExpression.cs @@ -23,10 +23,15 @@ public FormattableStringExpression(string format, IReadOnlyList Format = format; Args = args; } + + public FormattableStringExpression(string format, params ValueExpression[] args) : this(format, args as IReadOnlyList) + { + } + public string Format { get; init; } public IReadOnlyList Args { get; init; } - public void Deconstruct(out string format, out IReadOnlyList args) + public void Deconstruct(out string format, out IReadOnlyList args) { format = Format; args = Args; diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/InvokeInstanceMethodExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/InvokeInstanceMethodExpression.cs index b5e7d88ab89..593f4cac561 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/InvokeInstanceMethodExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/InvokeInstanceMethodExpression.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; +using AutoRest.CSharp.Common.Output.Expressions.Statements; using AutoRest.CSharp.Generation.Types; using AutoRest.CSharp.Output.Models; @@ -14,5 +15,8 @@ internal record InvokeInstanceMethodExpression(ValueExpression? InstanceReferenc public InvokeInstanceMethodExpression(ValueExpression? instanceReference, MethodSignature signature, IReadOnlyList arguments, bool addConfigureAwaitFalse = true) : this(instanceReference, signature.Name, arguments, signature.GenericArguments, signature.Modifiers.HasFlag(MethodSignatureModifiers.Async), addConfigureAwaitFalse) { } public InvokeInstanceMethodExpression(ValueExpression? instanceReference, MethodSignature signature, bool addConfigureAwaitFalse = true) : this(instanceReference, signature, signature.Parameters.Select(p => (ValueExpression)p).ToArray(), addConfigureAwaitFalse) { } + + public MethodBodyStatement ToStatement() + => new InvokeInstanceMethodStatement(InstanceReference, MethodName, Arguments, CallAsAsync); } } diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/InvokeStaticMethodExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/InvokeStaticMethodExpression.cs index fb60b687ed4..1c0ff394b18 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/InvokeStaticMethodExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/InvokeStaticMethodExpression.cs @@ -2,9 +2,20 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System.Collections.Generic; +using System.Linq; +using AutoRest.CSharp.Common.Output.Expressions.Statements; using AutoRest.CSharp.Generation.Types; namespace AutoRest.CSharp.Common.Output.Expressions.ValueExpressions { - internal record InvokeStaticMethodExpression(CSharpType? MethodType, string MethodName, IReadOnlyList Arguments, IReadOnlyList? TypeArguments = null, bool CallAsExtension = false, bool CallAsAsync = false) : ValueExpression; + internal record InvokeStaticMethodExpression(CSharpType? MethodType, string MethodName, IReadOnlyList Arguments, IReadOnlyList? TypeArguments = null, bool CallAsExtension = false, bool CallAsAsync = false) : ValueExpression + { + public static InvokeStaticMethodExpression Extension(CSharpType? methodType, string methodName, ValueExpression instanceReference) => new(methodType, methodName, new[] { instanceReference }, CallAsExtension: true); + public static InvokeStaticMethodExpression Extension(CSharpType? methodType, string methodName, ValueExpression instanceReference, ValueExpression arg) => new(methodType, methodName, new[] { instanceReference, arg }, CallAsExtension: true); + public static InvokeStaticMethodExpression Extension(CSharpType? methodType, string methodName, ValueExpression instanceReference, IReadOnlyList arguments) + => new(methodType, methodName, arguments.Prepend(instanceReference).ToArray(), CallAsExtension: true); + + public MethodBodyStatement ToStatement() + => new InvokeStaticMethodStatement(MethodType, MethodName, Arguments, TypeArguments, CallAsExtension, CallAsAsync); + } } diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/PositionalParameterReference.cs b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/PositionalParameterReference.cs index d53318af798..f4a2c8c14cb 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/PositionalParameterReference.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/PositionalParameterReference.cs @@ -1,7 +1,12 @@ // Copyright(c) Microsoft Corporation.All rights reserved. // Licensed under the MIT License. +using AutoRest.CSharp.Output.Models.Shared; + namespace AutoRest.CSharp.Common.Output.Expressions.ValueExpressions { - internal record PositionalParameterReference(string ParameterName, ValueExpression ParameterValue) : ValueExpression; + internal record PositionalParameterReference(string ParameterName, ValueExpression ParameterValue) : ValueExpression + { + public PositionalParameterReference(Parameter parameter) : this(parameter.Name, parameter) { } + } } diff --git a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/ValueExpression.cs b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/ValueExpression.cs index 78f76ecb115..9dfab51de8b 100644 --- a/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/ValueExpression.cs +++ b/src/AutoRest.CSharp/Common/Output/Expressions/ValueExpressions/ValueExpression.cs @@ -29,28 +29,28 @@ internal record ValueExpression public virtual ValueExpression Property(string propertyName) => new MemberExpression(this, propertyName); - public ValueExpression Invoke(string methodName) + public InvokeInstanceMethodExpression Invoke(string methodName) => new InvokeInstanceMethodExpression(this, methodName, Array.Empty(), null, false); - public ValueExpression Invoke(string methodName, ValueExpression arg) + public InvokeInstanceMethodExpression Invoke(string methodName, ValueExpression arg) => new InvokeInstanceMethodExpression(this, methodName, new[] { arg }, null, false); - public ValueExpression Invoke(string methodName, ValueExpression arg1, ValueExpression arg2) + public InvokeInstanceMethodExpression Invoke(string methodName, ValueExpression arg1, ValueExpression arg2) => new InvokeInstanceMethodExpression(this, methodName, new[] { arg1, arg2 }, null, false); - public ValueExpression Invoke(string methodName, IReadOnlyList arguments) + public InvokeInstanceMethodExpression Invoke(string methodName, IReadOnlyList arguments) => new InvokeInstanceMethodExpression(this, methodName, arguments, null, false); - public ValueExpression Invoke(MethodSignature method) + public InvokeInstanceMethodExpression Invoke(MethodSignature method) => new InvokeInstanceMethodExpression(this, method.Name, method.Parameters.Select(p => (ValueExpression)p).ToList(), null, method.Modifiers.HasFlag(MethodSignatureModifiers.Async)); - public ValueExpression Invoke(MethodSignature method, IReadOnlyList arguments, bool addConfigureAwaitFalse = true) + public InvokeInstanceMethodExpression Invoke(MethodSignature method, IReadOnlyList arguments, bool addConfigureAwaitFalse = true) => new InvokeInstanceMethodExpression(this, method.Name, arguments, null, method.Modifiers.HasFlag(MethodSignatureModifiers.Async), AddConfigureAwaitFalse: addConfigureAwaitFalse); - public ValueExpression Invoke(string methodName, bool async) + public InvokeInstanceMethodExpression Invoke(string methodName, bool async) => new InvokeInstanceMethodExpression(this, methodName, Array.Empty(), null, async); - public ValueExpression Invoke(string methodName, IReadOnlyList arguments, bool async) + public InvokeInstanceMethodExpression Invoke(string methodName, IReadOnlyList arguments, bool async) => new InvokeInstanceMethodExpression(this, methodName, arguments, null, async); public CastExpression CastTo(CSharpType to) => new CastExpression(this, to); diff --git a/src/AutoRest.CSharp/Common/Output/Models/ConstructorInitializer.cs b/src/AutoRest.CSharp/Common/Output/Models/ConstructorInitializer.cs index d3d85c5cb1a..4fe5abdbc16 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/ConstructorInitializer.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/ConstructorInitializer.cs @@ -5,18 +5,16 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; +using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using AutoRest.CSharp.Output.Models.Requests; using AutoRest.CSharp.Output.Models.Shared; -using Azure.Core; namespace AutoRest.CSharp.Output.Models { - internal record ConstructorInitializer(bool IsBase, FormattableString[] Arguments) + internal record ConstructorInitializer(bool IsBase, IReadOnlyList Arguments) { - public ConstructorInitializer(bool isBase, IEnumerable arguments) : this(isBase, ParametersToFormattableString(arguments).ToArray()) { } + public ConstructorInitializer(bool isBase, IEnumerable arguments) : this(isBase, arguments.Select(p => (ValueExpression)p).ToArray()) { } - public ConstructorInitializer(bool isBase, IEnumerable arguments) : this(isBase, arguments.Select(r => FormattableStringFactory.Create("{0:I}", r.Name)).ToArray()) { } - - public static IEnumerable ParametersToFormattableString(IEnumerable parameters) => parameters.Select(p => FormattableStringFactory.Create("{0:I}", p.Name)); + public ConstructorInitializer(bool isBase, IEnumerable arguments) : this(isBase, arguments.Select(r => new FormattableStringToExpression(FormattableStringFactory.Create("{0:I}", r.Name))).ToArray()) { } } } diff --git a/src/AutoRest.CSharp/Common/Output/Models/LongRunningOperation.cs b/src/AutoRest.CSharp/Common/Output/Models/LongRunningOperation.cs index 11fc1d646b4..53f06975553 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/LongRunningOperation.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/LongRunningOperation.cs @@ -1,17 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -using System; using System.Diagnostics; -using System.Linq; using AutoRest.CSharp.Common.Input; using AutoRest.CSharp.Common.Output.Models; using AutoRest.CSharp.Generation.Types; -using AutoRest.CSharp.Input; using AutoRest.CSharp.Output.Builders; using AutoRest.CSharp.Output.Models.Serialization; using AutoRest.CSharp.Output.Models.Types; -using AutoRest.CSharp.Utilities; using Azure; using Azure.Core; diff --git a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonAdditionalPropertiesSerialization.cs b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonAdditionalPropertiesSerialization.cs index 373812a3a6c..47dec1e4a7d 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonAdditionalPropertiesSerialization.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonAdditionalPropertiesSerialization.cs @@ -12,8 +12,8 @@ internal class JsonAdditionalPropertiesSerialization : JsonPropertySerialization { public CSharpType Type { get; } - public JsonAdditionalPropertiesSerialization(ObjectTypeProperty property, JsonSerialization valueSerialization, CSharpType type) - : base(property.Declaration.Name.ToVariableName(), new TypedMemberExpression(null, property.Declaration.Name, property.Declaration.Type), property.Declaration.Name, property.ValueType, valueSerialization, true, property.IsReadOnly, false) + public JsonAdditionalPropertiesSerialization(ObjectTypeProperty property, JsonSerialization valueSerialization, CSharpType type, bool shouldExcludeInWireSerialization) + : base(property.Declaration.Name.ToVariableName(), new TypedMemberExpression(null, property.Declaration.Name, property.Declaration.Type), property.Declaration.Name, property.ValueType, valueSerialization, true, shouldExcludeInWireSerialization) { Type = type; } diff --git a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonObjectSerialization.cs b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonObjectSerialization.cs index 8e7a9d0c5e0..8a30c544188 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonObjectSerialization.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonObjectSerialization.cs @@ -1,7 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +using System.ClientModel.Primitives; using System.Collections.Generic; +using AutoRest.CSharp.Common.Input; +using AutoRest.CSharp.Common.Output.Models.Types; using AutoRest.CSharp.Generation.Types; using AutoRest.CSharp.Output.Models.Shared; using AutoRest.CSharp.Output.Models.Types; @@ -10,14 +13,22 @@ namespace AutoRest.CSharp.Output.Models.Serialization.Json { internal class JsonObjectSerialization { - public JsonObjectSerialization(CSharpType type, IReadOnlyList constructorParameters, IReadOnlyList properties, JsonAdditionalPropertiesSerialization? additionalProperties, ObjectTypeDiscriminator? discriminator, bool includeConverter) + public JsonObjectSerialization(SerializableObjectType model, IReadOnlyList constructorParameters, IReadOnlyList properties, JsonAdditionalPropertiesSerialization? additionalProperties, ObjectTypeDiscriminator? discriminator, bool includeConverter) { - Type = type; + Type = model.Type; ConstructorParameters = constructorParameters; Properties = properties; AdditionalProperties = additionalProperties; Discriminator = discriminator; IncludeConverter = includeConverter; + // select interface model type here + var modelType = model.IsUnknownDerivedType && model.Inherits is { IsFrameworkType: false, Implementation: { } baseModel } ? baseModel.Type : model.Type; + IJsonModelInterface = new CSharpType(typeof(IJsonModel<>), modelType); + IPersistableModelTInterface = new CSharpType(typeof(IPersistableModel<>), modelType); + // we only need this interface when the model is a struct + IJsonModelObjectInterface = model.IsStruct ? (CSharpType)typeof(IJsonModel) : null; + IPersistableModelObjectInterface = model.IsStruct ? (CSharpType)typeof(IPersistableModel) : null; + IJsonInterface = Configuration.ApiTypes.IUtf8JsonSerializableType; } public CSharpType Type { get; } @@ -26,5 +37,26 @@ public JsonObjectSerialization(CSharpType type, IReadOnlyList constru public JsonAdditionalPropertiesSerialization? AdditionalProperties { get; } public ObjectTypeDiscriminator? Discriminator { get; } public bool IncludeConverter { get; } + + /// + /// The interface IJsonModel{T} + /// + public CSharpType IJsonModelInterface { get; } + /// + /// The interface IPersistableModel{T} + /// + public CSharpType IPersistableModelTInterface { get; } + /// + /// The interface IJsonModel{object}. We only have this interface when this model is a struct + /// + public CSharpType? IJsonModelObjectInterface { get; } + /// + /// The interface IPersistableModel{object}. We only have this interface when this model is a struct + /// + public CSharpType? IPersistableModelObjectInterface { get; } + /// + /// The interface IUtf8JsonSerializable + /// + public CSharpType IJsonInterface { get; } } } diff --git a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonPropertySerialization.cs b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonPropertySerialization.cs index 2ce1c54cdc8..cc7aed6e6c7 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonPropertySerialization.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonPropertySerialization.cs @@ -15,12 +15,11 @@ public JsonPropertySerialization( CSharpType? serializedType, JsonSerialization valueSerialization, bool isRequired, - bool shouldSkipSerialization, - bool shouldSkipDeserialization, + bool shouldExcludeInWireSerialization, string? customSerializationMethodName = null, string? customDeserializationMethodName = null, TypedValueExpression? enumerableExpression = null) - : base(parameterName, value, serializedName, serializedType, isRequired, shouldSkipSerialization, shouldSkipDeserialization, enumerableExpression) + : base(parameterName, value, serializedName, serializedType, isRequired, shouldExcludeInWireSerialization, enumerableExpression) { ValueSerialization = valueSerialization; CustomSerializationMethodName = customSerializationMethodName; diff --git a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonSerialization.cs b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonSerialization.cs index c59dd0ecdb8..c42a98779fc 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonSerialization.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonSerialization.cs @@ -3,7 +3,7 @@ namespace AutoRest.CSharp.Output.Models.Serialization.Json { - internal abstract class JsonSerialization: ObjectSerialization + internal abstract class JsonSerialization : ObjectSerialization { protected JsonSerialization(bool isNullable, JsonSerializationOptions options = JsonSerializationOptions.None) { diff --git a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonValueSerialization.cs b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonValueSerialization.cs index fbcf13de6fd..c3b6e25a608 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonValueSerialization.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Json/JsonValueSerialization.cs @@ -6,7 +6,7 @@ namespace AutoRest.CSharp.Output.Models.Serialization.Json { - internal class JsonValueSerialization: JsonSerialization + internal class JsonValueSerialization : JsonSerialization { public JsonValueSerialization(CSharpType type, SerializationFormat format, bool isNullable, JsonSerializationOptions options = JsonSerializationOptions.None) : base(isNullable, options) { diff --git a/src/AutoRest.CSharp/Common/Output/Models/Serialization/PropertySerialization.cs b/src/AutoRest.CSharp/Common/Output/Models/Serialization/PropertySerialization.cs index 18b3735e8e2..8c39e73dc37 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Serialization/PropertySerialization.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Serialization/PropertySerialization.cs @@ -33,23 +33,16 @@ internal abstract class PropertySerialization public CSharpType? SerializedType { get; } public bool IsRequired { get; } - public bool ShouldSkipSerialization { get; } - public bool ShouldSkipDeserialization { get; } + public bool ShouldExcludeInWireSerialization { get; } - protected PropertySerialization(string parameterName, TypedValueExpression value, string serializedName, CSharpType? serializedType, bool isRequired, bool shouldSkipSerialization) : - this(parameterName, value, serializedName, serializedType, isRequired, shouldSkipSerialization, false) - { - } - - protected PropertySerialization(string parameterName, TypedValueExpression value, string serializedName, CSharpType? serializedType, bool isRequired, bool shouldSkipSerialization, bool shouldSkipDeserialization, TypedValueExpression? enumerableValue = null) + protected PropertySerialization(string parameterName, TypedValueExpression value, string serializedName, CSharpType? serializedType, bool isRequired, bool shouldExcludeInWireSerialization, TypedValueExpression? enumerableValue = null) { SerializationConstructorParameterName = parameterName; Value = value; SerializedName = serializedName; SerializedType = serializedType; IsRequired = isRequired; - ShouldSkipSerialization = shouldSkipSerialization; - ShouldSkipDeserialization = shouldSkipDeserialization; + ShouldExcludeInWireSerialization = shouldExcludeInWireSerialization; EnumerableValue = enumerableValue; } } diff --git a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Xml/XmlObjectContentSerialization.cs b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Xml/XmlObjectContentSerialization.cs index ce996cbfe5a..4739faca516 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Xml/XmlObjectContentSerialization.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Xml/XmlObjectContentSerialization.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. using AutoRest.CSharp.Output.Models.Types; -using AutoRest.CSharp.Utilities; namespace AutoRest.CSharp.Output.Models.Serialization.Xml { diff --git a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Xml/XmlObjectSerialization.cs b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Xml/XmlObjectSerialization.cs index 655f15c24b8..bd81b644ef8 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Serialization/Xml/XmlObjectSerialization.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Serialization/Xml/XmlObjectSerialization.cs @@ -2,6 +2,9 @@ // Licensed under the MIT License. +using System.ClientModel.Primitives; +using AutoRest.CSharp.Common.Input; +using AutoRest.CSharp.Common.Output.Models.Types; using AutoRest.CSharp.Generation.Types; namespace AutoRest.CSharp.Output.Models.Serialization.Xml @@ -9,18 +12,27 @@ namespace AutoRest.CSharp.Output.Models.Serialization.Xml internal class XmlObjectSerialization { public XmlObjectSerialization(string name, - CSharpType type, + SerializableObjectType model, XmlObjectElementSerialization[] elements, XmlObjectAttributeSerialization[] attributes, XmlObjectArraySerialization[] embeddedArrays, - XmlObjectContentSerialization? contentSerialization) + XmlObjectContentSerialization? contentSerialization, + string? writeXmlMethodName = null) { - Type = type; + Type = model.Type; Elements = elements; Attributes = attributes; Name = name; EmbeddedArrays = embeddedArrays; ContentSerialization = contentSerialization; + WriteXmlMethodName = writeXmlMethodName ?? "WriteInternal"; + + // select interface model type here + var modelType = model.IsUnknownDerivedType && model.Inherits is { IsFrameworkType: false, Implementation: { } baseModel } ? baseModel.Type : model.Type; + IPersistableModelTInterface = new CSharpType(typeof(IPersistableModel<>), modelType); + // we only need this interface when the model is a struct + IPersistableModelObjectInterface = model.IsStruct ? (CSharpType)typeof(IPersistableModel) : null; + IXmlInterface = Configuration.ApiTypes.IXmlSerializableType; } public string Name { get; } @@ -29,5 +41,20 @@ public XmlObjectSerialization(string name, public XmlObjectArraySerialization[] EmbeddedArrays { get; } public XmlObjectContentSerialization? ContentSerialization { get; } public CSharpType Type { get; } + + public string WriteXmlMethodName { get; } + + /// + /// The interface IXmlSerializable + /// + public CSharpType IXmlInterface { get; } + /// + /// The interface IPersistableModel{T} + /// + public CSharpType IPersistableModelTInterface { get; } + /// + /// The interface IPersistableModel{object} + /// + public CSharpType? IPersistableModelObjectInterface { get; } } } diff --git a/src/AutoRest.CSharp/Common/Output/Models/Shared/KnownParameters.Serialization.cs b/src/AutoRest.CSharp/Common/Output/Models/Shared/KnownParameters.Serialization.cs new file mode 100644 index 00000000000..281b358f85a --- /dev/null +++ b/src/AutoRest.CSharp/Common/Output/Models/Shared/KnownParameters.Serialization.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; +using System.Xml; +using System.Xml.Linq; +using AutoRest.CSharp.Generation.Types; + +namespace AutoRest.CSharp.Output.Models.Shared +{ + internal static partial class KnownParameters + { + public static class Serializations + { + private static readonly CSharpType modelReaderWriterOptionsType = typeof(ModelReaderWriterOptions); + private static readonly CSharpType nullableModelReaderWriterOptionsType = new CSharpType(typeof(ModelReaderWriterOptions), isNullable: true); + + public static readonly Parameter XmlWriter = new Parameter("writer", null, typeof(XmlWriter), null, ValidationType.None, null); + public static readonly Parameter NameHint = new Parameter("nameHint", null, typeof(string), null, ValidationType.None, null); + public static readonly Parameter XElement = new Parameter("element", null, typeof(XElement), null, ValidationType.None, null); + + public static readonly Parameter Utf8JsonWriter = new Parameter("writer", null, typeof(Utf8JsonWriter), null, ValidationType.None, null); + public static readonly Parameter Utf8JsonReader = new Parameter("reader", null, typeof(Utf8JsonReader), null, ValidationType.None, null, IsRef: true); + public static readonly Parameter Options = new Parameter("options", null, modelReaderWriterOptionsType, null, ValidationType.None, null); + public static readonly Parameter OptionalOptions = new Parameter("options", null, nullableModelReaderWriterOptionsType, Constant.Default(nullableModelReaderWriterOptionsType), ValidationType.None, null); + public static readonly Parameter JsonElement = new Parameter("element", null, typeof(JsonElement), null, ValidationType.None, null); + public static readonly Parameter Data = new Parameter("data", null, typeof(BinaryData), null, ValidationType.None, null); + } + } +} diff --git a/src/AutoRest.CSharp/Common/Output/Models/Shared/KnownParameters.cs b/src/AutoRest.CSharp/Common/Output/Models/Shared/KnownParameters.cs index a0835550df0..5b4a12e3b05 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Shared/KnownParameters.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Shared/KnownParameters.cs @@ -12,7 +12,7 @@ namespace AutoRest.CSharp.Output.Models.Shared { - internal static class KnownParameters + internal static partial class KnownParameters { private static readonly CSharpType MatchConditionsType = new(typeof(MatchConditions), true); private static readonly CSharpType RequestConditionsType = new(typeof(RequestConditions), true); diff --git a/src/AutoRest.CSharp/Common/Output/Models/Shared/Parameter.cs b/src/AutoRest.CSharp/Common/Output/Models/Shared/Parameter.cs index 853cb6baec3..94d4c222c77 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Shared/Parameter.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Shared/Parameter.cs @@ -16,8 +16,10 @@ namespace AutoRest.CSharp.Output.Models.Shared { - internal record Parameter(string Name, FormattableString? Description, CSharpType Type, Constant? DefaultValue, ValidationType Validation, FormattableString? Initializer, bool IsApiVersionParameter = false, bool IsEndpoint = false, bool IsResourceIdentifier = false, bool SkipUrlEncoding = false, RequestLocation RequestLocation = RequestLocation.None, SerializationFormat SerializationFormat = SerializationFormat.Default, bool IsPropertyBag = false) + internal record Parameter(string Name, FormattableString? Description, CSharpType Type, Constant? DefaultValue, ValidationType Validation, FormattableString? Initializer, bool IsApiVersionParameter = false, bool IsEndpoint = false, bool IsResourceIdentifier = false, bool SkipUrlEncoding = false, RequestLocation RequestLocation = RequestLocation.None, SerializationFormat SerializationFormat = SerializationFormat.Default, bool IsPropertyBag = false, bool IsRef = false) { + public bool IsRawData { get; init; } + public CSharpAttribute[] Attributes { get; init; } = Array.Empty(); public bool IsOptionalInSignature => DefaultValue != null; diff --git a/src/AutoRest.CSharp/Common/Output/Models/Types/ModelFactoryTypeProvider.cs b/src/AutoRest.CSharp/Common/Output/Models/Types/ModelFactoryTypeProvider.cs index 6ab4cf8a6ec..32ca6bf8a18 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Types/ModelFactoryTypeProvider.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Types/ModelFactoryTypeProvider.cs @@ -118,9 +118,19 @@ private ValueExpression BuildPropertyAssignmentExpression(Parameter parameter, O switch (parentPropertyType) { case { IsFrameworkType: false, Implementation: SerializableObjectType serializableObjectType }: + // when a property is flattened, it should only have one property. But the serialization ctor might takes two parameters because it may have the raw data field as an extra parameter + var parameters = serializableObjectType.SerializationConstructor.Signature.Parameters; + var arguments = new List(); // get the type of the first parameter of its ctor - var to = serializableObjectType.SerializationConstructor.Signature.Parameters.First().Type; - result = New.Instance(parentPropertyType, result.GetConversion(from, to)); + var to = parameters[0].Type; + arguments.Add(result.GetConversion(from, to)); + // check if we need extra parameters for the raw data field + if (parameters.Count > 1) + { + // this parameter should be the raw data field, otherwise this property should not have been flattened in the first place + arguments.Add(new PositionalParameterReference(parameters[1].Name, Null)); + } + result = New.Instance(parentPropertyType, arguments.ToArray()); break; case { IsFrameworkType: false, Implementation: SystemObjectType systemObjectType }: // for the case of SystemObjectType, the serialization constructor is internal and the definition of this class might be outside of this assembly, we need to use its corresponding model factory to construct it @@ -177,6 +187,13 @@ private Method CreateMethod(SerializableObjectType model) continue; } + if (ctorParameter.IsRawData) + { + // we do not want to include the raw data as a parameter of the model factory entry method, therefore here we skip the parameter, and use empty dictionary as argument + methodArguments.Add(new PositionalParameterReference(ctorParameter.Name, Null)); + continue; + } + if (property.FlattenedProperty != null) property = property.FlattenedProperty; @@ -262,7 +279,7 @@ private static bool RequiresModelFactory(SerializableObjectType model) return false; } - var properties = model.EnumerateHierarchy().SelectMany(obj => obj.Properties); + var properties = model.EnumerateHierarchy().SelectMany(obj => obj.Properties.Where(p => p != (obj as SerializableObjectType)?.RawDataField)); // we skip the models with internal properties when the internal property is neither a discriminator or safe flattened if (properties.Any(p => p.Declaration.Accessibility != "public" && (model.Discriminator?.Property != p && p.FlattenedProperty == null))) { diff --git a/src/AutoRest.CSharp/Common/Output/Models/Types/ModelTypeProvider.cs b/src/AutoRest.CSharp/Common/Output/Models/Types/ModelTypeProvider.cs index 9230f58be91..39b8a72bf70 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Types/ModelTypeProvider.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Types/ModelTypeProvider.cs @@ -51,10 +51,44 @@ internal sealed class ModelTypeProvider : SerializableObjectType private ObjectTypeProperty? EnsureAdditionalPropertiesProperty() => Fields.AdditionalProperties is { } additionalPropertiesField - ? Properties.Last(p => p.Declaration.Name == additionalPropertiesField.Name) + ? new ObjectTypeProperty(additionalPropertiesField, null) : null; - public bool IsPropertyBag => _inputModel.IsPropertyBag; + private ObjectTypeProperty? _rawDataField; + public override ObjectTypeProperty? RawDataField + { + get + { + if (_rawDataField != null) + return _rawDataField; + + if (AdditionalPropertiesProperty != null || !ShouldHaveRawData) + return null; + + // when this model has derived types, the accessibility should change from private to `protected internal` + string accessibility = HasDerivedTypes() ? "private protected" : "private"; + + _rawDataField = new ObjectTypeProperty( + BuilderHelpers.CreateMemberDeclaration(PrivateAdditionalPropertiesPropertyName, + _privateAdditionalPropertiesPropertyType, accessibility, null, _typeFactory), + PrivateAdditionalPropertiesPropertyDescription, + true, + null); + + return _rawDataField; + } + } + + private bool HasDerivedTypes() + { + if (_derivedModels is not null && _derivedModels.Any()) + return true; + + if (_inputModel.DiscriminatorPropertyName is not null) + return true; + + return false; + } public ModelTypeProvider(InputModelType inputModel, string defaultNamespace, SourceInputModel? sourceInputModel, TypeFactory typeFactory, SerializableObjectType? defaultDerivedType = null) : base(defaultNamespace, sourceInputModel) @@ -68,6 +102,9 @@ public ModelTypeProvider(InputModelType inputModel, string defaultNamespace, Sou _deprecated = inputModel.Deprecated; _derivedModels = inputModel.DerivedModels; _defaultDerivedType = defaultDerivedType ?? (inputModel.IsUnknownDiscriminatorModel ? this : null); + + IsPropertyBag = inputModel.IsPropertyBag; + IsUnknownDerivedType = inputModel.IsUnknownDiscriminatorModel; } private MethodSignatureModifiers GetFromResponseModifiers() @@ -119,7 +156,7 @@ private ModelTypeProviderFields EnsureFields() private ConstructorSignature EnsurePublicConstructorSignature() { //get base public ctor params - GetConstructorParameters(Fields.PublicConstructorParameters, out var fullParameterList, out var parametersToPassToBase, true); + GetConstructorParameters(Fields.PublicConstructorParameters, out var fullParameterList, out var parametersToPassToBase, out var baseInitializers, true); var accessibility = _inputModel.Usage.HasFlag(InputModelTypeUsage.Input) ? MethodSignatureModifiers.Public @@ -134,13 +171,31 @@ private ConstructorSignature EnsurePublicConstructorSignature() null, accessibility, fullParameterList, - Initializer: new(true, parametersToPassToBase)); + Initializer: new(true, baseInitializers)); } private ConstructorSignature EnsureSerializationConstructorSignature() { + // if there is additional properties property, we need to append it to the parameter list + var parameters = Fields.SerializationParameters; + if (RawDataField != null) + { + var deserializationParameter = new Parameter( + RawDataField.Declaration.Name.ToVariableName(), + RawDataField.ParameterDescription, + RawDataField.Declaration.Type, + null, + ValidationType.None, + null + ) + { + IsRawData = true + }; + parameters = parameters.Append(deserializationParameter).ToList(); + } + //get base public ctor params - GetConstructorParameters(Fields.SerializationParameters, out var fullParameterList, out var parametersToPassToBase, false); + GetConstructorParameters(parameters, out var fullParameterList, out var parametersToPassToBase, out var baseInitializers, false); return new ConstructorSignature( Type, @@ -148,7 +203,7 @@ private ConstructorSignature EnsureSerializationConstructorSignature() null, MethodSignatureModifiers.Internal, fullParameterList, - Initializer: new(true, parametersToPassToBase)); + Initializer: new(true, baseInitializers)); } private IEnumerable CreatePropertySerializations() @@ -180,8 +235,7 @@ private IEnumerable CreatePropertySerializations() property.ValueType.IsNullable && property.OptionalViaNullability ? property.ValueType.WithNullable(false) : property.ValueType, valueSerialization, property.IsRequired, - ShouldSkipSerialization(property, inputModelProperty), - false, + ShouldExcludeInWireSerialization(property, inputModelProperty), customSerializationMethodName: property.SerializationMapping?.SerializationValueHook, customDeserializationMethodName: property.SerializationMapping?.DeserializationValueHook, enumerableExpression: enumerableExpression); @@ -190,7 +244,7 @@ private IEnumerable CreatePropertySerializations() } } - private static bool ShouldSkipSerialization(ObjectTypeProperty property, InputModelProperty inputProperty) + private static bool ShouldExcludeInWireSerialization(ObjectTypeProperty property, InputModelProperty inputProperty) { if (inputProperty.IsDiscriminator) { @@ -205,18 +259,36 @@ private static bool ShouldSkipSerialization(ObjectTypeProperty property, InputMo return inputProperty.IsReadOnly; } - private void GetConstructorParameters(IEnumerable parameters, out List fullParameterList, out IEnumerable parametersToPassToBase, bool isInitializer) + private void GetConstructorParameters(IEnumerable parameters, out IReadOnlyList fullParameterList, out IReadOnlyList parametersToPassToBase, out IReadOnlyList baseInitializers, bool isInitializer) { - fullParameterList = new List(); + var parameterList = new List(); var parent = GetBaseObjectType(); parametersToPassToBase = Array.Empty(); + baseInitializers = Array.Empty(); if (parent is not null) { var ctor = isInitializer ? parent.InitializationConstructor : parent.SerializationConstructor; - parametersToPassToBase = ctor.Signature.Parameters; - fullParameterList.AddRange(parametersToPassToBase); + var baseParameters = new List(); + var baseParameterInitializers = new List(); + foreach (var p in ctor.Signature.Parameters) + { + if (p.IsRawData && AdditionalPropertiesProperty != null) + { + baseParameterInitializers.Add(Snippets.Null); + // do not add into the list + } + else + { + baseParameterInitializers.Add(p); + baseParameters.Add(p); + } + } + parameterList.AddRange(baseParameters); + parametersToPassToBase = baseParameters; + baseInitializers = baseParameterInitializers; } - fullParameterList.AddRange(parameters); + parameterList.AddRange(parameters); + fullParameterList = parameterList; } protected override ObjectTypeConstructor BuildInitializationConstructor() @@ -241,11 +313,12 @@ protected override ObjectTypeConstructor BuildSerializationConstructor() return new ObjectTypeConstructor(SerializationConstructorSignature, GetPropertyInitializers(SerializationConstructorSignature.Parameters, false), baseCtor); } - private ObjectPropertyInitializer[] GetPropertyInitializers(IReadOnlyList parameters, bool includeDiscriminator) + private IReadOnlyList GetPropertyInitializers(IReadOnlyList parameters, bool isInitializer) { - List defaultCtorInitializers = new List(); + List defaultCtorInitializers = new(); - if (includeDiscriminator && Discriminator is not null && Discriminator.Value is { } discriminatorValue && !_inputModel.IsUnknownDiscriminatorModel) + // only initialization ctor initializes the discriminator + if (isInitializer && Discriminator is not null && Discriminator.Value is { } discriminatorValue && !_inputModel.IsUnknownDiscriminatorModel) { defaultCtorInitializers.Add(new ObjectPropertyInitializer(Discriminator.Property, discriminatorValue)); } @@ -256,6 +329,12 @@ private ObjectPropertyInitializer[] GetPropertyInitializers(IReadOnlyList BuildProperties() { foreach (var field in Fields) yield return new ObjectTypeProperty(field, Fields.GetInputByField(field)); + + if (AdditionalPropertiesProperty is { } additionalPropertiesProperty) + yield return additionalPropertiesProperty; + + if (RawDataField is { } rawData) + yield return rawData; } protected override IEnumerable BuildConstructors() @@ -332,67 +417,94 @@ protected override IEnumerable BuildConstructors() yield return InitializationConstructor; if (SerializationConstructor != InitializationConstructor) yield return SerializationConstructor; - } - - protected override bool EnsureHasJsonSerialization() - { - if (IsPropertyBag) - return false; - return true; - } - - protected override bool EnsureHasXmlSerialization() - { - return false; - } - - protected override bool EnsureIncludeSerializer() - { - return _inputModel.Usage.HasFlag(InputModelTypeUsage.Input); - } - protected override bool EnsureIncludeDeserializer() - { - return _inputModel.Usage.HasFlag(InputModelTypeUsage.Output); + // add an extra empty ctor if we do not have a ctor with no parameters + var accessibility = IsStruct ? MethodSignatureModifiers.Public : MethodSignatureModifiers.Internal; + if (Configuration.UseModelReaderWriter && InitializationConstructor.Signature.Parameters.Count > 0 && SerializationConstructor.Signature.Parameters.Count > 0) + yield return new( + new ConstructorSignature(Type, null, $"Initializes a new instance of {Type:C} for deserialization.", accessibility, Array.Empty()), + Array.Empty(), + null); } - protected override JsonObjectSerialization EnsureJsonSerialization() + protected override JsonObjectSerialization? BuildJsonSerialization() { + if (IsPropertyBag) + return null; // Serialization uses field and property names that first need to verified for uniqueness // For that, FieldDeclaration instances must be written in the main partial class before JsonObjectSerialization is created for the serialization partial class - var additionalProperties = CreateAdditionalPropertySerialization(); - return new(Type, SerializationConstructor.Signature.Parameters, CreatePropertySerializations().ToArray(), additionalProperties, Discriminator, false); + var additionalProperties = CreateAdditionalPropertiesSerialization(); + return new(this, SerializationConstructor.Signature.Parameters, CreatePropertySerializations().ToArray(), additionalProperties, Discriminator, false); } - private JsonAdditionalPropertiesSerialization? CreateAdditionalPropertySerialization() + private JsonAdditionalPropertiesSerialization? CreateAdditionalPropertiesSerialization() { - foreach (var model in EnumerateHierarchy().OfType()) + bool shouldExcludeInWireSerialization = false; + ObjectTypeProperty? additionalPropertiesProperty = null; + InputType? additionalPropertiesValueType = null; + foreach (var model in EnumerateHierarchy()) { - if (model is { AdditionalPropertiesProperty: { } additionalProperties, _inputModel.InheritedDictionaryType: { } inheritedDictionaryType }) + additionalPropertiesProperty = model.AdditionalPropertiesProperty ?? (model as SerializableObjectType)?.RawDataField; + if (additionalPropertiesProperty != null) { - var dictionaryValueType = additionalProperties.Declaration.Type.Arguments[1]; - Debug.Assert(!dictionaryValueType.IsNullable, $"{typeof(JsonSerializationMethodsBuilder)} implicitly relies on {additionalProperties.Declaration.Name} dictionary value being non-nullable"); + // if this is a real "AdditionalProperties", we should NOT exclude it in wire + shouldExcludeInWireSerialization = additionalPropertiesProperty != model.AdditionalPropertiesProperty; + if (model is ModelTypeProvider { AdditionalPropertiesProperty: { } additionalProperties, _inputModel.InheritedDictionaryType: { } inheritedDictionaryType }) + { + additionalPropertiesValueType = inheritedDictionaryType.ValueType; + } + break; + } + } - var type = new CSharpType(typeof(Dictionary<,>), additionalProperties.Declaration.Type.Arguments); - var valueSerialization = SerializationBuilder.BuildJsonSerialization(inheritedDictionaryType.ValueType, dictionaryValueType, false, SerializationFormat.Default); + if (additionalPropertiesProperty == null) + { + return null; + } - return new JsonAdditionalPropertiesSerialization(additionalProperties, valueSerialization, type); - } + var dictionaryValueType = additionalPropertiesProperty.Declaration.Type.Arguments[1]; + Debug.Assert(!dictionaryValueType.IsNullable, $"{typeof(JsonCodeWriterExtensions)} implicitly relies on {additionalPropertiesProperty.Declaration.Name} dictionary value being non-nullable"); + JsonSerialization valueSerialization; + if (additionalPropertiesValueType is not null) + { + // build the serialization when there is an input type corresponding to it + valueSerialization = SerializationBuilder.BuildJsonSerialization(additionalPropertiesValueType, dictionaryValueType, false, SerializationFormat.Default); + } + else + { + // build a simple one from its type when there is not an input type corresponding to it (indicating it is a raw data field) + valueSerialization = new JsonValueSerialization(dictionaryValueType, SerializationFormat.Default, true); } - return null; + return new JsonAdditionalPropertiesSerialization( + additionalPropertiesProperty, + valueSerialization, + new CSharpType(typeof(Dictionary<,>), additionalPropertiesProperty.Declaration.Type.Arguments), + shouldExcludeInWireSerialization); } - protected override XmlObjectSerialization? EnsureXmlSerialization() + protected override XmlObjectSerialization? BuildXmlSerialization() { return null; } + protected override bool EnsureIncludeSerializer() + { + // TODO -- this should always return true when use model reader writer is enabled. + return Configuration.UseModelReaderWriter || _inputModel.Usage.HasFlag(InputModelTypeUsage.Input); + } + + protected override bool EnsureIncludeDeserializer() + { + // TODO -- this should always return true when use model reader writer is enabled. + return Configuration.UseModelReaderWriter || _inputModel.Usage.HasFlag(InputModelTypeUsage.Output); + } + protected override IEnumerable BuildMethods() { - if (EnsureIncludeDeserializer()) + if (IncludeDeserializer) yield return Snippets.Extensible.Model.BuildFromOperationResponseMethod(this, GetFromResponseModifiers()); - if (EnsureIncludeSerializer()) + if (IncludeSerializer) yield return Snippets.Extensible.Model.BuildConversionToRequestBodyMethod(GetToRequestContentModifiers()); } diff --git a/src/AutoRest.CSharp/Common/Output/Models/Types/ModelTypeProviderFields.cs b/src/AutoRest.CSharp/Common/Output/Models/Types/ModelTypeProviderFields.cs index 2642338a5b3..808bc6d0696 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Types/ModelTypeProviderFields.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Types/ModelTypeProviderFields.cs @@ -55,7 +55,7 @@ public ModelTypeProviderFields(InputModelType inputModel, CSharpType modelType, var serialization = sourceTypeMapping?.GetForMemberSerialization(existingMember); var field = existingMember is not null - ? CreateFieldFromExisting(existingMember, serialization, propertyType, inputModel, inputModelProperty, typeFactory, optionalViaNullability) + ? CreateFieldFromExisting(existingMember, serialization, propertyType, inputModelProperty, typeFactory, optionalViaNullability) : CreateField(originalFieldName, propertyType, inputModel, inputModelProperty, isStruct, optionalViaNullability); if (existingMember is not null) @@ -109,7 +109,7 @@ public ModelTypeProviderFields(InputModelType inputModel, CSharpType modelType, var additionalPropertiesField = new FieldDeclaration($"Additional Properties", accessModifiers | ReadOnly, type, type, declaration, null, false, Serialization.SerializationFormat.Default, true); var additionalPropertiesParameter = new Parameter(name.ToVariableName(), $"Additional Properties", type, null, ValidationType.None, null); - fields.Add(additionalPropertiesField); + // we intentionally do not add this field into the field list to avoid cyclic references serializationParameters.Add(additionalPropertiesParameter); if (isStruct) { @@ -136,7 +136,7 @@ public ModelTypeProviderFields(InputModelType inputModel, CSharpType modelType, // therefore the top type here is reasonable // the serialization will be generated for this type and it might has issues if the type is not recognized properly. // but customer could always use the `CodeGenMemberSerializationHooks` attribute to override those incorrect serialization/deserialization code. - var field = CreateFieldFromExisting(serializationMapping.ExistingMember, serializationMapping, typeof(object), inputModel, inputModelProperty, typeFactory, false); + var field = CreateFieldFromExisting(serializationMapping.ExistingMember, serializationMapping, typeof(object), inputModelProperty, typeFactory, false); var parameter = new Parameter(field.Name.ToVariableName(), $"to be removed by post process", field.Type, null, ValidationType.None, null); fields.Add(field); fieldsToInputs[field] = inputModelProperty; @@ -274,7 +274,7 @@ private static FieldDeclaration CreateField(string fieldName, CSharpType origina SetterModifiers: setterModifiers); } - private static FieldDeclaration CreateFieldFromExisting(ISymbol existingMember, SourcePropertySerializationMapping? serialization, CSharpType originalType, InputModelType inputModel, InputModelProperty inputModelProperty, TypeFactory typeFactory, bool optionalViaNullability) + private static FieldDeclaration CreateFieldFromExisting(ISymbol existingMember, SourcePropertySerializationMapping? serialization, CSharpType originalType, InputModelProperty inputModelProperty, TypeFactory typeFactory, bool optionalViaNullability) { if (optionalViaNullability) { diff --git a/src/AutoRest.CSharp/Common/Output/Models/Types/ObjectType.cs b/src/AutoRest.CSharp/Common/Output/Models/Types/ObjectType.cs index 3815eb9062b..f5bd8a3ac6d 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Types/ObjectType.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Types/ObjectType.cs @@ -33,6 +33,8 @@ protected ObjectType(string defaultNamespace, SourceInputModel? sourceInputModel { } + public bool IsUnknownDerivedType { get; protected init; } + public bool IsPropertyBag { get; protected init; } public bool IsStruct => ExistingType?.IsValueType ?? false; protected override TypeKind TypeKind => IsStruct ? TypeKind.Struct : TypeKind.Class; public ObjectTypeConstructor[] Constructors => _constructors ??= BuildConstructors().ToArray(); @@ -103,7 +105,7 @@ public virtual FormattableString CreateExtraDescriptionWithDiscriminator() continue; childrenList.Add($"{implementation.Type:C}"); } - return childrenList.Any() ? + return childrenList.Count > 0 ? (FormattableString)$"{Environment.NewLine}{DiscriminatorDescFixedPart[0]}{Type:C}{DiscriminatorDescFixedPart[1]}{Environment.NewLine}{DiscriminatorDescFixedPart[2]}{childrenList.Join(", ", " and ")}." : $"{Environment.NewLine}{DiscriminatorDescFixedPart[0]}{Type:C}{DiscriminatorDescFixedPart[1]}."; } diff --git a/src/AutoRest.CSharp/Common/Output/Models/Types/ObjectTypeProperty.cs b/src/AutoRest.CSharp/Common/Output/Models/Types/ObjectTypeProperty.cs index a87d63752bf..c0e6cf803ee 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Types/ObjectTypeProperty.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Types/ObjectTypeProperty.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using AutoRest.CSharp.Common.Input; using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; @@ -16,6 +17,7 @@ namespace AutoRest.CSharp.Output.Models.Types { + [DebuggerDisplay("Name: {Declaration.Name}, Type: {Declaration.Type}")] internal class ObjectTypeProperty { public ObjectTypeProperty(FieldDeclaration field, InputModelProperty? inputModelProperty) @@ -445,10 +447,5 @@ private static FormattableString CreateExtraPropertyDiscriminatorSummary(CSharpT } return updatedDescription ?? $""; } - - public override string ToString() - { - return $"ObjectTypeProperty {{Name: {Declaration.Name}, Type: {Declaration.Type}}}"; - } } } diff --git a/src/AutoRest.CSharp/Common/Output/Models/Types/SchemaObjectType.cs b/src/AutoRest.CSharp/Common/Output/Models/Types/SchemaObjectType.cs index ba8f65acdaa..afef110c7ac 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Types/SchemaObjectType.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Types/SchemaObjectType.cs @@ -8,6 +8,8 @@ using System.Linq; using AutoRest.CSharp.Common.Decorator; using AutoRest.CSharp.Common.Input; +using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; +using AutoRest.CSharp.Common.Output.Models; using AutoRest.CSharp.Common.Output.Models.Types; using AutoRest.CSharp.Generation.Types; using AutoRest.CSharp.Input; @@ -70,6 +72,7 @@ public SchemaObjectType(ObjectSchema objectSchema, BuildContext context) } _supportedSerializationFormats = GetSupportedSerializationFormats(objectSchema, _sourceTypeMapping); + IsUnknownDerivedType = objectSchema.IsUnknownDiscriminatorModel; } internal ObjectSchema ObjectSchema { get; } @@ -111,6 +114,42 @@ public override ObjectTypeProperty? AdditionalPropertiesProperty } } + private ObjectTypeProperty? _rawDataField; + public override ObjectTypeProperty? RawDataField + { + get + { + if (_rawDataField != null) + return _rawDataField; + + if (AdditionalPropertiesProperty != null || !ShouldHaveRawData) + return null; + + // when this model has derived types, the accessibility should change from private to `protected internal` + string accessibility = HasDerivedTypes() ? "private protected" : "private"; + + _rawDataField = new ObjectTypeProperty( + BuilderHelpers.CreateMemberDeclaration(PrivateAdditionalPropertiesPropertyName, + _privateAdditionalPropertiesPropertyType, accessibility, null, _typeFactory), + PrivateAdditionalPropertiesPropertyDescription, + true, + null); + + return _rawDataField; + } + } + + private bool HasDerivedTypes() + { + if (ObjectSchema.Children is not null && ObjectSchema.Children.All.Count > 0) + return true; + + if (ObjectSchema.Discriminator is not null) + return true; + + return false; + } + protected override ObjectTypeConstructor BuildSerializationConstructor() { bool ownsDiscriminatorProperty = false; @@ -118,11 +157,24 @@ protected override ObjectTypeConstructor BuildSerializationConstructor() List serializationConstructorParameters = new List(); List serializationInitializers = new List(); ObjectTypeConstructor? baseSerializationCtor = null; + List baseParameterInitializers = new List(); if (Inherits is { IsFrameworkType: false, Implementation: ObjectType objectType }) { baseSerializationCtor = objectType.SerializationConstructor; - serializationConstructorParameters.AddRange(baseSerializationCtor.Signature.Parameters); + foreach (var p in baseSerializationCtor.Signature.Parameters) + { + if (p.IsRawData && AdditionalPropertiesProperty != null) + { + baseParameterInitializers.Add(Snippets.Null); + // do not add into the list + } + else + { + baseParameterInitializers.Add(p); + serializationConstructorParameters.Add(p); + } + } } foreach (var property in Properties) @@ -149,6 +201,24 @@ protected override ObjectTypeConstructor BuildSerializationConstructor() serializationInitializers.Add(new ObjectPropertyInitializer(property, deserializationParameter, GetPropertyDefaultValue(property))); } + // add the raw data to serialization ctor parameter list + if (RawDataField != null) + { + var deserializationParameter = new Parameter( + RawDataField.Declaration.Name.ToVariableName(), + RawDataField.ParameterDescription, + RawDataField.Declaration.Type, + null, + ValidationType.None, + null + ) + { + IsRawData = true + }; + serializationConstructorParameters.Add(deserializationParameter); + serializationInitializers.Add(new ObjectPropertyInitializer(RawDataField, deserializationParameter, null)); + } + if (InitializationConstructor.Signature.Parameters .Select(p => p.Type) .SequenceEqual(serializationConstructorParameters.Select(p => p.Type))) @@ -173,13 +243,20 @@ protected override ObjectTypeConstructor BuildSerializationConstructor() } } - return new ObjectTypeConstructor( + var initializer = new ConstructorInitializer(true, baseParameterInitializers); + + var signature = new ConstructorSignature( Type, + $"Initializes a new instance of {Type:C}", + null, IsInheritableCommonType ? Protected : Internal, - serializationConstructorParameters.ToArray(), - serializationInitializers.ToArray(), - baseSerializationCtor - ); + serializationConstructorParameters, + Initializer: initializer); + + return new ObjectTypeConstructor( + signature, + serializationInitializers, + baseSerializationCtor); } private ReferenceOrConstant? GetPropertyDefaultValue(ObjectTypeProperty property) @@ -204,6 +281,11 @@ protected override ObjectTypeConstructor BuildInitializationConstructor() foreach (var property in Properties) { + // we do not need to add intialization for raw data field + if (property == RawDataField) + { + continue; + } // Only required properties that are not discriminators go into default ctor // skip the flattened properties, we should never include them in the constructors if (property == Discriminator?.Property || property is FlattenedObjectTypeProperty) @@ -289,8 +371,8 @@ protected override ObjectTypeConstructor BuildInitializationConstructor() return new ObjectTypeConstructor( Type, IsAbstract ? Protected : _usage.HasFlag(SchemaTypeUsage.Input) ? Public : Internal, - defaultCtorParameters.ToArray(), - defaultCtorInitializers.ToArray(), + defaultCtorParameters, + defaultCtorInitializers, baseCtor); } @@ -304,15 +386,19 @@ protected override IEnumerable BuildConstructors() { // Skip initialization ctor if this instance is used to support forward compatibility in polymorphism. if (!SkipInitializerConstructor) - { yield return InitializationConstructor; - } // Skip serialization ctor if they are the same if (InitializationConstructor != SerializationConstructor) - { yield return SerializationConstructor; - } + + // add an extra empty ctor if we do not have a ctor with no parameters + var accessibility = IsStruct ? Public : Internal; + if (Configuration.UseModelReaderWriter && InitializationConstructor.Signature.Parameters.Count > 0 && SerializationConstructor.Signature.Parameters.Count > 0) + yield return new( + new ConstructorSignature(Type, null, $"Initializes a new instance of {Type:C} for deserialization.", accessibility, Array.Empty()), + Array.Empty(), + null); } protected override ObjectTypeDiscriminator? BuildDiscriminator() @@ -629,34 +715,26 @@ protected override FormattableString CreateDescription() return $"{ObjectSchema.CreateDescription()}"; } - protected override bool EnsureHasJsonSerialization() - { - return _supportedSerializationFormats.Contains(KnownMediaType.Json); - } - - protected override bool EnsureHasXmlSerialization() - { - return _supportedSerializationFormats.Contains(KnownMediaType.Xml); - } - protected override bool EnsureIncludeSerializer() { - return _usage.HasFlag(SchemaTypeUsage.Input); + // TODO -- this should always return true when use model reader writer is enabled. + return Configuration.UseModelReaderWriter || _usage.HasFlag(SchemaTypeUsage.Input); } protected override bool EnsureIncludeDeserializer() { - return _usage.HasFlag(SchemaTypeUsage.Output); + // TODO -- this should always return true when use model reader writer is enabled. + return Configuration.UseModelReaderWriter || _usage.HasFlag(SchemaTypeUsage.Output); } - protected override JsonObjectSerialization EnsureJsonSerialization() + protected override JsonObjectSerialization? BuildJsonSerialization() { - return _serializationBuilder.BuildJsonObjectSerialization(ObjectSchema, this); + return _supportedSerializationFormats.Contains(KnownMediaType.Json) ? _serializationBuilder.BuildJsonObjectSerialization(ObjectSchema, this) : null; } - protected override XmlObjectSerialization EnsureXmlSerialization() + protected override XmlObjectSerialization? BuildXmlSerialization() { - return _serializationBuilder.BuildXmlObjectSerialization(ObjectSchema, this); + return _supportedSerializationFormats.Contains(KnownMediaType.Xml) ? _serializationBuilder.BuildXmlObjectSerialization(ObjectSchema, this) : null; } private SerializableObjectType? BuildDefaultDerivedType() diff --git a/src/AutoRest.CSharp/Common/Output/Models/Types/SerializableObjectType.cs b/src/AutoRest.CSharp/Common/Output/Models/Types/SerializableObjectType.cs index 7a26433833a..25ab909e8c2 100644 --- a/src/AutoRest.CSharp/Common/Output/Models/Types/SerializableObjectType.cs +++ b/src/AutoRest.CSharp/Common/Output/Models/Types/SerializableObjectType.cs @@ -1,6 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +using System; +using System.Collections.Generic; +using AutoRest.CSharp.Common.Input; +using AutoRest.CSharp.Generation.Types; using AutoRest.CSharp.Input.Source; using AutoRest.CSharp.Output.Models.Serialization.Json; using AutoRest.CSharp.Output.Models.Serialization.Xml; @@ -26,23 +30,63 @@ protected SerializableObjectType(string defaultNamespace, SourceInputModel? sour private bool? _includeDeserializer; public bool IncludeDeserializer => _includeDeserializer ??= EnsureIncludeDeserializer(); + private bool _jsonSerializationInitialized = false; private JsonObjectSerialization? _jsonSerialization; - public JsonObjectSerialization? JsonSerialization => HasJsonSerialization ? _jsonSerialization ??= EnsureJsonSerialization() : null; + public JsonObjectSerialization? JsonSerialization => EnsureJsonSerialization(); + private bool _xmlSerializationInitialized = false; private XmlObjectSerialization? _xmlSerialization; - public XmlObjectSerialization? XmlSerialization => HasXmlSerialization ? _xmlSerialization ??= EnsureXmlSerialization() : null; + public XmlObjectSerialization? XmlSerialization => EnsureXmlSerialization(); - private bool? _hasJsonSerialization; - private bool HasJsonSerialization => _hasJsonSerialization ??= EnsureHasJsonSerialization(); + private JsonObjectSerialization? EnsureJsonSerialization() + { + if (_jsonSerializationInitialized) + return _jsonSerialization; + + _jsonSerializationInitialized = true; + _jsonSerialization = BuildJsonSerialization(); + return _jsonSerialization; + } + + private XmlObjectSerialization? EnsureXmlSerialization() + { + if (_xmlSerializationInitialized) + return _xmlSerialization; + + _xmlSerializationInitialized = true; + _xmlSerialization = BuildXmlSerialization(); + return _xmlSerialization; + } + + protected abstract JsonObjectSerialization? BuildJsonSerialization(); + protected abstract XmlObjectSerialization? BuildXmlSerialization(); - private bool? _hasXmlSerialization; - private bool HasXmlSerialization => _hasXmlSerialization ??= EnsureHasXmlSerialization(); - protected abstract bool EnsureHasJsonSerialization(); - protected abstract bool EnsureHasXmlSerialization(); protected abstract bool EnsureIncludeSerializer(); protected abstract bool EnsureIncludeDeserializer(); - protected abstract JsonObjectSerialization? EnsureJsonSerialization(); - protected abstract XmlObjectSerialization? EnsureXmlSerialization(); + + // TODO -- despite this is actually a field if present, we have to make it a property to work properly with other functionalities in the generator, such as the `CodeWriter.WriteInitialization` method + public virtual ObjectTypeProperty? RawDataField => null; + + private bool? _shouldHaveRawData; + protected bool ShouldHaveRawData => _shouldHaveRawData ??= EnsureShouldHaveRawData(); + + private bool EnsureShouldHaveRawData() + { + if (!Configuration.UseModelReaderWriter) + return false; + + if (IsPropertyBag) + return false; + + if (Inherits != null && Inherits is not { IsFrameworkType: false, Implementation: SystemObjectType }) + return false; + + return true; + } + + protected const string PrivateAdditionalPropertiesPropertyDescription = "Keeps track of any properties unknown to the library."; + protected const string PrivateAdditionalPropertiesPropertyName = "_serializedAdditionalRawData"; + protected static readonly CSharpType _privateAdditionalPropertiesPropertyType = typeof(IDictionary); } } diff --git a/src/AutoRest.CSharp/LowLevel/Generation/DpgClientWriter.cs b/src/AutoRest.CSharp/LowLevel/Generation/DpgClientWriter.cs index accd59dadfe..c860d7fb1c9 100644 --- a/src/AutoRest.CSharp/LowLevel/Generation/DpgClientWriter.cs +++ b/src/AutoRest.CSharp/LowLevel/Generation/DpgClientWriter.cs @@ -315,7 +315,7 @@ private void WriteConvenienceMethod(LowLevelClientMethod clientMethod, Convenien { _writer.WriteMethodBodyStatement(Return(response)); } - else if (responseType is { IsFrameworkType: false, Implementation: SerializableObjectType { JsonSerialization: { }, IncludeDeserializer: true } serializableObjectType}) + else if (responseType is { IsFrameworkType: false, Implementation: SerializableObjectType { JsonSerialization: { } } serializableObjectType}) { _writer.WriteMethodBodyStatement(Return(Extensible.RestOperations.GetTypedResponseFromModel(serializableObjectType, response))); } diff --git a/src/AutoRest.CSharp/LowLevel/Output/DpgOutputLibraryBuilder.cs b/src/AutoRest.CSharp/LowLevel/Output/DpgOutputLibraryBuilder.cs index 2c869dd7702..5cdb98f6bf1 100644 --- a/src/AutoRest.CSharp/LowLevel/Output/DpgOutputLibraryBuilder.cs +++ b/src/AutoRest.CSharp/LowLevel/Output/DpgOutputLibraryBuilder.cs @@ -372,7 +372,8 @@ private bool IsSameType(InputType type, InputModelType anonModel) InputModelType actualBase = isBasePolyType ? model : model.BaseModel!; //Since the unknown type is used for deserialization only we don't need to create if its an input only model - if (!actualBase.Usage.HasFlag(InputModelTypeUsage.Output)) + // TODO -- remove this condition completely when remove the UseModelReaderWriter flag + if (!Configuration.UseModelReaderWriter && !actualBase.Usage.HasFlag(InputModelTypeUsage.Output)) return null; string defaultDerivedName = $"Unknown{actualBase.Name}"; diff --git a/src/AutoRest.CSharp/LowLevel/Output/LowLevelClient.cs b/src/AutoRest.CSharp/LowLevel/Output/LowLevelClient.cs index 6502d2a7d2d..598acf7632c 100644 --- a/src/AutoRest.CSharp/LowLevel/Output/LowLevelClient.cs +++ b/src/AutoRest.CSharp/LowLevel/Output/LowLevelClient.cs @@ -8,6 +8,7 @@ using AutoRest.CSharp.Common.Input; using AutoRest.CSharp.Common.Input.Examples; using AutoRest.CSharp.Common.Output.Builders; +using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using AutoRest.CSharp.Common.Output.Models.Responses; using AutoRest.CSharp.Generation.Types; using AutoRest.CSharp.Generation.Writers; @@ -206,17 +207,16 @@ private IEnumerable BuildSecondaryConstructors(IReadOnlyLi * */ var optionalParametersArguments = optionalParameters .Where(p => !p.Name.Equals("endpoint", StringComparison.OrdinalIgnoreCase)) - .Select(p => p.Initializer ?? p.Type.GetParameterInitializer(p.DefaultValue!.Value)!) + .Select(p => new FormattableStringToExpression(p.Initializer ?? p.Type.GetParameterInitializer(p.DefaultValue!.Value)!)) .ToArray(); var optionalEndpoint = optionalParameters.Where(p => p.Name.Equals("endpoint", StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); - var arguments = new List(); + var arguments = new List(); if (optionalEndpoint != null) { - arguments.Add(optionalEndpoint.Initializer ?? optionalEndpoint.Type.GetParameterInitializer(optionalEndpoint.DefaultValue!.Value)!); + arguments.Add(new FormattableStringToExpression(optionalEndpoint.Initializer ?? optionalEndpoint.Type.GetParameterInitializer(optionalEndpoint.DefaultValue!.Value)!)); } - arguments.AddRange(requiredParameters - .Select(p => $"{p.Name}")); + arguments.AddRange(requiredParameters.Select(p => (ValueExpression)p)); if (Fields.CredentialFields.Count == 0) { @@ -228,7 +228,7 @@ private IEnumerable BuildSecondaryConstructors(IReadOnlyLi foreach (var credentialField in Fields.CredentialFields) { var credentialParameter = CreateCredentialParameter(credentialField!.Type); - var allArguments = arguments.Concat(new List() { $"{credentialParameter.Name}" }).Concat(optionalParametersArguments); + var allArguments = arguments.Append(credentialParameter).Concat(optionalParametersArguments); yield return CreateSecondaryConstructor(requiredParameters.Append(credentialParameter).ToArray(), allArguments.ToArray()); } } @@ -237,7 +237,7 @@ private IEnumerable BuildSecondaryConstructors(IReadOnlyLi private ConstructorSignature CreatePrimaryConstructor(IReadOnlyList parameters) => new(Type, $"Initializes a new instance of {Declaration.Name}", null, Public, parameters); - private ConstructorSignature CreateSecondaryConstructor(IReadOnlyList parameters, FormattableString[] arguments) + private ConstructorSignature CreateSecondaryConstructor(IReadOnlyList parameters, IReadOnlyList arguments) { return new(Type, $"Initializes a new instance of {Declaration.Name}", null, Public, parameters, Initializer: new ConstructorInitializer(false, arguments)); } diff --git a/src/AutoRest.CSharp/LowLevel/Output/Samples/DpgClientSampleProvider.cs b/src/AutoRest.CSharp/LowLevel/Output/Samples/DpgClientSampleProvider.cs index 83346ef8de9..51a02809407 100644 --- a/src/AutoRest.CSharp/LowLevel/Output/Samples/DpgClientSampleProvider.cs +++ b/src/AutoRest.CSharp/LowLevel/Output/Samples/DpgClientSampleProvider.cs @@ -156,7 +156,7 @@ private IEnumerable BuildSampleOperationInvocation(DpgOpera { var methodSignature = sample.OperationMethodSignature.WithAsync(isAsync); var parameterExpressions = sample.GetValueExpressionsForParameters(methodSignature.Parameters, variableDeclarations); - var invocation = clientVar.Invoke(methodSignature, parameterExpressions.ToArray(), addConfigureAwaitFalse: false); + ValueExpression invocation = clientVar.Invoke(methodSignature, parameterExpressions.ToArray(), addConfigureAwaitFalse: false); var returnType = GetReturnType(methodSignature.ReturnType); VariableReference resultVar = sample.IsLongRunning ? new VariableReference(returnType, "operation") diff --git a/src/AutoRest.CSharp/Mgmt/Generation/MockableArmClientWriter.cs b/src/AutoRest.CSharp/Mgmt/Generation/MockableArmClientWriter.cs index 2541a0d7cba..dd0b287c6cb 100644 --- a/src/AutoRest.CSharp/Mgmt/Generation/MockableArmClientWriter.cs +++ b/src/AutoRest.CSharp/Mgmt/Generation/MockableArmClientWriter.cs @@ -4,6 +4,9 @@ using System; using System.Collections.Generic; using System.Linq; +using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions; +using AutoRest.CSharp.Common.Output.Expressions.KnownValueExpressions.Azure; +using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using AutoRest.CSharp.Generation.Writers; using AutoRest.CSharp.Mgmt.Decorator; using AutoRest.CSharp.Mgmt.Models; @@ -40,7 +43,7 @@ protected override void WriteCtors() var ctor = armClientCtor with { Parameters = new[] { KnownParameters.ArmClient }, - Initializer = new(false, new FormattableString[] { $"{KnownParameters.ArmClient.Name:I}", $"{typeof(ResourceIdentifier)}.{nameof(ResourceIdentifier.Root)}" }) + Initializer = new(false, new ValueExpression[] { KnownParameters.ArmClient, ResourceIdentifierExpression.Root }) }; using (_writer.WriteMethodDeclaration(ctor)) diff --git a/src/AutoRest.CSharp/Mgmt/Generation/OperationSourceWriter.cs b/src/AutoRest.CSharp/Mgmt/Generation/OperationSourceWriter.cs index 66e4d044875..daecfc3bfaf 100644 --- a/src/AutoRest.CSharp/Mgmt/Generation/OperationSourceWriter.cs +++ b/src/AutoRest.CSharp/Mgmt/Generation/OperationSourceWriter.cs @@ -102,7 +102,14 @@ public void Write() foreach (var param in resource.ResourceData.SerializationConstructor.Signature.Parameters.Skip(3)) { _writer.Line(); - _writer.Append($"\tdata.{param.Name.FirstCharToUpperCase()},"); + if (param.IsRawData) + { + _writer.Append($"\tnull"); + } + else + { + _writer.Append($"\tdata.{param.Name.ToCleanName()},"); + } } _writer.RemoveTrailingComma(); _writer.Line($");"); @@ -148,7 +155,6 @@ private IEnumerable BuildCreateResultBody(StreamExpression if (_opSource.IsReturningResource) { var resourceData = _opSource.Resource!.ResourceData; - Debug.Assert(resourceData.IncludeDeserializer); yield return UsingVar("document", JsonDocumentExpression.Parse(stream, async), out var document); diff --git a/src/AutoRest.CSharp/Mgmt/Output/MgmtReferenceType.cs b/src/AutoRest.CSharp/Mgmt/Output/MgmtReferenceType.cs index 9eb0dc263b6..c34046d146a 100644 --- a/src/AutoRest.CSharp/Mgmt/Output/MgmtReferenceType.cs +++ b/src/AutoRest.CSharp/Mgmt/Output/MgmtReferenceType.cs @@ -54,5 +54,8 @@ protected override ObjectTypeProperty CreatePropertyType(ObjectTypeProperty obje { return ObjectSchema.Extensions?.MgmtReferenceType == true ? CreateInheritedTypeWithNoExtraMatch() : base.CreateInheritedType(); } + + // the reference types do not need raw data field + public override ObjectTypeProperty? RawDataField => null; } } diff --git a/src/AutoRest.CSharp/Mgmt/Output/Resource.cs b/src/AutoRest.CSharp/Mgmt/Output/Resource.cs index 3ff2e034c43..24adbcafe4e 100644 --- a/src/AutoRest.CSharp/Mgmt/Output/Resource.cs +++ b/src/AutoRest.CSharp/Mgmt/Output/Resource.cs @@ -123,7 +123,7 @@ protected internal Resource(OperationSet operationSet, IEnumerable op Parameters: new[] { KnownParameters.ArmClient, ResourceDataParameter }, Initializer: new( IsBase: false, - Arguments: new FormattableString[] { $"{KnownParameters.ArmClient.Name:I}", ResourceDataIdExpression($"{ResourceDataParameter.Name:I}") })); + Arguments: new ValueExpression[] { KnownParameters.ArmClient, ResourceDataIdExpression(ResourceDataParameter) })); } public override CSharpType? BaseType => typeof(ArmResource); @@ -569,17 +569,18 @@ protected virtual Method BuildCreateResourceIdentifierMethod() return new Method(signature, methodBody); } - public FormattableString ResourceDataIdExpression(FormattableString dataExpression) + public ValueExpression ResourceDataIdExpression(ValueExpression dataExpression) { + var id = dataExpression.Property("Id"); var typeOfId = ResourceData.TypeOfId; if (typeOfId != null && typeOfId.Equals(typeof(string))) { - return $"new {typeof(ResourceIdentifier)}({dataExpression}.Id)"; + return Snippets.New.Instance(typeof(ResourceIdentifier), id); } else { // we have ensured other cases we would have an Id of Azure.Core.ResourceIdentifier type - return $"{dataExpression}.Id"; + return id; } } diff --git a/src/AutoRest.CSharp/MgmtTest/Output/Mock/MgmtMockTestProvider.cs b/src/AutoRest.CSharp/MgmtTest/Output/Mock/MgmtMockTestProvider.cs index 8c5d6d6065e..fa8c318bdea 100644 --- a/src/AutoRest.CSharp/MgmtTest/Output/Mock/MgmtMockTestProvider.cs +++ b/src/AutoRest.CSharp/MgmtTest/Output/Mock/MgmtMockTestProvider.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using AutoRest.CSharp.Common.Output.Expressions.ValueExpressions; using AutoRest.CSharp.Generation.Types; using AutoRest.CSharp.Mgmt.Output; using AutoRest.CSharp.MgmtTest.Models; @@ -42,7 +43,7 @@ public MgmtMockTestProvider(T provider, IEnumerable testCases) : b Parameters: new[] { IsAsyncParameter }, Initializer: new ConstructorInitializer( true, - new FormattableString[] { $"{IsAsyncParameter.Name:I}", $"{typeof(RecordedTestMode)}.Record" })); + new ValueExpression[] { IsAsyncParameter, new TypeReference(typeof(RecordedTestMode)).Property(nameof(RecordedTestMode.Record)) })); } } } diff --git a/src/TypeSpec.Extension/Emitter.Csharp/src/emitter.ts b/src/TypeSpec.Extension/Emitter.Csharp/src/emitter.ts index 4dc4d9d031f..3707cee9e24 100644 --- a/src/TypeSpec.Extension/Emitter.Csharp/src/emitter.ts +++ b/src/TypeSpec.Extension/Emitter.Csharp/src/emitter.ts @@ -160,7 +160,8 @@ export async function $onEmit(context: EmitContext) { generateTestProject: options["generateTestProject"] === true ? undefined - : options["generateTestProject"] + : options["generateTestProject"], + "use-model-reader-writer": options["use-model-reader-writer"] } as Configuration; await program.host.writeFile( diff --git a/src/TypeSpec.Extension/Emitter.Csharp/src/options.ts b/src/TypeSpec.Extension/Emitter.Csharp/src/options.ts index 615118c3963..6e815cd671f 100644 --- a/src/TypeSpec.Extension/Emitter.Csharp/src/options.ts +++ b/src/TypeSpec.Extension/Emitter.Csharp/src/options.ts @@ -32,6 +32,7 @@ export type NetEmitterOptions = { "head-as-boolean"?: boolean; branded?: boolean; generateTestProject?: boolean; + "use-model-reader-writer"?: boolean; } & SdkEmitterOptions; export const NetEmitterOptionsSchema: JSONSchemaType = { @@ -101,7 +102,8 @@ export const NetEmitterOptionsSchema: JSONSchemaType = { "package-dir": { type: "string", nullable: true }, "head-as-boolean": { type: "boolean", nullable: true }, branded: { type: "boolean", nullable: true, default: true }, - generateTestProject: { type: "boolean", nullable: true, default: true } + generateTestProject: { type: "boolean", nullable: true, default: true }, + "use-model-reader-writer": { type: "boolean", nullable: true } }, required: [] }; diff --git a/src/assets/Generator.Shared/GeneratorPageableHelpers.cs b/src/assets/Generator.Shared/GeneratorPageableHelpers.cs index 190b769e544..2014c349e9c 100644 --- a/src/assets/Generator.Shared/GeneratorPageableHelpers.cs +++ b/src/assets/Generator.Shared/GeneratorPageableHelpers.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; -using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -17,9 +16,6 @@ namespace Autorest.CSharp.Core { internal static class GeneratorPageableHelpers { - private static readonly byte[] DefaultItemPropertyName = Encoding.UTF8.GetBytes("value"); - private static readonly byte[] DefaultNextLinkPropertyName = Encoding.UTF8.GetBytes("nextLink"); - public static AsyncPageable CreateAsyncPageable( Func? createFirstPageRequest, Func? createNextPageRequest, diff --git a/test/AutoRest.Shared.Tests/AutoRest.Shared.Tests.csproj b/test/AutoRest.Shared.Tests/AutoRest.Shared.Tests.csproj index f04725c2eb0..0ba6275d7c7 100644 --- a/test/AutoRest.Shared.Tests/AutoRest.Shared.Tests.csproj +++ b/test/AutoRest.Shared.Tests/AutoRest.Shared.Tests.csproj @@ -10,6 +10,7 @@ + diff --git a/test/AutoRest.TestServer.Tests/Common/Utilities/NamedTypeSymbolExtensionsTests.cs b/test/AutoRest.TestServer.Tests/Common/Utilities/NamedTypeSymbolExtensionsTests.cs index b5099cf9c16..196e4003765 100644 --- a/test/AutoRest.TestServer.Tests/Common/Utilities/NamedTypeSymbolExtensionsTests.cs +++ b/test/AutoRest.TestServer.Tests/Common/Utilities/NamedTypeSymbolExtensionsTests.cs @@ -94,6 +94,7 @@ public void Method(int? nullableInt, List intList, List nullableIntLi publicDiscriminatorProperty: false, deserializeNullCollectionAsNullValue: false, useCoreDataFactoryReplacements: true, + useModelReaderWriter: true, modelFactoryForHlc: Array.Empty(), unreferencedTypesHandling: Configuration.UnreferencedTypesHandlingOption.RemoveOrInternalize, keepNonOverloadableProtocolSignature: false, diff --git a/test/AutoRest.TestServer.Tests/Infrastructure/JsonAsserts.cs b/test/AutoRest.TestServer.Tests/Infrastructure/JsonAsserts.cs index b67052e1377..af825f5eb1b 100644 --- a/test/AutoRest.TestServer.Tests/Infrastructure/JsonAsserts.cs +++ b/test/AutoRest.TestServer.Tests/Infrastructure/JsonAsserts.cs @@ -8,7 +8,7 @@ namespace AutoRest.TestServer.Tests.Infrastructure { internal static class JsonAsserts { - public static void AssertSerialization(string expected, IUtf8JsonSerializable serializable) + public static void AssertWireSerialization(string expected, IUtf8JsonSerializable serializable) { using var memoryStream = new MemoryStream(); @@ -22,7 +22,7 @@ public static void AssertSerialization(string expected, IUtf8JsonSerializable se Assert.AreEqual(expected, text); } - public static JsonElement AssertSerializes(IUtf8JsonSerializable serializable) + public static JsonElement AssertWireSerializes(IUtf8JsonSerializable serializable) { using var memoryStream = new MemoryStream(); @@ -33,8 +33,5 @@ public static JsonElement AssertSerializes(IUtf8JsonSerializable serializable) return JsonDocument.Parse(memoryStream.ToArray()).RootElement; } - - public static JsonElement Parse(string content) - => JsonDocument.Parse(content).RootElement; } } diff --git a/test/AutoRest.TestServer.Tests/LowLevel/CircularModelTests.cs b/test/AutoRest.TestServer.Tests/LowLevel/CircularModelTests.cs index 79f624e74f4..465e4c2cd8b 100644 --- a/test/AutoRest.TestServer.Tests/LowLevel/CircularModelTests.cs +++ b/test/AutoRest.TestServer.Tests/LowLevel/CircularModelTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +using System.Text.Json; using AutoRest.TestServer.Tests.Infrastructure; using ModelsTypeSpec.Models; using NUnit.Framework; @@ -15,13 +16,14 @@ public void InputRecursive() var input = new InputRecursiveModel("parent"); input.Inner = new InputRecursiveModel("child"); - JsonAsserts.AssertSerialization("{\"message\":\"parent\",\"inner\":{\"message\":\"child\"}}", input); + JsonAsserts.AssertWireSerialization("{\"message\":\"parent\",\"inner\":{\"message\":\"child\"}}", input); } [Test] public void OutputRecursive() { - var output = ErrorModel.DeserializeErrorModel(JsonAsserts.Parse("{\"message\":\"parent\",\"innerError\":{\"message\":\"child\"}}")); + using var document = JsonDocument.Parse("{\"message\":\"parent\",\"innerError\":{\"message\":\"child\"}}"); + var output = ErrorModel.DeserializeErrorModel(document.RootElement); Assert.AreEqual("parent", output.Message); Assert.AreEqual("child", output.InnerError.Message); @@ -34,9 +36,9 @@ public void RoundTripRecursive() var input = new RoundTripRecursiveModel("parent"); input.Inner = new RoundTripRecursiveModel("child"); - JsonAsserts.AssertSerialization("{\"message\":\"parent\",\"inner\":{\"message\":\"child\"}}", input); + JsonAsserts.AssertWireSerialization("{\"message\":\"parent\",\"inner\":{\"message\":\"child\"}}", input); - var output = RoundTripRecursiveModel.DeserializeRoundTripRecursiveModel(JsonAsserts.AssertSerializes(input)); + var output = RoundTripRecursiveModel.DeserializeRoundTripRecursiveModel(JsonAsserts.AssertWireSerializes(input)); Assert.AreEqual(input.Message, output.Message); Assert.AreEqual(input.Inner.Message, output.Inner.Message); diff --git a/test/AutoRest.TestServer.Tests/LowLevel/ModelsTypeSpecTests.cs b/test/AutoRest.TestServer.Tests/LowLevel/ModelsTypeSpecTests.cs index 637c0345e91..c621293b803 100644 --- a/test/AutoRest.TestServer.Tests/LowLevel/ModelsTypeSpecTests.cs +++ b/test/AutoRest.TestServer.Tests/LowLevel/ModelsTypeSpecTests.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using System.Text.Json; using AutoRest.TestServer.Tests.Infrastructure; using ModelsTypeSpec.Models; using NUnit.Framework; @@ -19,9 +20,10 @@ public void PlainDateTime() var input = new RoundTripOptionalModel(); input.OptionalPlainDate = PlainDateData; - JsonAsserts.AssertSerialization("{\"optionalPlainDate\":\"2022-12-12\"}", input); + JsonAsserts.AssertWireSerialization("{\"optionalPlainDate\":\"2022-12-12\"}", input); - var output = RoundTripOptionalModel.DeserializeRoundTripOptionalModel(JsonAsserts.Parse("{\"optionalPlainDate\":\"2022-12-12\"}")); + using var document = JsonDocument.Parse("{\"optionalPlainDate\":\"2022-12-12\"}"); + var output = RoundTripOptionalModel.DeserializeRoundTripOptionalModel(document.RootElement); Assert.AreEqual(PlainDateData, output.OptionalPlainDate); } @@ -31,9 +33,10 @@ public void PlainDateTimeOmittingTime() var input = new RoundTripOptionalModel(); input.OptionalPlainDate = new DateTimeOffset(2022, 12, 12, 13, 06, 0, 0, new TimeSpan()); - JsonAsserts.AssertSerialization("{\"optionalPlainDate\":\"2022-12-12\"}", input); + JsonAsserts.AssertWireSerialization("{\"optionalPlainDate\":\"2022-12-12\"}", input); - var output = RoundTripOptionalModel.DeserializeRoundTripOptionalModel(JsonAsserts.Parse("{\"optionalPlainDate\":\"2022-12-12T13:06:00\"}")); + using var document = JsonDocument.Parse("{\"optionalPlainDate\":\"2022-12-12T13:06:00\"}"); + var output = RoundTripOptionalModel.DeserializeRoundTripOptionalModel(document.RootElement); var plainDate = output.OptionalPlainDate; Assert.IsNotNull(plainDate.Value); Assert.AreEqual(2022, plainDate.Value.Year); @@ -50,9 +53,10 @@ public void PlainTime() var input = new RoundTripOptionalModel(); input.OptionalPlainTime = PlainTimeData; - JsonAsserts.AssertSerialization("{\"optionalPlainTime\":\"13:06:12\"}", input); + JsonAsserts.AssertWireSerialization("{\"optionalPlainTime\":\"13:06:12\"}", input); - var output = RoundTripOptionalModel.DeserializeRoundTripOptionalModel(JsonAsserts.Parse("{\"optionalPlainTime\":\"13:06:12\"}")); + using var document = JsonDocument.Parse("{\"optionalPlainTime\":\"13:06:12\"}"); + var output = RoundTripOptionalModel.DeserializeRoundTripOptionalModel(document.RootElement); Assert.AreEqual(PlainTimeData, output.OptionalPlainTime); } } diff --git a/test/AutoRest.TestServer.Tests/Mgmt/Unit/MgmtRestOperationTests.cs b/test/AutoRest.TestServer.Tests/Mgmt/Unit/MgmtRestOperationTests.cs index 03b5615963a..ec8e3d1c0c3 100644 --- a/test/AutoRest.TestServer.Tests/Mgmt/Unit/MgmtRestOperationTests.cs +++ b/test/AutoRest.TestServer.Tests/Mgmt/Unit/MgmtRestOperationTests.cs @@ -74,6 +74,7 @@ public void Setup() unreferencedTypesHandling: Configuration.UnreferencedTypesHandlingOption.RemoveOrInternalize, keepNonOverloadableProtocolSignature: false, useCoreDataFactoryReplacements: true, + useModelReaderWriter: true, projectFolder: "/..", existingProjectFolder: null, protocolMethodList: Array.Empty(), diff --git a/test/AutoRest.TestServer.Tests/MgmtCustomizationsTests.cs b/test/AutoRest.TestServer.Tests/MgmtCustomizationsTests.cs index b2de75e8a95..7e64985d633 100644 --- a/test/AutoRest.TestServer.Tests/MgmtCustomizationsTests.cs +++ b/test/AutoRest.TestServer.Tests/MgmtCustomizationsTests.cs @@ -19,7 +19,7 @@ public void Cat_SizeSerializeIntoString() Meow = "MEOW" }; - var root = JsonAsserts.AssertSerializes(pet); + var root = JsonAsserts.AssertWireSerializes(pet); var sizeProperty = root.GetProperty("size"); // asserts we serialize the int size into a string @@ -31,9 +31,9 @@ public void Cat_SizeSerializeIntoString() public void Cat_SizeDeserializeIntoInt() { var json = @"{""kind"": ""Cat"", ""size"": ""10"", ""meow"": ""MEOW""}"; - var root = JsonAsserts.Parse(json); + using var document = JsonDocument.Parse(json); - var pet = Pet.DeserializePet(root); + var pet = Pet.DeserializePet(document.RootElement); var cat = pet as Cat; Assert.IsTrue(cat != null); @@ -52,7 +52,7 @@ public void Dog_SerializeIntoProperties() // this should serialize into: // { "kind": "Dog", "properties": { "dog": { "bark": "DOG BARKS" } } } - var root = JsonAsserts.AssertSerializes(pet); + var root = JsonAsserts.AssertWireSerializes(pet); var properties = root.GetProperty("properties"); Assert.AreEqual(JsonValueKind.Object, properties.ValueKind); var dogProperty = properties.GetProperty("dog"); @@ -66,10 +66,9 @@ public void Dog_SerializeIntoProperties() public void Dog_DeserializeFromProperties() { var json = @"{""kind"": ""Dog"", ""properties"": { ""dog"": { ""bark"": ""dog barks"" }}}"; + using var document = JsonDocument.Parse(json); - var root = JsonAsserts.Parse(json); - - var pet = Pet.DeserializePet(root); + var pet = Pet.DeserializePet(document.RootElement); var dog = pet as Dog; Assert.IsTrue(dog != null); diff --git a/test/AutoRest.TestServer.Tests/ModelShapeTests.cs b/test/AutoRest.TestServer.Tests/ModelShapeTests.cs index 2464a28d5de..65b6ad49264 100644 --- a/test/AutoRest.TestServer.Tests/ModelShapeTests.cs +++ b/test/AutoRest.TestServer.Tests/ModelShapeTests.cs @@ -112,7 +112,7 @@ public void NotRequiredNullablePropertiesOmitedByDefault() { var inputModel = CreateInputModel(); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.False(element.TryGetProperty("NonRequiredNullableInt", out _)); Assert.False(element.TryGetProperty("NonRequiredNullableString", out _)); Assert.False(element.TryGetProperty("NonRequiredNullableIntList", out _)); @@ -126,7 +126,7 @@ public void NotRequiredNullableListsSerializedAsNull() inputModel.NonRequiredNullableIntList = null; inputModel.NonRequiredNullableStringList = null; - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("NonRequiredNullableIntList").ValueKind); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("NonRequiredNullableStringList").ValueKind); } @@ -138,7 +138,7 @@ public void NotRequiredNullableListsSerializedEmptyWhenCleared() inputModel.NonRequiredNullableIntList.Clear(); inputModel.NonRequiredNullableStringList.Clear(); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(JsonValueKind.Array, element.GetProperty("NonRequiredNullableIntList").ValueKind); Assert.AreEqual(JsonValueKind.Array, element.GetProperty("NonRequiredNullableStringList").ValueKind); } @@ -150,7 +150,7 @@ public void NotRequiredNullablePropertiesSerializeWhenSet() inputModel.NonRequiredNullableInt = 1; inputModel.NonRequiredNullableString = "2"; - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(1, element.GetProperty("NonRequiredNullableInt").GetInt32()); Assert.AreEqual("2", element.GetProperty("NonRequiredNullableString").GetString()); } @@ -221,7 +221,7 @@ public void NullablePropertiesSerializedAsNulls() null ); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("RequiredNullableString").ValueKind); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("RequiredNullableInt").ValueKind); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("RequiredNullableStringList").ValueKind); @@ -247,7 +247,7 @@ public void NullablePropertiesSerializedAsEmptyLists() ); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(JsonValueKind.Array, element.GetProperty("RequiredNullableStringList").ValueKind); Assert.AreEqual(0, element.GetProperty("RequiredNullableStringList").GetArrayLength()); Assert.AreEqual(JsonValueKind.Array, element.GetProperty("RequiredNullableIntList").ValueKind); @@ -295,7 +295,7 @@ public void InputModelDoesntSerializeOptionalCollections() _ = inputModel.NonRequiredIntList.Remove(1); _ = inputModel.NonRequiredStringList.Remove("s"); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.False(element.TryGetProperty("NonRequiredStringList", out _)); Assert.False(element.TryGetProperty("NonRequiredIntList", out _)); @@ -309,7 +309,7 @@ public void InputModelSerializeOptionalCollectionAfterMutation() inputModel.NonRequiredIntList.Add(1); inputModel.NonRequiredStringList.Add("1"); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual("[1]", element.GetProperty("NonRequiredIntList").ToString()); Assert.AreEqual("[\"1\"]", element.GetProperty("NonRequiredStringList").ToString()); @@ -325,7 +325,7 @@ public void InputModelSerializeOptionalEmptyCollectionAfterMutation() inputModel.NonRequiredStringList.Add("1"); inputModel.NonRequiredStringList.Clear(); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual("[]", element.GetProperty("NonRequiredIntList").ToString()); Assert.AreEqual("[]", element.GetProperty("NonRequiredStringList").ToString()); @@ -341,7 +341,7 @@ public void InputModelDoesntSerializeOptionalCollectionAfterReset() inputModel.NonRequiredStringList.Add("1"); (inputModel.NonRequiredStringList as ChangeTrackingList).Reset(); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.False(element.TryGetProperty("NonRequiredStringList", out _)); Assert.False(element.TryGetProperty("NonRequiredIntList", out _)); @@ -358,7 +358,7 @@ public void RequiredNullableCollectionsSerializeAsNull() inputModel.RequiredNullableIntList = null; inputModel.RequiredNullableStringList = null; - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("RequiredNullableIntList").ValueKind); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("RequiredNullableStringList").ValueKind); @@ -437,9 +437,9 @@ public void ErrorModelsAreInternalWithDeserializers() [Test] public void ReadOnlyPropertyTypesOfMixedModelIsOutputOnly() { - Assert.True(typeof(ReadonlyModel).IsPublic); - Assert.False(typeof(IUtf8JsonSerializable).IsAssignableFrom(typeof(ReadonlyModel))); - Assert.NotNull(typeof(ReadonlyModel).GetMethod("DeserializeReadonlyModel", BindingFlags.Static | BindingFlags.NonPublic)); + Assert.IsTrue(typeof(ReadonlyModel).IsPublic); + Assert.IsTrue(typeof(IUtf8JsonSerializable).IsAssignableFrom(typeof(ReadonlyModel))); + Assert.IsNotNull(typeof(ReadonlyModel).GetMethod("DeserializeReadonlyModel", BindingFlags.Static | BindingFlags.NonPublic)); } [Test] @@ -456,9 +456,9 @@ public void ReadOnlyPropertiesAreReadOnly() [Test] public void ModelsFlattenedIntoParametersAreInternal() { - Assert.False(typeof(ParametersModel).IsPublic); - Assert.False(typeof(IUtf8JsonSerializable).IsAssignableFrom(typeof(ReadonlyModel))); - Assert.Null(typeof(ReadonlyModel).GetMethod("DeserializeParametersModel", BindingFlags.Static | BindingFlags.NonPublic)); + Assert.IsFalse(typeof(ParametersModel).IsPublic); + Assert.IsTrue(typeof(IUtf8JsonSerializable).IsAssignableFrom(typeof(ReadonlyModel))); + Assert.IsNull(typeof(ReadonlyModel).GetMethod("DeserializeParametersModel", BindingFlags.Static | BindingFlags.NonPublic)); } @@ -499,19 +499,19 @@ public void ModelWithCustomizedNullableJsonElementPropertyDeserializesValue() [Test] public void ModelWithCustomizedNullableJsonElementPropertySerializesNull() { - JsonAsserts.AssertSerialization("{\"ModelProperty\":null}", new ModelWithNullableObjectProperty() { ModelProperty = JsonDocument.Parse("null").RootElement }); + JsonAsserts.AssertWireSerialization("{\"ModelProperty\":null}", new ModelWithNullableObjectProperty() { ModelProperty = JsonDocument.Parse("null").RootElement }); } [Test] public void ModelWithCustomizedNullableJsonElementPropertySerializesUndefined() { - JsonAsserts.AssertSerialization("{}", new ModelWithNullableObjectProperty() { ModelProperty = default }); + JsonAsserts.AssertWireSerialization("{}", new ModelWithNullableObjectProperty() { ModelProperty = default }); } [Test] public void ModelWithCustomizedNullableJsonElementPropertySerializesValue() { - JsonAsserts.AssertSerialization("{\"ModelProperty\":1}", new ModelWithNullableObjectProperty() { ModelProperty = JsonDocument.Parse("1").RootElement }); + JsonAsserts.AssertWireSerialization("{\"ModelProperty\":1}", new ModelWithNullableObjectProperty() { ModelProperty = JsonDocument.Parse("1").RootElement }); } [Test] @@ -519,7 +519,12 @@ public void ModelFactory_DeclaresOnlyStaticMethodsForReadonlyTypes() { TypeAsserts.TypeIsStatic(typeof(ModelShapesModelFactory)); TypeAsserts.TypeOnlyDeclaresThesePublicMethods(typeof(ModelShapesModelFactory), - nameof(MixedModel), nameof(MixedModelWithReadonlyProperty), nameof(OutputModel), nameof(ReadonlyModel)); + nameof(InputModel), + nameof(MixedModel), + nameof(OutputModel), + nameof(MixedModelWithReadonlyProperty), + nameof(OutputModel), + nameof(ReadonlyModel)); } [Test] @@ -534,7 +539,7 @@ public void ModelFactory_InstantiatesReadonlyModel() { const string stringValue = "stringValue"; - var expectedModel = new ReadonlyModel(stringValue); + var expectedModel = new ReadonlyModel(stringValue, new Dictionary()); var actualModel = ModelShapesModelFactory.ReadonlyModel(stringValue); Assert.AreEqual(expectedModel.Name, actualModel.Name); @@ -544,10 +549,10 @@ public void ModelFactory_InstantiatesReadonlyModel() public void ModelFactory_InstantiatesMixedModelWithReadonlyProperty() { const string stringValue = "stringValue"; - var readonlyModel = new ReadonlyModel(stringValue); + var readonlyModel = new ReadonlyModel(stringValue, new Dictionary()); var readonlyModelList = new List { readonlyModel }; - var expectedModel = new MixedModelWithReadonlyProperty(readonlyModel, readonlyModelList.ToList()); + var expectedModel = new MixedModelWithReadonlyProperty(readonlyModel, readonlyModelList.ToList(), new Dictionary()); var actualModel = ModelShapesModelFactory.MixedModelWithReadonlyProperty(readonlyModel, readonlyModelList); Assert.AreEqual(expectedModel.ReadonlyProperty, actualModel.ReadonlyProperty); diff --git a/test/AutoRest.TestServer.Tests/ModelWithConverterUsageTests.cs b/test/AutoRest.TestServer.Tests/ModelWithConverterUsageTests.cs index bcd54ed1ae8..4e633ccdfa6 100644 --- a/test/AutoRest.TestServer.Tests/ModelWithConverterUsageTests.cs +++ b/test/AutoRest.TestServer.Tests/ModelWithConverterUsageTests.cs @@ -2,9 +2,9 @@ // Licensed under the MIT License. using System; -using NUnit.Framework; -using ModelWithConverterUsage.Models; using System.Text.Json; +using ModelWithConverterUsage.Models; +using NUnit.Framework; namespace AutoRest.TestServer.Tests { @@ -16,7 +16,10 @@ public void SerializeModelClass() var model = new ModelClass(EnumProperty.A) { StringProperty = "test_str", - ObjProperty = new Product("str") + ObjProperty = new Product() + { + ConstProperty = "str" + } }; var jsonAsString = JsonSerializer.Serialize(model); @@ -55,7 +58,10 @@ public void DeserializeModelStruct() [Test] public void SerializeProductModel() { - var model = new Product("test_str"); + var model = new Product() + { + ConstProperty = "test_str" + }; var jsonAsString = JsonSerializer.Serialize(model); Assert.AreEqual("{\"ConstProperty\":\"test_str\"}", jsonAsString); @@ -86,14 +92,16 @@ public void SerializeInputModel() public void DeserializeInputModel() { string jsonString = @"{""Input_Model_Property"": ""test_str""}"; - Assert.That(() => JsonSerializer.Deserialize(jsonString), Throws.InstanceOf()); + var model = JsonSerializer.Deserialize(jsonString); + Assert.AreEqual("test_str", model.InputModelProperty); } [Test] public void SerializeOutputModel() { - var model = new OutputModel("test_str"); - Assert.That(() => JsonSerializer.Serialize(model), Throws.InstanceOf()); + var model = ModelWithConverterUsageModelFactory.OutputModel("test_str"); + var json = JsonSerializer.Serialize(model); + Assert.AreEqual(@"{""Output_Model_Property"":""test_str""}", json); } [Test] diff --git a/test/AutoRest.TestServer.Tests/ModelsTypeSpecTests.cs b/test/AutoRest.TestServer.Tests/ModelsTypeSpecTests.cs index 2b7e045370d..a5fdc013a77 100644 --- a/test/AutoRest.TestServer.Tests/ModelsTypeSpecTests.cs +++ b/test/AutoRest.TestServer.Tests/ModelsTypeSpecTests.cs @@ -2,14 +2,15 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text.Json; using AutoRest.TestServer.Tests.Infrastructure; using Azure.Core; -using NUnit.Framework; using ModelsTypeSpec.Models; +using NUnit.Framework; namespace AutoRest.TestServer.Tests { @@ -96,7 +97,7 @@ public void NotRequiredNullablePropertiesOmitedByDefault() { var inputModel = CreateInputModel(); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.False(element.TryGetProperty("nonRequiredNullableInt", out _)); Assert.False(element.TryGetProperty("nonRequiredNullableString", out _)); Assert.False(element.TryGetProperty("nonRequiredNullableIntList", out _)); @@ -110,7 +111,7 @@ public void NotRequiredNullableListsSerializedAsNull() inputModel.NonRequiredNullableIntList = null; inputModel.NonRequiredNullableStringList = null; - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("nonRequiredNullableIntList").ValueKind); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("nonRequiredNullableStringList").ValueKind); } @@ -122,7 +123,7 @@ public void NotRequiredNullableListsSerializedEmptyWhenCleared() inputModel.NonRequiredNullableIntList.Clear(); inputModel.NonRequiredNullableStringList.Clear(); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(JsonValueKind.Array, element.GetProperty("nonRequiredNullableIntList").ValueKind); Assert.AreEqual(JsonValueKind.Array, element.GetProperty("nonRequiredNullableStringList").ValueKind); } @@ -134,7 +135,7 @@ public void NotRequiredNullablePropertiesSerializeWhenSet() inputModel.NonRequiredNullableInt = 1; inputModel.NonRequiredNullableString = "2"; - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(1, element.GetProperty("nonRequiredNullableInt").GetInt32()); Assert.AreEqual("2", element.GetProperty("nonRequiredNullableString").GetString()); } @@ -211,7 +212,7 @@ public void NullablePropertiesSerializedAsNulls() null ); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("requiredNullableString").ValueKind); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("requiredNullableInt").ValueKind); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("requiredNullableStringList").ValueKind); @@ -239,7 +240,7 @@ public void NullablePropertiesSerializedAsEmptyLists() Array.Empty() ); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(JsonValueKind.Array, element.GetProperty("requiredNullableStringList").ValueKind); Assert.AreEqual(0, element.GetProperty("requiredNullableStringList").GetArrayLength()); Assert.AreEqual(JsonValueKind.Array, element.GetProperty("requiredNullableIntList").ValueKind); @@ -287,7 +288,7 @@ public void InputModelDoesntSerializeOptionalCollections() _ = inputModel.NonRequiredIntList.Remove(1); _ = inputModel.NonRequiredStringList.Remove("s"); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.False(element.TryGetProperty("nonRequiredStringList", out _)); Assert.False(element.TryGetProperty("nonRequiredIntList", out _)); @@ -301,7 +302,7 @@ public void InputModelSerializeOptionalCollectionAfterMutation() inputModel.NonRequiredIntList.Add(1); inputModel.NonRequiredStringList.Add("1"); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual("[1]", element.GetProperty("nonRequiredIntList").ToString()); Assert.AreEqual("[\"1\"]", element.GetProperty("nonRequiredStringList").ToString()); @@ -317,7 +318,7 @@ public void InputModelSerializeOptionalEmptyCollectionAfterMutation() inputModel.NonRequiredStringList.Add("1"); inputModel.NonRequiredStringList.Clear(); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual("[]", element.GetProperty("nonRequiredIntList").ToString()); Assert.AreEqual("[]", element.GetProperty("nonRequiredStringList").ToString()); @@ -333,7 +334,7 @@ public void InputModelDoesntSerializeOptionalCollectionAfterReset() inputModel.NonRequiredStringList.Add("1"); (inputModel.NonRequiredStringList as ChangeTrackingList).Reset(); - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.False(element.TryGetProperty("nonRequiredStringList", out _)); Assert.False(element.TryGetProperty("nonRequiredIntList", out _)); @@ -350,7 +351,7 @@ public void RequiredNullableCollectionsSerializeAsNull() inputModel.RequiredNullableIntList = null; inputModel.RequiredNullableStringList = null; - var element = JsonAsserts.AssertSerializes(inputModel); + var element = JsonAsserts.AssertWireSerializes(inputModel); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("requiredNullableIntList").ValueKind); Assert.AreEqual(JsonValueKind.Null, element.GetProperty("requiredNullableStringList").ValueKind); @@ -440,5 +441,227 @@ public void OptionalPropertyWithNullIsAccepted() var model = RoundTripModel.DeserializeRoundTripModel(JsonDocument.Parse("{\"RequiredReadonlyInt\":1, \"NonRequiredReadonlyInt\": 2,\"NonRequiredInt\": null}").RootElement); Assert.Null(model.NonRequiredInt); } + + [TestCase("J")] + [TestCase("W")] + public void ValidateWriteInputModel(string format) + { + var options = format switch + { + "W" => new ModelReaderWriterOptions("W"), + "J" => ModelReaderWriterOptions.Json, + _ => throw new NotSupportedException() + }; + var baseModel = new BaseModel(); + var modelList = new[] { + new CollectionItem(new Dictionary() + { + ["key"] = new RecordItem(Array.Empty()) + }) + }; + var input = new InputModel("requiredString", 314, null, null, baseModel, baseModel, new[] { 1, 2, 3 }, new[] { "a", "b" }, modelList, new Dictionary(), new float?[] { null }, new bool?[] { null, true }, Array.Empty(), new[] { "c", null }, new[] { 1, 2 }); + + var result = ModelReaderWriter.Write(input, options); + using var document = JsonDocument.Parse(result); + var root = document.RootElement; + + foreach (var property in document.RootElement.EnumerateObject()) + { + if (property.NameEquals("requiredString")) + { + Assert.AreEqual("requiredString", property.Value.GetString()); + continue; + } + + if (property.NameEquals("requiredInt")) + { + Assert.AreEqual(314, property.Value.GetInt32()); + continue; + } + + if (property.NameEquals("requiredNullableInt")) + { + Assert.AreEqual(JsonValueKind.Null, property.Value.ValueKind); + continue; + } + + if (property.NameEquals("requiredNullableString")) + { + Assert.AreEqual(JsonValueKind.Null, property.Value.ValueKind); + continue; + } + + if (property.NameEquals("requiredModel")) + { + Assert.AreEqual(0, property.Value.EnumerateObject().Count()); // this model does not have any properties + continue; + } + + if (property.NameEquals("requiredModel2")) + { + Assert.AreEqual(0, property.Value.EnumerateObject().Count()); // this model does not have any properties + continue; + } + + if (property.NameEquals("requiredIntList")) + { + CollectionAssert.AreEqual(new[] { 1, 2, 3 }, property.Value.EnumerateArray().Select(e => e.GetInt32())); + continue; + } + + if (property.NameEquals("requiredStringList")) + { + CollectionAssert.AreEqual(new[] { "a", "b" }, property.Value.EnumerateArray().Select(e => e.GetString())); + continue; + } + + if (property.NameEquals("requiredModelList")) + { + var modelArray = property.Value.EnumerateArray().ToArray(); + Assert.AreEqual(1, modelArray.Length); + foreach (var p in modelArray[0].EnumerateObject()) + { + if (p.NameEquals("requiredModelRecord")) + { + Assert.AreEqual(0, p.Value.GetProperty("key").GetProperty("requiredList").EnumerateArray().Count()); + continue; + } + + Assert.Fail($"We should not have other properties here, but got {p.Name}"); + } + continue; + } + + if (property.NameEquals("requiredCollectionWithNullableFloatElement")) + { + CollectionAssert.AreEqual(new float?[] { null }, property.Value.EnumerateArray().Select(e => e.ValueKind == JsonValueKind.Null ? (float?)null : e.GetSingle())); + continue; + } + + if (property.NameEquals("requiredCollectionWithNullableBooleanElement")) + { + CollectionAssert.AreEqual(new bool?[] { null, true }, property.Value.EnumerateArray().Select(e => e.ValueKind == JsonValueKind.Null ? (bool?)null : e.GetBoolean())); + continue; + } + + if (property.NameEquals("requiredNullableModelList")) + { + Assert.AreEqual(0, property.Value.EnumerateArray().Count()); + continue; + } + + if (property.NameEquals("requiredNullableStringList")) + { + CollectionAssert.AreEqual(new[] { "c", null }, property.Value.EnumerateArray().Select(e => e.GetString())); + continue; + } + + if (property.NameEquals("requiredNullableIntList")) + { + CollectionAssert.AreEqual(new[] { 1, 2 }, property.Value.EnumerateArray().Select(e => e.GetInt32())); + continue; + } + + if (property.NameEquals("requiredModelRecord")) + { + Assert.AreEqual(0, property.Value.EnumerateObject().Count()); // this record does not have any entry + continue; + } + + Assert.Fail($"We should not have other properties here, but got {property.Name}"); + } + + } + + [TestCase("J")] + [TestCase("W")] + public void ValidateReadInputModel(string format) + { + var options = format switch + { + "W" => new ModelReaderWriterOptions("W"), + "J" => ModelReaderWriterOptions.Json, + _ => throw new NotSupportedException() + }; + var json = @"{""requiredString"": ""foo"", ""requiredCollectionWithNullableBooleanElement"": [false, null], ""extraProperty"": ""test""}"; + var binary = BinaryData.FromString(json); + var model = ModelReaderWriter.Read(binary, options); + + Assert.AreEqual("foo", model.RequiredString); + Assert.AreEqual(default(int), model.RequiredInt); + CollectionAssert.AreEqual(new bool?[] { false, null }, model.RequiredCollectionWithNullableBooleanElement); + if (format == "J") + { + // get the private _serializedAdditionalRawData field + var field = typeof(InputModel).GetField("_serializedAdditionalRawData", BindingFlags.Instance | BindingFlags.NonPublic); + var rawData = (IDictionary)field.GetValue(model); + Assert.AreEqual(1, rawData.Count); + Assert.AreEqual("\"test\"", rawData["extraProperty"].ToString()); + } + } + + [TestCase("J")] + [TestCase("W")] + public void ValidateWriteOutputModel(string format) + { + var options = format switch + { + "W" => new ModelReaderWriterOptions("W"), + "J" => ModelReaderWriterOptions.Json, + _ => throw new NotSupportedException() + }; + var output = ModelsTypeSpecModelFactory.OutputModel(requiredString: "requiredString", requiredInt: 314, optionalNullableList: new[] + { + new CollectionItem(new Dictionary() + { + ["key"] = new RecordItem(Array.Empty()) + }) + }); + + var result = ModelReaderWriter.Write(output, options); + using var document = JsonDocument.Parse(result); + + foreach (var property in document.RootElement.EnumerateObject()) + { + if (property.NameEquals("requiredString")) + { + Assert.AreEqual("requiredString", property.Value.GetString()); + continue; + } + + if (property.NameEquals("requiredInt")) + { + Assert.AreEqual(314, property.Value.GetInt32()); + continue; + } + + if (property.NameEquals("optionalNullableList")) + { + var array = property.Value.EnumerateArray().ToArray(); + Assert.AreEqual(1, array.Length); + + foreach (var p in array[0].EnumerateObject()) + { + if (p.NameEquals("requiredModelRecord")) + { + foreach (var pp in p.Value.GetProperty("key").EnumerateObject()) + { + if (pp.NameEquals("requiredList")) + { + Assert.AreEqual(0, pp.Value.EnumerateArray().Count()); + continue; + } + Assert.Fail($"We should not have other properties here, but got {pp.Name}"); + } + continue; + } + Assert.Fail($"We should not have other properties here, but got {p.Name}"); + } + } + + // TODO -- remove the comment until the issue is fixed + //Assert.Fail($"We should not have other properties here, but got {property.Name}"); + } + } } } diff --git a/test/AutoRest.TestServer.Tests/TypeSchemaMappingTest.cs b/test/AutoRest.TestServer.Tests/TypeSchemaMappingTest.cs index cb946f00437..448a5c399ac 100644 --- a/test/AutoRest.TestServer.Tests/TypeSchemaMappingTest.cs +++ b/test/AutoRest.TestServer.Tests/TypeSchemaMappingTest.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Linq; using System.Reflection; using System.Text.Json; @@ -109,9 +110,13 @@ public void NullableParamsAsNull() public void ObjectTypePropertiesSerializedAsValues() { DateTime date = DateTime.UtcNow; - var inputModel = new RenamedThirdModel(new ETag("Id"), date); + var inputModel = new RenamedThirdModel() + { + CustomizedETagProperty = new ETag("Id"), + CustomizedCreatedAtProperty = date + }; - JsonAsserts.AssertSerialization( + JsonAsserts.AssertWireSerialization( @"{""ETag"":""Id"",""CreatedAt"":" + JsonSerializer.Serialize(date) + "}", inputModel); } @@ -130,7 +135,7 @@ public void ObjectTypePropertiesDeserializedAsValues() public void ObjectTypePropertiesSerializedAsNull() { var inputModel = new RenamedThirdModel(); - JsonAsserts.AssertSerialization( + JsonAsserts.AssertWireSerialization( @"{""ETag"":"""",""CreatedAt"":" + JsonSerializer.Serialize(new DateTime()) + "}", inputModel); } @@ -195,12 +200,12 @@ public void TypesWithCustomUsageGeneratedCorrectly(Type type) Assert.NotNull(type.GetMethod("Deserialize" + type.Name, BindingFlags.Static | BindingFlags.NonPublic, null, - new[] { typeof(JsonElement) }, + new[] { typeof(JsonElement), typeof(ModelReaderWriterOptions) }, null)); Assert.NotNull(type.GetMethod("Deserialize" + type.Name, BindingFlags.Static | BindingFlags.NonPublic, null, - new[] { typeof(XElement) }, + new[] { typeof(XElement), typeof(ModelReaderWriterOptions) }, null)); } @@ -230,7 +235,7 @@ public void UriPropertySerializedCorrectly() var inputModel = new ModelWithUriProperty(); inputModel.Uri = new Uri("http://localhost"); - JsonAsserts.AssertSerialization( + JsonAsserts.AssertWireSerialization( @"{""Uri"":""http://localhost/""}", inputModel); } diff --git a/test/AutoRest.TestServer.Tests/constantsModel.cs b/test/AutoRest.TestServer.Tests/constantsModel.cs index 5b72167855c..443ecf9d831 100644 --- a/test/AutoRest.TestServer.Tests/constantsModel.cs +++ b/test/AutoRest.TestServer.Tests/constantsModel.cs @@ -15,12 +15,9 @@ public void NoModelAsStringNoRequiredTwoValueDefault_IsInternal() } [Test] - public void NoModelAsStringNoRequiredTwoValueDefault_HasDefaultCtor() + public void NoModelAsStringNoRequiredTwoValueDefault_HasOneDefaultCtor() { - var constructor = typeof(NoModelAsStringNoRequiredTwoValueDefault) - .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) - .FirstOrDefault(ctor => ctor.GetParameters().Length == 0); - Assert.IsNotNull(constructor); + AssertHasDefaultCtor(typeof(NoModelAsStringNoRequiredTwoValueDefault)); } [Test] @@ -53,12 +50,9 @@ public void NoModelAsStringNoRequiredTwoValueNoDefault_IsInternal() } [Test] - public void NoModelAsStringNoRequiredTwoValueNoDefault_HasDefaultCtor() + public void NoModelAsStringNoRequiredTwoValueNoDefault_HasOneDefaultCtor() { - var constructor = typeof(NoModelAsStringNoRequiredTwoValueNoDefault) - .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) - .FirstOrDefault(ctor => ctor.GetParameters().Length == 0); - Assert.IsNotNull(constructor); + AssertHasDefaultCtor(typeof(NoModelAsStringNoRequiredTwoValueNoDefault)); } [Test] @@ -91,12 +85,9 @@ public void NoModelAsStringNoRequiredOneValueNoDefault_IsInternal() } [Test] - public void NoModelAsStringNoRequiredOneValueNoDefault_HasDefaultCtor() + public void NoModelAsStringNoRequiredOneValueNoDefault_HasOneDefaultCtor() { - var constructor = typeof(NoModelAsStringNoRequiredOneValueNoDefault) - .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) - .FirstOrDefault(ctor => ctor.GetParameters().Length == 0); - Assert.IsNotNull(constructor); + AssertHasDefaultCtor(typeof(NoModelAsStringNoRequiredOneValueNoDefault)); } [Test] @@ -118,12 +109,9 @@ public void NoModelAsStringNoRequiredOneValueDefault_IsInternal() } [Test] - public void NoModelAsStringNoRequiredOneValueDefault_HasDefaultCtor() + public void NoModelAsStringNoRequiredOneValueDefault_HasOneDefaultCtor() { - var constructor = typeof(NoModelAsStringNoRequiredOneValueDefault) - .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) - .FirstOrDefault(ctor => ctor.GetParameters().Length == 0); - Assert.IsNotNull(constructor); + AssertHasDefaultCtor(typeof(NoModelAsStringNoRequiredOneValueDefault)); } [Test] @@ -148,9 +136,10 @@ public void NoModelAsStringRequiredTwoValueNoDefault_IsInternal() public void NoModelAsStringRequiredTwoValueNoDefault_HasOneCtorWithRequiredParam() { var constructors = typeof(NoModelAsStringRequiredTwoValueNoDefault).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic); - Assert.AreEqual(1, constructors.Length); - Assert.AreEqual(1, constructors[0].GetParameters().Length); - Assert.AreEqual(typeof(NoModelAsStringRequiredTwoValueNoDefaultEnum), constructors[0].GetParameters()[0].ParameterType); + Assert.AreEqual(3, constructors.Length); + var ctor = constructors.SingleOrDefault(ctor => ctor.GetParameters().Length == 1); + Assert.IsNotNull(ctor); + Assert.AreEqual(typeof(NoModelAsStringRequiredTwoValueNoDefaultEnum), ctor.GetParameters()[0].ParameterType); } [Test] @@ -186,9 +175,10 @@ public void NoModelAsStringRequiredTwoValueDefault() public void NoModelAsStringRequiredTwoValueDefault_HasOneCtorWithRequiredParam() { var constructors = typeof(NoModelAsStringRequiredTwoValueDefault).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic); - Assert.AreEqual(1, constructors.Length); - Assert.AreEqual(1, constructors[0].GetParameters().Length); - Assert.AreEqual(typeof(NoModelAsStringRequiredTwoValueDefaultEnum), constructors[0].GetParameters()[0].ParameterType); + Assert.AreEqual(3, constructors.Length); + var ctor = constructors.SingleOrDefault(ctor => ctor.GetParameters().Length == 1); + Assert.IsNotNull(ctor); + Assert.AreEqual(typeof(NoModelAsStringRequiredTwoValueDefaultEnum), ctor.GetParameters()[0].ParameterType); } [Test] @@ -228,12 +218,9 @@ public void NoModelAsStringRequiredOneValueNoDefault() } [Test] - public void NoModelAsStringRequiredOneValueNoDefault_HasDefaultCtor() + public void NoModelAsStringRequiredOneValueNoDefault_HasOneDefaultCtor() { - var constructor = typeof(NoModelAsStringRequiredOneValueNoDefault) - .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) - .FirstOrDefault(ctor => ctor.GetParameters().Length == 0); - Assert.IsNotNull(constructor); + AssertHasDefaultCtor(typeof(NoModelAsStringRequiredOneValueNoDefault)); } [Test] @@ -262,12 +249,9 @@ public void NoModelAsStringRequiredOneValueDefault() } [Test] - public void NoModelAsStringRequiredOneValueDefault_HasDefaultCtor() + public void NoModelAsStringRequiredOneValueDefault_HasOneDefaultCtor() { - var constructor = typeof(NoModelAsStringRequiredOneValueDefault) - .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) - .FirstOrDefault(ctor => ctor.GetParameters().Length == 0); - Assert.IsNotNull(constructor); + AssertHasDefaultCtor(typeof(NoModelAsStringRequiredOneValueDefault)); } [Test] @@ -296,12 +280,9 @@ public void ModelAsStringNoRequiredTwoValueNoDefault_IsInternal() } [Test] - public void ModelAsStringNoRequiredTwoValueNoDefault_HasDefaultCtor() + public void ModelAsStringNoRequiredTwoValueNoDefault_HasOneDefaultCtor() { - var constructor = typeof(ModelAsStringNoRequiredTwoValueNoDefault) - .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) - .FirstOrDefault(ctor => ctor.GetParameters().Length == 0); - Assert.IsNotNull(constructor); + AssertHasDefaultCtor(typeof(ModelAsStringNoRequiredTwoValueNoDefault)); } [Test] @@ -334,12 +315,9 @@ public void ModelAsStringNoRequiredTwoValueDefault_IsInternal() } [Test] - public void ModelAsStringNoRequiredTwoValueDefault_HasDefaultCtor() + public void ModelAsStringNoRequiredTwoValueDefault_HasOneDefaultCtor() { - var constructor = typeof(ModelAsStringNoRequiredTwoValueDefault) - .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) - .FirstOrDefault(ctor => ctor.GetParameters().Length == 0); - Assert.IsNotNull(constructor); + AssertHasDefaultCtor(typeof(ModelAsStringNoRequiredTwoValueDefault)); } [Test] @@ -372,12 +350,17 @@ public void ModelAsStringNoRequiredOneValueDefault_IsInternal() } [Test] - public void ModelAsStringNoRequiredOneValueDefault_HasDefaultCtor() + public void ModelAsStringNoRequiredOneValueDefault_HasOneDefaultCtor() { - var constructor = typeof(ModelAsStringNoRequiredOneValueDefault) - .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) - .FirstOrDefault(ctor => ctor.GetParameters().Length == 0); - Assert.IsNotNull(constructor); + AssertHasDefaultCtor(typeof(ModelAsStringNoRequiredOneValueDefault)); + } + + private static void AssertHasDefaultCtor(Type type) + { + var constructors = type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic); + // when the model has default ctor, it should always have another ctor that takes an extra raw data parameter + Assert.AreEqual(2, constructors.Length); + Assert.IsTrue(constructors.Any(ctor => ctor.GetParameters().Length == 0)); } [Test] @@ -412,9 +395,10 @@ public void ModelAsStringRequiredTwoValueNoDefault_IsInternal() public void ModelAsStringRequiredTwoValueNoDefault_HasOneCtorWithRequiredParam() { var constructors = typeof(ModelAsStringRequiredTwoValueNoDefault).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic); - Assert.AreEqual(1, constructors.Length); - Assert.AreEqual(1, constructors[0].GetParameters().Length); - Assert.AreEqual(typeof(ModelAsStringRequiredTwoValueNoDefaultEnum), constructors[0].GetParameters()[0].ParameterType); + Assert.AreEqual(3, constructors.Length); + var ctor = constructors.SingleOrDefault(ctor => ctor.GetParameters().Length == 1); + Assert.IsNotNull(ctor); + Assert.AreEqual(typeof(ModelAsStringRequiredTwoValueNoDefaultEnum), ctor.GetParameters()[0].ParameterType); } [Test] @@ -450,10 +434,11 @@ public void ModelAsStringRequiredTwoValueDefault_IsInternal() public void ModelAsStringRequiredTwoValueDefault_HasOneCtorWithOptionalParam() { var constructors = typeof(ModelAsStringRequiredTwoValueDefault).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic); - Assert.AreEqual(1, constructors.Length); - Assert.AreEqual(1, constructors[0].GetParameters().Length); + Assert.AreEqual(3, constructors.Length); + var ctor = constructors.SingleOrDefault(ctor => ctor.GetParameters().Length == 1); + Assert.IsNotNull(ctor); /* eliminate the default value for the parameter property, so the type is not Nullable. */ - Assert.AreEqual(typeof(ModelAsStringRequiredTwoValueDefaultEnum), constructors[0].GetParameters()[0].ParameterType); + Assert.AreEqual(typeof(ModelAsStringRequiredTwoValueDefaultEnum), ctor.GetParameters()[0].ParameterType); } [Test] @@ -496,9 +481,10 @@ public void ModelAsStringRequiredOneValueNoDefault_IsInternal() public void ModelAsStringRequiredOneValueNoDefault_HasOneCtorWithRequiredParam() { var constructors = typeof(ModelAsStringRequiredOneValueNoDefault).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic); - Assert.AreEqual(1, constructors.Length); - Assert.AreEqual(1, constructors[0].GetParameters().Length); - Assert.AreEqual(typeof(ModelAsStringRequiredOneValueNoDefaultEnum), constructors[0].GetParameters()[0].ParameterType); + Assert.AreEqual(3, constructors.Length); + var ctor = constructors.SingleOrDefault(ctor => ctor.GetParameters().Length == 1); + Assert.IsNotNull(ctor); + Assert.AreEqual(typeof(ModelAsStringRequiredOneValueNoDefaultEnum), ctor.GetParameters()[0].ParameterType); } [Test] @@ -533,10 +519,11 @@ public void ModelAsStringRequiredOneValueDefault_IsInternal() public void ModelAsStringRequiredOneValueDefault_HasOneCtorWithOptionalParam() { var constructors = typeof(ModelAsStringRequiredOneValueDefault).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic); - Assert.AreEqual(1, constructors.Length); - Assert.AreEqual(1, constructors[0].GetParameters().Length); + Assert.AreEqual(3, constructors.Length); // one with required parameter, one with required parameter and extra raw data, and a default ctor + var ctor = constructors.SingleOrDefault(ctor => ctor.GetParameters().Length == 1); + Assert.IsNotNull(ctor); /* eliminate the default value for the parameter property, so the type is not Nullable. */ - Assert.AreEqual(typeof(ModelAsStringRequiredOneValueDefaultEnum), constructors[0].GetParameters()[0].ParameterType); + Assert.AreEqual(typeof(ModelAsStringRequiredOneValueDefaultEnum), ctor.GetParameters()[0].ParameterType); } [Test] diff --git a/test/AutoRest.TestServer.Tests/multiple-inheritance.cs b/test/AutoRest.TestServer.Tests/multiple-inheritance.cs index e5732e71fa1..db085111d3e 100644 --- a/test/AutoRest.TestServer.Tests/multiple-inheritance.cs +++ b/test/AutoRest.TestServer.Tests/multiple-inheritance.cs @@ -24,7 +24,12 @@ public Task MultipleInheritanceCatGet() => Test(async (host, pipeline) => [Test] public Task MultipleInheritanceCatPut() => Test(async (host, pipeline) => { - var value = new Cat("Boots", false, true, false); + var value = new Cat("Boots") + { + LikesMilk = false, + Meows = true, + Hisses = false + }; var result = await new MultipleInheritanceServiceClient(ClientDiagnostics, pipeline, host).RestClient.PutCatAsync(value); Assert.AreEqual(200, result.GetRawResponse().Status); Assert.AreEqual("Cat was correct!", result.Value); @@ -41,7 +46,11 @@ public Task MultipleInheritanceFelineGet() => Test(async (host, pipeline) => [Test] public Task MultipleInheritanceFelinePut() => Test(async (host, pipeline) => { - var value = new Feline(false, true); + var value = new Feline() + { + Meows = false, + Hisses = true + }; var result = await new MultipleInheritanceServiceClient(ClientDiagnostics, pipeline, host).RestClient.PutFelineAsync(value); Assert.AreEqual(200, result.GetRawResponse().Status); Assert.AreEqual("Feline was correct!", result.Value); @@ -58,7 +67,10 @@ public Task MultipleInheritanceHorseGet() => Test(async (host, pipeline) => [Test] public Task MultipleInheritanceHorsePut() => Test(async (host, pipeline) => { - var value = new Horse("General", false); + var value = new Horse("General") + { + IsAShowHorse = false + }; var result = await new MultipleInheritanceServiceClient(ClientDiagnostics, pipeline, host).RestClient.PutHorseAsync(value); Assert.AreEqual(200, result.GetRawResponse().Status); Assert.AreEqual("Horse was correct!", result.Value); @@ -78,7 +90,13 @@ public Task MultipleInheritanceKittenGet() => Test(async (host, pipeline) => [Test] public Task MultipleInheritanceKittenPut() => Test(async (host, pipeline) => { - var value = new Kitten("Kitty", false, true, false, true); + var value = new Kitten("Kitty") + { + LikesMilk = false, + Meows = true, + Hisses = false, + EatsMiceYet = true + }; var result = await new MultipleInheritanceServiceClient(ClientDiagnostics, pipeline, host).RestClient.PutKittenAsync(value); Assert.AreEqual(200, result.GetRawResponse().Status); Assert.AreEqual("Kitten was correct!", result.Value); diff --git a/test/AutoRest.TestServer.Tests/xml-service.cs b/test/AutoRest.TestServer.Tests/xml-service.cs index d0928ac8232..d74fb25248f 100644 --- a/test/AutoRest.TestServer.Tests/xml-service.cs +++ b/test/AutoRest.TestServer.Tests/xml-service.cs @@ -253,8 +253,8 @@ public Task PutWrappedXMLList() => TestStatus(async (host, pipeline) => { var root = new AppleBarrel() { - BadApples = {"Red Delicious"}, - GoodApples = {"Fuji", "Gala"} + BadApples = { "Red Delicious" }, + GoodApples = { "Fuji", "Gala" } }; return await new XmlClient(ClientDiagnostics, pipeline, host).PutWrappedListsAsync(root); @@ -266,8 +266,8 @@ public Task GetWrappedXMLList() => Test(async (host, pipeline) => var result = await new XmlClient(ClientDiagnostics, pipeline, host).GetWrappedListsAsync(); var value = result.Value; - CollectionAssert.AreEqual(new[] {"Red Delicious"}, value.BadApples); - CollectionAssert.AreEqual(new[] {"Fuji", "Gala"}, value.GoodApples); + CollectionAssert.AreEqual(new[] { "Red Delicious" }, value.BadApples); + CollectionAssert.AreEqual(new[] { "Fuji", "Gala" }, value.GoodApples); }); [Test] @@ -505,7 +505,7 @@ public Task StoragePutServicePropertiesXML() => TestStatus(async (host, pipeline { var properties = new StorageServiceProperties() { - Logging = new Logging("1.0", true, false, true, new RetentionPolicy(true, 7)), + Logging = new Logging("1.0", true, false, true, new RetentionPolicy(true) { Days = 7 }), HourMetrics = new Metrics(true) { Version = "1.0", diff --git a/test/AutoRest.TestServerLowLevel.Tests/LowLevel/Generation/ModelGenerationTestBase.cs b/test/AutoRest.TestServerLowLevel.Tests/LowLevel/Generation/ModelGenerationTestBase.cs index e1ed227a487..bbc8e62cdac 100644 --- a/test/AutoRest.TestServerLowLevel.Tests/LowLevel/Generation/ModelGenerationTestBase.cs +++ b/test/AutoRest.TestServerLowLevel.Tests/LowLevel/Generation/ModelGenerationTestBase.cs @@ -53,6 +53,7 @@ public void Initialize() publicDiscriminatorProperty: false, deserializeNullCollectionAsNullValue: false, useCoreDataFactoryReplacements: true, + useModelReaderWriter: true, modelFactoryForHlc: Array.Empty(), unreferencedTypesHandling: Configuration.UnreferencedTypesHandlingOption.RemoveOrInternalize, keepNonOverloadableProtocolSignature: false, diff --git a/test/CadlRanchProjects.Tests/type-dictionary.cs b/test/CadlRanchProjects.Tests/type-dictionary.cs index 87188a3c502..6287cf96e5a 100644 --- a/test/CadlRanchProjects.Tests/type-dictionary.cs +++ b/test/CadlRanchProjects.Tests/type-dictionary.cs @@ -196,8 +196,14 @@ public Task Dictionary_RecursiveModelValue_put() => Test(async (host) => firstModel.Children.Clear(); var response = await new DictionaryClient(host, null).GetRecursiveModelValueClient().PutAsync(new Dictionary() { - {"k1", firstModel }, - {"k2", new InnerModel("world", new Dictionary() {{"k2.1", new InnerModel("inner world")} }) } + ["k1"] = firstModel, + ["k2"] = new InnerModel("world") + { + Children = + { + ["k2.1"] = new InnerModel("inner world") + } + } }); Assert.AreEqual(204, response.Status); }); diff --git a/test/CadlRanchProjects.Tests/type-property-optionality.cs b/test/CadlRanchProjects.Tests/type-property-optionality.cs index 41d2afc53b0..86339c08b44 100644 --- a/test/CadlRanchProjects.Tests/type-property-optionality.cs +++ b/test/CadlRanchProjects.Tests/type-property-optionality.cs @@ -196,8 +196,14 @@ public Task Type_Property_Optional_CollectionsModel_getDefault() => Test(async ( public Task Type_Property_Optional_CollectionsModel_putAll() => Test(async (host) => { CollectionsModelProperty data = new(); - data.Property.Add(new StringProperty("hello")); - data.Property.Add(new StringProperty("world")); + data.Property.Add(new StringProperty() + { + Property = "hello" + }); + data.Property.Add(new StringProperty() + { + Property = "world" + }); Response response = await new OptionalClient(host, null).GetCollectionsModelClient().PutAllAsync(data.ToRequestContent()); Assert.AreEqual(204, response.Status); diff --git a/test/CadlRanchProjects/client/structure/default/src/Client.Structure.Service.Default.csproj b/test/CadlRanchProjects/client/structure/default/src/Client.Structure.Service.Default.csproj index 97f837929d5..ae773519292 100644 --- a/test/CadlRanchProjects/client/structure/default/src/Client.Structure.Service.Default.csproj +++ b/test/CadlRanchProjects/client/structure/default/src/Client.Structure.Service.Default.csproj @@ -14,6 +14,7 @@ + diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Configuration.json b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Configuration.json index 66bc96eb455..e6702623d8c 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Configuration.json +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Configuration.json @@ -5,5 +5,6 @@ "shared-source-folders": [ "../../../../../../../artifacts/bin/AutoRest.CSharp/Debug/net7.0/Generator.Shared", "../../../../../../../artifacts/bin/AutoRest.CSharp/Debug/net7.0/Azure.Core.Shared" - ] + ], + "use-model-reader-writer": true } diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsFloatAdditionalProperties.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsFloatAdditionalProperties.Serialization.cs index b015bbe3acd..805d1be0e45 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsFloatAdditionalProperties.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsFloatAdditionalProperties.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class ExtendsFloatAdditionalProperties : IUtf8JsonSerializable + public partial class ExtendsFloatAdditionalProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsFloatAdditionalProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id); @@ -27,8 +37,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static ExtendsFloatAdditionalProperties DeserializeExtendsFloatAdditionalProperties(JsonElement element) + ExtendsFloatAdditionalProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsFloatAdditionalProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeExtendsFloatAdditionalProperties(document.RootElement, options); + } + + internal static ExtendsFloatAdditionalProperties DeserializeExtendsFloatAdditionalProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -49,6 +73,37 @@ internal static ExtendsFloatAdditionalProperties DeserializeExtendsFloatAddition return new ExtendsFloatAdditionalProperties(id, additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ExtendsFloatAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + ExtendsFloatAdditionalProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeExtendsFloatAdditionalProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ExtendsFloatAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ExtendsFloatAdditionalProperties FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsFloatAdditionalProperties.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsFloatAdditionalProperties.cs index d9226539992..a5c8cbaa7e6 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsFloatAdditionalProperties.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsFloatAdditionalProperties.cs @@ -30,6 +30,11 @@ internal ExtendsFloatAdditionalProperties(float id, IDictionary a AdditionalProperties = additionalProperties; } + /// Initializes a new instance of for deserialization. + internal ExtendsFloatAdditionalProperties() + { + } + /// The id property. public float Id { get; set; } /// Additional Properties. diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsModelAdditionalProperties.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsModelAdditionalProperties.Serialization.cs index 2da79566d48..c4531229ec8 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsModelAdditionalProperties.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsModelAdditionalProperties.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class ExtendsModelAdditionalProperties : IUtf8JsonSerializable + public partial class ExtendsModelAdditionalProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsModelAdditionalProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); foreach (var item in AdditionalProperties) { @@ -25,8 +35,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static ExtendsModelAdditionalProperties DeserializeExtendsModelAdditionalProperties(JsonElement element) + ExtendsModelAdditionalProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsModelAdditionalProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeExtendsModelAdditionalProperties(document.RootElement, options); + } + + internal static ExtendsModelAdditionalProperties DeserializeExtendsModelAdditionalProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -41,6 +65,37 @@ internal static ExtendsModelAdditionalProperties DeserializeExtendsModelAddition return new ExtendsModelAdditionalProperties(additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ExtendsModelAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + ExtendsModelAdditionalProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeExtendsModelAdditionalProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ExtendsModelAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ExtendsModelAdditionalProperties FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsModelArrayAdditionalProperties.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsModelArrayAdditionalProperties.Serialization.cs index e6b80e41eb5..9b8c6e5eb82 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsModelArrayAdditionalProperties.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsModelArrayAdditionalProperties.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class ExtendsModelArrayAdditionalProperties : IUtf8JsonSerializable + public partial class ExtendsModelArrayAdditionalProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsModelArrayAdditionalProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); foreach (var item in AdditionalProperties) { @@ -30,8 +40,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static ExtendsModelArrayAdditionalProperties DeserializeExtendsModelArrayAdditionalProperties(JsonElement element) + ExtendsModelArrayAdditionalProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsModelArrayAdditionalProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeExtendsModelArrayAdditionalProperties(document.RootElement, options); + } + + internal static ExtendsModelArrayAdditionalProperties DeserializeExtendsModelArrayAdditionalProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -51,6 +75,37 @@ internal static ExtendsModelArrayAdditionalProperties DeserializeExtendsModelArr return new ExtendsModelArrayAdditionalProperties(additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ExtendsModelArrayAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + ExtendsModelArrayAdditionalProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeExtendsModelArrayAdditionalProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ExtendsModelArrayAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ExtendsModelArrayAdditionalProperties FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsStringAdditionalProperties.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsStringAdditionalProperties.Serialization.cs index c0bc593fae0..c987edda174 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsStringAdditionalProperties.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsStringAdditionalProperties.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class ExtendsStringAdditionalProperties : IUtf8JsonSerializable + public partial class ExtendsStringAdditionalProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsStringAdditionalProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); @@ -27,8 +37,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static ExtendsStringAdditionalProperties DeserializeExtendsStringAdditionalProperties(JsonElement element) + ExtendsStringAdditionalProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsStringAdditionalProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeExtendsStringAdditionalProperties(document.RootElement, options); + } + + internal static ExtendsStringAdditionalProperties DeserializeExtendsStringAdditionalProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -49,6 +73,37 @@ internal static ExtendsStringAdditionalProperties DeserializeExtendsStringAdditi return new ExtendsStringAdditionalProperties(name, additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ExtendsStringAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + ExtendsStringAdditionalProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeExtendsStringAdditionalProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ExtendsStringAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ExtendsStringAdditionalProperties FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsStringAdditionalProperties.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsStringAdditionalProperties.cs index fd449836fba..ed380223251 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsStringAdditionalProperties.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsStringAdditionalProperties.cs @@ -34,6 +34,11 @@ internal ExtendsStringAdditionalProperties(string name, IDictionary Initializes a new instance of for deserialization. + internal ExtendsStringAdditionalProperties() + { + } + /// The name property. public string Name { get; set; } /// Additional Properties. diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalProperties.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalProperties.Serialization.cs index 1a8105ce7ce..941d4bd2049 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalProperties.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalProperties.Serialization.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -13,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class ExtendsUnknownAdditionalProperties : IUtf8JsonSerializable + public partial class ExtendsUnknownAdditionalProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); @@ -35,8 +44,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static ExtendsUnknownAdditionalProperties DeserializeExtendsUnknownAdditionalProperties(JsonElement element) + ExtendsUnknownAdditionalProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeExtendsUnknownAdditionalProperties(document.RootElement, options); + } + + internal static ExtendsUnknownAdditionalProperties DeserializeExtendsUnknownAdditionalProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -57,6 +80,37 @@ internal static ExtendsUnknownAdditionalProperties DeserializeExtendsUnknownAddi return new ExtendsUnknownAdditionalProperties(name, additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + ExtendsUnknownAdditionalProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeExtendsUnknownAdditionalProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ExtendsUnknownAdditionalProperties FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalProperties.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalProperties.cs index 9b0fb8507e2..17c54caaaa1 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalProperties.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalProperties.cs @@ -34,6 +34,11 @@ internal ExtendsUnknownAdditionalProperties(string name, IDictionary Initializes a new instance of for deserialization. + internal ExtendsUnknownAdditionalProperties() + { + } + /// The name property. public string Name { get; set; } /// diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDerived.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDerived.Serialization.cs index 226c092e219..11c1c6e4d23 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDerived.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDerived.Serialization.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -13,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class ExtendsUnknownAdditionalPropertiesDerived : IUtf8JsonSerializable + public partial class ExtendsUnknownAdditionalPropertiesDerived : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDerived)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("index"u8); writer.WriteNumberValue(Index); @@ -42,8 +51,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static ExtendsUnknownAdditionalPropertiesDerived DeserializeExtendsUnknownAdditionalPropertiesDerived(JsonElement element) + ExtendsUnknownAdditionalPropertiesDerived IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDerived)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeExtendsUnknownAdditionalPropertiesDerived(document.RootElement, options); + } + + internal static ExtendsUnknownAdditionalPropertiesDerived DeserializeExtendsUnknownAdditionalPropertiesDerived(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -80,6 +103,37 @@ internal static ExtendsUnknownAdditionalPropertiesDerived DeserializeExtendsUnkn return new ExtendsUnknownAdditionalPropertiesDerived(name, additionalProperties, index, Optional.ToNullable(age)); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDerived)} does not support '{options.Format}' format."); + } + } + + ExtendsUnknownAdditionalPropertiesDerived IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeExtendsUnknownAdditionalPropertiesDerived(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDerived)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new ExtendsUnknownAdditionalPropertiesDerived FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDerived.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDerived.cs index 62e9481358f..e5ad4d84d78 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDerived.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDerived.cs @@ -36,6 +36,11 @@ internal ExtendsUnknownAdditionalPropertiesDerived(string name, IDictionary Initializes a new instance of for deserialization. + internal ExtendsUnknownAdditionalPropertiesDerived() + { + } + /// The index property. public int Index { get; set; } /// The age property. diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminated.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminated.Serialization.cs index 77c5a23624d..49a6e3be014 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminated.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminated.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; using Azure; using Azure.Core; namespace _Type.Property.AdditionalProperties.Models { - public partial class ExtendsUnknownAdditionalPropertiesDiscriminated : IUtf8JsonSerializable + [PersistableModelProxy(typeof(UnknownExtendsUnknownAdditionalPropertiesDiscriminated))] + public partial class ExtendsUnknownAdditionalPropertiesDiscriminated : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminated)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); @@ -35,8 +46,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static ExtendsUnknownAdditionalPropertiesDiscriminated DeserializeExtendsUnknownAdditionalPropertiesDiscriminated(JsonElement element) + ExtendsUnknownAdditionalPropertiesDiscriminated IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminated)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeExtendsUnknownAdditionalPropertiesDiscriminated(document.RootElement, options); + } + + internal static ExtendsUnknownAdditionalPropertiesDiscriminated DeserializeExtendsUnknownAdditionalPropertiesDiscriminated(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -51,6 +76,37 @@ internal static ExtendsUnknownAdditionalPropertiesDiscriminated DeserializeExten return UnknownExtendsUnknownAdditionalPropertiesDiscriminated.DeserializeUnknownExtendsUnknownAdditionalPropertiesDiscriminated(element); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminated)} does not support '{options.Format}' format."); + } + } + + ExtendsUnknownAdditionalPropertiesDiscriminated IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeExtendsUnknownAdditionalPropertiesDiscriminated(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminated)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ExtendsUnknownAdditionalPropertiesDiscriminated FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminated.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminated.cs index 131c588bb8d..466a3c5df66 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminated.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminated.cs @@ -40,6 +40,11 @@ internal ExtendsUnknownAdditionalPropertiesDiscriminated(string name, string kin AdditionalProperties = additionalProperties; } + /// Initializes a new instance of for deserialization. + internal ExtendsUnknownAdditionalPropertiesDiscriminated() + { + } + /// The name property. public string Name { get; set; } /// The discriminator. diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminatedDerived.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminatedDerived.Serialization.cs index 551483d1e57..dab86cad946 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminatedDerived.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminatedDerived.Serialization.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -13,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class ExtendsUnknownAdditionalPropertiesDiscriminatedDerived : IUtf8JsonSerializable + public partial class ExtendsUnknownAdditionalPropertiesDiscriminatedDerived : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminatedDerived)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("index"u8); writer.WriteNumberValue(Index); @@ -44,8 +53,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static ExtendsUnknownAdditionalPropertiesDiscriminatedDerived DeserializeExtendsUnknownAdditionalPropertiesDiscriminatedDerived(JsonElement element) + ExtendsUnknownAdditionalPropertiesDiscriminatedDerived IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminatedDerived)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeExtendsUnknownAdditionalPropertiesDiscriminatedDerived(document.RootElement, options); + } + + internal static ExtendsUnknownAdditionalPropertiesDiscriminatedDerived DeserializeExtendsUnknownAdditionalPropertiesDiscriminatedDerived(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -88,6 +111,37 @@ internal static ExtendsUnknownAdditionalPropertiesDiscriminatedDerived Deseriali return new ExtendsUnknownAdditionalPropertiesDiscriminatedDerived(name, kind, additionalProperties, index, Optional.ToNullable(age)); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminatedDerived)} does not support '{options.Format}' format."); + } + } + + ExtendsUnknownAdditionalPropertiesDiscriminatedDerived IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeExtendsUnknownAdditionalPropertiesDiscriminatedDerived(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminatedDerived)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new ExtendsUnknownAdditionalPropertiesDiscriminatedDerived FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminatedDerived.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminatedDerived.cs index 438ecc99a23..c29f6c6ac78 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminatedDerived.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ExtendsUnknownAdditionalPropertiesDiscriminatedDerived.cs @@ -38,6 +38,11 @@ internal ExtendsUnknownAdditionalPropertiesDiscriminatedDerived(string name, str Age = age; } + /// Initializes a new instance of for deserialization. + internal ExtendsUnknownAdditionalPropertiesDiscriminatedDerived() + { + } + /// The index property. public int Index { get; set; } /// The age property. diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsFloatAdditionalProperties.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsFloatAdditionalProperties.Serialization.cs index 424e662269f..9b49eb921f3 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsFloatAdditionalProperties.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsFloatAdditionalProperties.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class IsFloatAdditionalProperties : IUtf8JsonSerializable + public partial class IsFloatAdditionalProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsFloatAdditionalProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id); @@ -27,8 +37,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static IsFloatAdditionalProperties DeserializeIsFloatAdditionalProperties(JsonElement element) + IsFloatAdditionalProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsFloatAdditionalProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIsFloatAdditionalProperties(document.RootElement, options); + } + + internal static IsFloatAdditionalProperties DeserializeIsFloatAdditionalProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -49,6 +73,37 @@ internal static IsFloatAdditionalProperties DeserializeIsFloatAdditionalProperti return new IsFloatAdditionalProperties(id, additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IsFloatAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + IsFloatAdditionalProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIsFloatAdditionalProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IsFloatAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static IsFloatAdditionalProperties FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsFloatAdditionalProperties.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsFloatAdditionalProperties.cs index c0f10766623..a39222c5472 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsFloatAdditionalProperties.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsFloatAdditionalProperties.cs @@ -30,6 +30,11 @@ internal IsFloatAdditionalProperties(float id, IDictionary additi AdditionalProperties = additionalProperties; } + /// Initializes a new instance of for deserialization. + internal IsFloatAdditionalProperties() + { + } + /// The id property. public float Id { get; set; } /// Additional Properties. diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsModelAdditionalProperties.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsModelAdditionalProperties.Serialization.cs index bc70c2e4866..5125c99a0d4 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsModelAdditionalProperties.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsModelAdditionalProperties.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class IsModelAdditionalProperties : IUtf8JsonSerializable + public partial class IsModelAdditionalProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsModelAdditionalProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); foreach (var item in AdditionalProperties) { @@ -25,8 +35,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static IsModelAdditionalProperties DeserializeIsModelAdditionalProperties(JsonElement element) + IsModelAdditionalProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsModelAdditionalProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIsModelAdditionalProperties(document.RootElement, options); + } + + internal static IsModelAdditionalProperties DeserializeIsModelAdditionalProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -41,6 +65,37 @@ internal static IsModelAdditionalProperties DeserializeIsModelAdditionalProperti return new IsModelAdditionalProperties(additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IsModelAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + IsModelAdditionalProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIsModelAdditionalProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IsModelAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static IsModelAdditionalProperties FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsModelArrayAdditionalProperties.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsModelArrayAdditionalProperties.Serialization.cs index e73773b63ea..f83929a2dc7 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsModelArrayAdditionalProperties.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsModelArrayAdditionalProperties.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class IsModelArrayAdditionalProperties : IUtf8JsonSerializable + public partial class IsModelArrayAdditionalProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsModelArrayAdditionalProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); foreach (var item in AdditionalProperties) { @@ -30,8 +40,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static IsModelArrayAdditionalProperties DeserializeIsModelArrayAdditionalProperties(JsonElement element) + IsModelArrayAdditionalProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsModelArrayAdditionalProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIsModelArrayAdditionalProperties(document.RootElement, options); + } + + internal static IsModelArrayAdditionalProperties DeserializeIsModelArrayAdditionalProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -51,6 +75,37 @@ internal static IsModelArrayAdditionalProperties DeserializeIsModelArrayAddition return new IsModelArrayAdditionalProperties(additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IsModelArrayAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + IsModelArrayAdditionalProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIsModelArrayAdditionalProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IsModelArrayAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static IsModelArrayAdditionalProperties FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsStringAdditionalProperties.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsStringAdditionalProperties.Serialization.cs index b2f6cea5a2c..e6c7edc6222 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsStringAdditionalProperties.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsStringAdditionalProperties.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class IsStringAdditionalProperties : IUtf8JsonSerializable + public partial class IsStringAdditionalProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsStringAdditionalProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); @@ -27,8 +37,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static IsStringAdditionalProperties DeserializeIsStringAdditionalProperties(JsonElement element) + IsStringAdditionalProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsStringAdditionalProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIsStringAdditionalProperties(document.RootElement, options); + } + + internal static IsStringAdditionalProperties DeserializeIsStringAdditionalProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -49,6 +73,37 @@ internal static IsStringAdditionalProperties DeserializeIsStringAdditionalProper return new IsStringAdditionalProperties(name, additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IsStringAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + IsStringAdditionalProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIsStringAdditionalProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IsStringAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static IsStringAdditionalProperties FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsStringAdditionalProperties.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsStringAdditionalProperties.cs index 821df1a01ae..a2b4703be2e 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsStringAdditionalProperties.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsStringAdditionalProperties.cs @@ -34,6 +34,11 @@ internal IsStringAdditionalProperties(string name, IDictionary a AdditionalProperties = additionalProperties; } + /// Initializes a new instance of for deserialization. + internal IsStringAdditionalProperties() + { + } + /// The name property. public string Name { get; set; } /// Additional Properties. diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalProperties.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalProperties.Serialization.cs index 7f13acb35b2..2e96ea4e3c1 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalProperties.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalProperties.Serialization.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -13,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class IsUnknownAdditionalProperties : IUtf8JsonSerializable + public partial class IsUnknownAdditionalProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsUnknownAdditionalProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); @@ -35,8 +44,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static IsUnknownAdditionalProperties DeserializeIsUnknownAdditionalProperties(JsonElement element) + IsUnknownAdditionalProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsUnknownAdditionalProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIsUnknownAdditionalProperties(document.RootElement, options); + } + + internal static IsUnknownAdditionalProperties DeserializeIsUnknownAdditionalProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -57,6 +80,37 @@ internal static IsUnknownAdditionalProperties DeserializeIsUnknownAdditionalProp return new IsUnknownAdditionalProperties(name, additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IsUnknownAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + IsUnknownAdditionalProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIsUnknownAdditionalProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IsUnknownAdditionalProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static IsUnknownAdditionalProperties FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalProperties.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalProperties.cs index 45b8130db86..b50271e6cfd 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalProperties.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalProperties.cs @@ -34,6 +34,11 @@ internal IsUnknownAdditionalProperties(string name, IDictionary Initializes a new instance of for deserialization. + internal IsUnknownAdditionalProperties() + { + } + /// The name property. public string Name { get; set; } /// diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDerived.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDerived.Serialization.cs index 033c657f0fc..19a6be4fc3d 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDerived.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDerived.Serialization.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -13,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class IsUnknownAdditionalPropertiesDerived : IUtf8JsonSerializable + public partial class IsUnknownAdditionalPropertiesDerived : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDerived)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("index"u8); writer.WriteNumberValue(Index); @@ -42,8 +51,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static IsUnknownAdditionalPropertiesDerived DeserializeIsUnknownAdditionalPropertiesDerived(JsonElement element) + IsUnknownAdditionalPropertiesDerived IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDerived)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIsUnknownAdditionalPropertiesDerived(document.RootElement, options); + } + + internal static IsUnknownAdditionalPropertiesDerived DeserializeIsUnknownAdditionalPropertiesDerived(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -80,6 +103,37 @@ internal static IsUnknownAdditionalPropertiesDerived DeserializeIsUnknownAdditio return new IsUnknownAdditionalPropertiesDerived(name, additionalProperties, index, Optional.ToNullable(age)); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDerived)} does not support '{options.Format}' format."); + } + } + + IsUnknownAdditionalPropertiesDerived IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIsUnknownAdditionalPropertiesDerived(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDerived)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new IsUnknownAdditionalPropertiesDerived FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDerived.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDerived.cs index a01448028e2..c9661099033 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDerived.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDerived.cs @@ -36,6 +36,11 @@ internal IsUnknownAdditionalPropertiesDerived(string name, IDictionary Initializes a new instance of for deserialization. + internal IsUnknownAdditionalPropertiesDerived() + { + } + /// The index property. public int Index { get; set; } /// The age property. diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminated.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminated.Serialization.cs index e2873c033ce..5beb4948d25 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminated.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminated.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; using Azure; using Azure.Core; namespace _Type.Property.AdditionalProperties.Models { - public partial class IsUnknownAdditionalPropertiesDiscriminated : IUtf8JsonSerializable + [PersistableModelProxy(typeof(UnknownIsUnknownAdditionalPropertiesDiscriminated))] + public partial class IsUnknownAdditionalPropertiesDiscriminated : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminated)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); @@ -35,8 +46,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static IsUnknownAdditionalPropertiesDiscriminated DeserializeIsUnknownAdditionalPropertiesDiscriminated(JsonElement element) + IsUnknownAdditionalPropertiesDiscriminated IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminated)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIsUnknownAdditionalPropertiesDiscriminated(document.RootElement, options); + } + + internal static IsUnknownAdditionalPropertiesDiscriminated DeserializeIsUnknownAdditionalPropertiesDiscriminated(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -51,6 +76,37 @@ internal static IsUnknownAdditionalPropertiesDiscriminated DeserializeIsUnknownA return UnknownIsUnknownAdditionalPropertiesDiscriminated.DeserializeUnknownIsUnknownAdditionalPropertiesDiscriminated(element); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminated)} does not support '{options.Format}' format."); + } + } + + IsUnknownAdditionalPropertiesDiscriminated IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIsUnknownAdditionalPropertiesDiscriminated(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminated)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static IsUnknownAdditionalPropertiesDiscriminated FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminated.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminated.cs index 0ce1b0e911b..fbdf1022a25 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminated.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminated.cs @@ -40,6 +40,11 @@ internal IsUnknownAdditionalPropertiesDiscriminated(string name, string kind, ID AdditionalProperties = additionalProperties; } + /// Initializes a new instance of for deserialization. + internal IsUnknownAdditionalPropertiesDiscriminated() + { + } + /// The name property. public string Name { get; set; } /// The discriminator. diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminatedDerived.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminatedDerived.Serialization.cs index 77b9806766a..29af09593a1 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminatedDerived.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminatedDerived.Serialization.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -13,10 +14,18 @@ namespace _Type.Property.AdditionalProperties.Models { - public partial class IsUnknownAdditionalPropertiesDiscriminatedDerived : IUtf8JsonSerializable + public partial class IsUnknownAdditionalPropertiesDiscriminatedDerived : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminatedDerived)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("index"u8); writer.WriteNumberValue(Index); @@ -44,8 +53,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static IsUnknownAdditionalPropertiesDiscriminatedDerived DeserializeIsUnknownAdditionalPropertiesDiscriminatedDerived(JsonElement element) + IsUnknownAdditionalPropertiesDiscriminatedDerived IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminatedDerived)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIsUnknownAdditionalPropertiesDiscriminatedDerived(document.RootElement, options); + } + + internal static IsUnknownAdditionalPropertiesDiscriminatedDerived DeserializeIsUnknownAdditionalPropertiesDiscriminatedDerived(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -88,6 +111,37 @@ internal static IsUnknownAdditionalPropertiesDiscriminatedDerived DeserializeIsU return new IsUnknownAdditionalPropertiesDiscriminatedDerived(name, kind, additionalProperties, index, Optional.ToNullable(age)); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminatedDerived)} does not support '{options.Format}' format."); + } + } + + IsUnknownAdditionalPropertiesDiscriminatedDerived IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIsUnknownAdditionalPropertiesDiscriminatedDerived(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminatedDerived)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new IsUnknownAdditionalPropertiesDiscriminatedDerived FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminatedDerived.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminatedDerived.cs index 1695d909934..1690842e20f 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminatedDerived.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/IsUnknownAdditionalPropertiesDiscriminatedDerived.cs @@ -38,6 +38,11 @@ internal IsUnknownAdditionalPropertiesDiscriminatedDerived(string name, string k Age = age; } + /// Initializes a new instance of for deserialization. + internal IsUnknownAdditionalPropertiesDiscriminatedDerived() + { + } + /// The index property. public int Index { get; set; } /// The age property. diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ModelForRecord.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ModelForRecord.Serialization.cs index 4fc2b5b11ef..42d5d9fb613 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ModelForRecord.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ModelForRecord.Serialization.cs @@ -5,29 +5,71 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace _Type.Property.AdditionalProperties.Models { - public partial class ModelForRecord : IUtf8JsonSerializable + public partial class ModelForRecord : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelForRecord)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("state"u8); writer.WriteStringValue(State); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelForRecord DeserializeModelForRecord(JsonElement element) + ModelForRecord IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelForRecord)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelForRecord(document.RootElement, options); + } + + internal static ModelForRecord DeserializeModelForRecord(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } string state = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("state"u8)) @@ -35,10 +77,46 @@ internal static ModelForRecord DeserializeModelForRecord(JsonElement element) state = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelForRecord(state, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelForRecord)} does not support '{options.Format}' format."); } - return new ModelForRecord(state); } + ModelForRecord IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelForRecord(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelForRecord)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ModelForRecord FromResponse(Response response) diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ModelForRecord.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ModelForRecord.cs index 6473d67501e..70c9da1c0fc 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ModelForRecord.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/ModelForRecord.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace _Type.Property.AdditionalProperties.Models @@ -13,6 +14,38 @@ namespace _Type.Property.AdditionalProperties.Models /// model for record. public partial class ModelForRecord { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// The state property. /// is null. @@ -23,6 +56,20 @@ public ModelForRecord(string state) State = state; } + /// Initializes a new instance of . + /// The state property. + /// Keeps track of any properties unknown to the library. + internal ModelForRecord(string state, IDictionary serializedAdditionalRawData) + { + State = state; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ModelForRecord() + { + } + /// The state property. public string State { get; set; } } diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownExtendsUnknownAdditionalPropertiesDiscriminated.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownExtendsUnknownAdditionalPropertiesDiscriminated.Serialization.cs index 4f16fabd19a..5ab586a56de 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownExtendsUnknownAdditionalPropertiesDiscriminated.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownExtendsUnknownAdditionalPropertiesDiscriminated.Serialization.cs @@ -6,16 +6,62 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; +using Azure.Core; namespace _Type.Property.AdditionalProperties.Models { - internal partial class UnknownExtendsUnknownAdditionalPropertiesDiscriminated + internal partial class UnknownExtendsUnknownAdditionalPropertiesDiscriminated : IUtf8JsonSerializable, IJsonModel { - internal static UnknownExtendsUnknownAdditionalPropertiesDiscriminated DeserializeUnknownExtendsUnknownAdditionalPropertiesDiscriminated(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminated)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind); + foreach (var item in AdditionalProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + writer.WriteEndObject(); + } + + ExtendsUnknownAdditionalPropertiesDiscriminated IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminated)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownExtendsUnknownAdditionalPropertiesDiscriminated(document.RootElement, options); + } + + internal static UnknownExtendsUnknownAdditionalPropertiesDiscriminated DeserializeUnknownExtendsUnknownAdditionalPropertiesDiscriminated(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -42,6 +88,37 @@ internal static UnknownExtendsUnknownAdditionalPropertiesDiscriminated Deseriali return new UnknownExtendsUnknownAdditionalPropertiesDiscriminated(name, kind, additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminated)} does not support '{options.Format}' format."); + } + } + + ExtendsUnknownAdditionalPropertiesDiscriminated IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownExtendsUnknownAdditionalPropertiesDiscriminated(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ExtendsUnknownAdditionalPropertiesDiscriminated)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new UnknownExtendsUnknownAdditionalPropertiesDiscriminated FromResponse(Response response) @@ -49,5 +126,13 @@ internal static UnknownExtendsUnknownAdditionalPropertiesDiscriminated Deseriali using var document = JsonDocument.Parse(response.Content); return DeserializeUnknownExtendsUnknownAdditionalPropertiesDiscriminated(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal override RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownExtendsUnknownAdditionalPropertiesDiscriminated.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownExtendsUnknownAdditionalPropertiesDiscriminated.cs index 737b7254803..ae9ad96cf08 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownExtendsUnknownAdditionalPropertiesDiscriminated.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownExtendsUnknownAdditionalPropertiesDiscriminated.cs @@ -29,5 +29,10 @@ internal UnknownExtendsUnknownAdditionalPropertiesDiscriminated(string name) : b internal UnknownExtendsUnknownAdditionalPropertiesDiscriminated(string name, string kind, IDictionary additionalProperties) : base(name, kind, additionalProperties) { } + + /// Initializes a new instance of for deserialization. + internal UnknownExtendsUnknownAdditionalPropertiesDiscriminated() + { + } } } diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownIsUnknownAdditionalPropertiesDiscriminated.Serialization.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownIsUnknownAdditionalPropertiesDiscriminated.Serialization.cs index 47e17902396..9f504f550aa 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownIsUnknownAdditionalPropertiesDiscriminated.Serialization.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownIsUnknownAdditionalPropertiesDiscriminated.Serialization.cs @@ -6,16 +6,62 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; +using Azure.Core; namespace _Type.Property.AdditionalProperties.Models { - internal partial class UnknownIsUnknownAdditionalPropertiesDiscriminated + internal partial class UnknownIsUnknownAdditionalPropertiesDiscriminated : IUtf8JsonSerializable, IJsonModel { - internal static UnknownIsUnknownAdditionalPropertiesDiscriminated DeserializeUnknownIsUnknownAdditionalPropertiesDiscriminated(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminated)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind); + foreach (var item in AdditionalProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + writer.WriteEndObject(); + } + + IsUnknownAdditionalPropertiesDiscriminated IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminated)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownIsUnknownAdditionalPropertiesDiscriminated(document.RootElement, options); + } + + internal static UnknownIsUnknownAdditionalPropertiesDiscriminated DeserializeUnknownIsUnknownAdditionalPropertiesDiscriminated(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -42,6 +88,37 @@ internal static UnknownIsUnknownAdditionalPropertiesDiscriminated DeserializeUnk return new UnknownIsUnknownAdditionalPropertiesDiscriminated(name, kind, additionalProperties); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminated)} does not support '{options.Format}' format."); + } + } + + IsUnknownAdditionalPropertiesDiscriminated IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownIsUnknownAdditionalPropertiesDiscriminated(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IsUnknownAdditionalPropertiesDiscriminated)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new UnknownIsUnknownAdditionalPropertiesDiscriminated FromResponse(Response response) @@ -49,5 +126,13 @@ internal static UnknownIsUnknownAdditionalPropertiesDiscriminated DeserializeUnk using var document = JsonDocument.Parse(response.Content); return DeserializeUnknownIsUnknownAdditionalPropertiesDiscriminated(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal override RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownIsUnknownAdditionalPropertiesDiscriminated.cs b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownIsUnknownAdditionalPropertiesDiscriminated.cs index ef51a3da6d7..23815b02bbd 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownIsUnknownAdditionalPropertiesDiscriminated.cs +++ b/test/CadlRanchProjects/type/property/additional-properties/src/Generated/Models/UnknownIsUnknownAdditionalPropertiesDiscriminated.cs @@ -29,5 +29,10 @@ internal UnknownIsUnknownAdditionalPropertiesDiscriminated(string name) : base(n internal UnknownIsUnknownAdditionalPropertiesDiscriminated(string name, string kind, IDictionary additionalProperties) : base(name, kind, additionalProperties) { } + + /// Initializes a new instance of for deserialization. + internal UnknownIsUnknownAdditionalPropertiesDiscriminated() + { + } } } diff --git a/test/CadlRanchProjects/type/property/additional-properties/src/_Type.Property.AdditionalProperties.csproj b/test/CadlRanchProjects/type/property/additional-properties/src/_Type.Property.AdditionalProperties.csproj index 7617accbc51..f4f99cf39a4 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/src/_Type.Property.AdditionalProperties.csproj +++ b/test/CadlRanchProjects/type/property/additional-properties/src/_Type.Property.AdditionalProperties.csproj @@ -15,5 +15,6 @@ + diff --git a/test/CadlRanchProjects/type/property/additional-properties/tspconfig.yaml b/test/CadlRanchProjects/type/property/additional-properties/tspconfig.yaml index 9075e5b9004..d65b7d638da 100644 --- a/test/CadlRanchProjects/type/property/additional-properties/tspconfig.yaml +++ b/test/CadlRanchProjects/type/property/additional-properties/tspconfig.yaml @@ -1,3 +1,4 @@ options: "@azure-tools/typespec-csharp": namespace: _Type.Property.AdditionalProperties + use-model-reader-writer: true diff --git a/test/TestProjects/AdditionalPropertiesEx/AdditionalPropertiesEx.csproj b/test/TestProjects/AdditionalPropertiesEx/AdditionalPropertiesEx.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestProjects/AdditionalPropertiesEx/AdditionalPropertiesEx.csproj +++ b/test/TestProjects/AdditionalPropertiesEx/AdditionalPropertiesEx.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/AdditionalPropertiesExModelFactory.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/AdditionalPropertiesExModelFactory.cs index c429ea5271c..2a01791179a 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/AdditionalPropertiesExModelFactory.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/AdditionalPropertiesExModelFactory.cs @@ -13,6 +13,17 @@ namespace AdditionalPropertiesEx.Models /// Model factory for models. public static partial class AdditionalPropertiesExModelFactory { + /// Initializes a new instance of . + /// + /// Additional Properties. + /// A new instance for mocking. + public static InputAdditionalPropertiesModel InputAdditionalPropertiesModel(int id = default, IDictionary additionalProperties = null) + { + additionalProperties ??= new Dictionary(); + + return new InputAdditionalPropertiesModel(id, additionalProperties); + } + /// Initializes a new instance of . /// /// Additional Properties. diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Configuration.json b/test/TestProjects/AdditionalPropertiesEx/Generated/Configuration.json index ff2f7775235..0a3cc1520af 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Configuration.json +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/Error.Serialization.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/Error.Serialization.cs index 78afe32211d..8cd9d7dffc5 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/Error.Serialization.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace AdditionalPropertiesEx.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/Error.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/Error.cs index fcdc1d54fa6..7f4a7acbbdc 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/Error.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace AdditionalPropertiesEx.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModel.Serialization.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModel.Serialization.cs index c55b344c0b9..60005ad1cd6 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModel.Serialization.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModel.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace AdditionalPropertiesEx.Models { - public partial class InputAdditionalPropertiesModel : IUtf8JsonSerializable + public partial class InputAdditionalPropertiesModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputAdditionalPropertiesModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id); @@ -24,5 +35,72 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndObject(); } + + InputAdditionalPropertiesModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputAdditionalPropertiesModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInputAdditionalPropertiesModel(document.RootElement, options); + } + + internal static InputAdditionalPropertiesModel DeserializeInputAdditionalPropertiesModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + int id = default; + IDictionary additionalProperties = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("id"u8)) + { + id = property.Value.GetInt32(); + continue; + } + additionalPropertiesDictionary.Add(property.Name, property.Value.GetObject()); + } + additionalProperties = additionalPropertiesDictionary; + return new InputAdditionalPropertiesModel(id, additionalProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InputAdditionalPropertiesModel)} does not support '{options.Format}' format."); + } + } + + InputAdditionalPropertiesModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeInputAdditionalPropertiesModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InputAdditionalPropertiesModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModel.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModel.cs index d2270c03e15..312058af69e 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModel.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModel.cs @@ -30,6 +30,11 @@ internal InputAdditionalPropertiesModel(int id, IDictionary addi AdditionalProperties = additionalProperties; } + /// Initializes a new instance of for deserialization. + internal InputAdditionalPropertiesModel() + { + } + /// Gets the id. public int Id { get; } /// Additional Properties. diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModelStruct.Serialization.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModelStruct.Serialization.cs index 15532816920..305635270dc 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModelStruct.Serialization.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModelStruct.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace AdditionalPropertiesEx.Models { - public partial struct InputAdditionalPropertiesModelStruct : IUtf8JsonSerializable + public partial struct InputAdditionalPropertiesModelStruct : IUtf8JsonSerializable, IJsonModel, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputAdditionalPropertiesModelStruct)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id); @@ -24,5 +35,78 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndObject(); } + + InputAdditionalPropertiesModelStruct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputAdditionalPropertiesModelStruct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInputAdditionalPropertiesModelStruct(document.RootElement, options); + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => ((IJsonModel)this).Write(writer, options); + + object IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => ((IJsonModel)this).Create(ref reader, options); + + internal static InputAdditionalPropertiesModelStruct DeserializeInputAdditionalPropertiesModelStruct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + int id = default; + IDictionary additionalProperties = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("id"u8)) + { + id = property.Value.GetInt32(); + continue; + } + additionalPropertiesDictionary.Add(property.Name, property.Value.GetObject()); + } + additionalProperties = additionalPropertiesDictionary; + return new InputAdditionalPropertiesModelStruct(id, additionalProperties); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InputAdditionalPropertiesModelStruct)} does not support '{options.Format}' format."); + } + } + + InputAdditionalPropertiesModelStruct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeInputAdditionalPropertiesModelStruct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InputAdditionalPropertiesModelStruct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => ((IPersistableModel)this).Write(options); + + object IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => ((IPersistableModel)this).Create(data, options); + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => ((IPersistableModel)this).GetFormatFromOptions(options); } } diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModelStruct.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModelStruct.cs index 721b3e0ecd6..804d10b6cdf 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModelStruct.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/InputAdditionalPropertiesModelStruct.cs @@ -26,6 +26,11 @@ public InputAdditionalPropertiesModelStruct(int id, IDictionary AdditionalProperties = additionalProperties; } + /// Initializes a new instance of for deserialization. + public InputAdditionalPropertiesModelStruct() + { + } + /// Gets the id. public int Id { get; } /// Additional Properties. diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModel.Serialization.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModel.Serialization.cs index 0dabfae2a8b..461a9d801d7 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModel.Serialization.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModel.Serialization.cs @@ -5,15 +5,53 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; +using Azure.Core; namespace AdditionalPropertiesEx.Models { - public partial class OutputAdditionalPropertiesModel + public partial class OutputAdditionalPropertiesModel : IUtf8JsonSerializable, IJsonModel { - internal static OutputAdditionalPropertiesModel DeserializeOutputAdditionalPropertiesModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputAdditionalPropertiesModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("id"u8); + writer.WriteNumberValue(Id); + foreach (var item in AdditionalProperties) + { + writer.WritePropertyName(item.Key); + writer.WriteStringValue(item.Value); + } + writer.WriteEndObject(); + } + + OutputAdditionalPropertiesModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputAdditionalPropertiesModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeOutputAdditionalPropertiesModel(document.RootElement, options); + } + + internal static OutputAdditionalPropertiesModel DeserializeOutputAdditionalPropertiesModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -33,5 +71,36 @@ internal static OutputAdditionalPropertiesModel DeserializeOutputAdditionalPrope additionalProperties = additionalPropertiesDictionary; return new OutputAdditionalPropertiesModel(id, additionalProperties); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(OutputAdditionalPropertiesModel)} does not support '{options.Format}' format."); + } + } + + OutputAdditionalPropertiesModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeOutputAdditionalPropertiesModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(OutputAdditionalPropertiesModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModel.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModel.cs index e0e2b7baa97..8c11b29f7d5 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModel.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModel.cs @@ -30,6 +30,11 @@ internal OutputAdditionalPropertiesModel(int id, IReadOnlyDictionary Initializes a new instance of for deserialization. + internal OutputAdditionalPropertiesModel() + { + } + /// Gets the id. public int Id { get; } /// Additional Properties. diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModelStruct.Serialization.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModelStruct.Serialization.cs index 2461d202c4b..4240f127c08 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModelStruct.Serialization.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModelStruct.Serialization.cs @@ -5,15 +5,57 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; +using Azure.Core; namespace AdditionalPropertiesEx.Models { - public partial struct OutputAdditionalPropertiesModelStruct + public partial struct OutputAdditionalPropertiesModelStruct : IUtf8JsonSerializable, IJsonModel, IJsonModel { - internal static OutputAdditionalPropertiesModelStruct DeserializeOutputAdditionalPropertiesModelStruct(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputAdditionalPropertiesModelStruct)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("id"u8); + writer.WriteNumberValue(Id); + foreach (var item in AdditionalProperties) + { + writer.WritePropertyName(item.Key); + writer.WriteStringValue(item.Value); + } + writer.WriteEndObject(); + } + + OutputAdditionalPropertiesModelStruct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputAdditionalPropertiesModelStruct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeOutputAdditionalPropertiesModelStruct(document.RootElement, options); + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => ((IJsonModel)this).Write(writer, options); + + object IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => ((IJsonModel)this).Create(ref reader, options); + + internal static OutputAdditionalPropertiesModelStruct DeserializeOutputAdditionalPropertiesModelStruct(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + int id = default; IReadOnlyDictionary additionalProperties = default; Dictionary additionalPropertiesDictionary = new Dictionary(); @@ -29,5 +71,42 @@ internal static OutputAdditionalPropertiesModelStruct DeserializeOutputAdditiona additionalProperties = additionalPropertiesDictionary; return new OutputAdditionalPropertiesModelStruct(id, additionalProperties); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(OutputAdditionalPropertiesModelStruct)} does not support '{options.Format}' format."); + } + } + + OutputAdditionalPropertiesModelStruct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeOutputAdditionalPropertiesModelStruct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(OutputAdditionalPropertiesModelStruct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => ((IPersistableModel)this).Write(options); + + object IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => ((IPersistableModel)this).Create(data, options); + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => ((IPersistableModel)this).GetFormatFromOptions(options); } } diff --git a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModelStruct.cs b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModelStruct.cs index 17cb284d468..6b4957333e4 100644 --- a/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModelStruct.cs +++ b/test/TestProjects/AdditionalPropertiesEx/Generated/Models/OutputAdditionalPropertiesModelStruct.cs @@ -26,6 +26,11 @@ internal OutputAdditionalPropertiesModelStruct(int id, IReadOnlyDictionary Initializes a new instance of for deserialization. + public OutputAdditionalPropertiesModelStruct() + { + } + /// Gets the id. public int Id { get; } /// Additional Properties. diff --git a/test/TestProjects/AdditionalPropertiesEx/readme.md b/test/TestProjects/AdditionalPropertiesEx/readme.md new file mode 100644 index 00000000000..80cbd1a9fde --- /dev/null +++ b/test/TestProjects/AdditionalPropertiesEx/readme.md @@ -0,0 +1,12 @@ +# ApiVersion +### AutoRest Configuration +> see https://aka.ms/autorest + +``` yaml +generation1-convenience-client: true +require: $(this-folder)/../../../readme.md +input-file: $(this-folder)/AdditionalPropertiesEx.json +namespace: AdditionalPropertiesEx + +use-model-reader-writer: true +``` diff --git a/test/TestProjects/Customizations-TypeSpec/src/CustomizationsInTsp.csproj b/test/TestProjects/Customizations-TypeSpec/src/CustomizationsInTsp.csproj index 6ed2cdf69aa..8a5609d3bc3 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/CustomizationsInTsp.csproj +++ b/test/TestProjects/Customizations-TypeSpec/src/CustomizationsInTsp.csproj @@ -15,5 +15,6 @@ + diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Configuration.json b/test/TestProjects/Customizations-TypeSpec/src/Generated/Configuration.json index a91197eb2de..1b3d8460ed6 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Configuration.json +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Configuration.json @@ -5,5 +5,6 @@ "shared-source-folders": [ "../../../../../artifacts/bin/AutoRest.CSharp/Debug/net7.0/Generator.Shared", "../../../../../artifacts/bin/AutoRest.CSharp/Debug/net7.0/Azure.Core.Shared" - ] + ], + "use-model-reader-writer": true } diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelStruct.Serialization.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelStruct.Serialization.cs index 96f44b280d2..45136a81ef1 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelStruct.Serialization.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelStruct.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace CustomizationsInTsp.Models { - public partial struct ModelStruct : IUtf8JsonSerializable + public partial struct ModelStruct : IUtf8JsonSerializable, IJsonModel, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelStruct)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredInt"u8); writer.WriteNumberValue(RequiredInt); @@ -28,14 +39,49 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("optionalString"u8); writer.WriteStringValue(OptionalString); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelStruct DeserializeModelStruct(JsonElement element) + ModelStruct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelStruct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelStruct(document.RootElement, options); + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => ((IJsonModel)this).Write(writer, options); + + object IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => ((IJsonModel)this).Create(ref reader, options); + + internal static ModelStruct DeserializeModelStruct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + int requiredInt = default; Optional optionalInt = default; Optional optionalString = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredInt"u8)) @@ -57,10 +103,52 @@ internal static ModelStruct DeserializeModelStruct(JsonElement element) optionalString = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelStruct(requiredInt, Optional.ToNullable(optionalInt), optionalString.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelStruct)} does not support '{options.Format}' format."); } - return new ModelStruct(requiredInt, Optional.ToNullable(optionalInt), optionalString.Value); } + ModelStruct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelStruct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelStruct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => ((IPersistableModel)this).Write(options); + + object IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => ((IPersistableModel)this).Create(data, options); + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => ((IPersistableModel)this).GetFormatFromOptions(options); + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ModelStruct FromResponse(Response response) diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelStruct.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelStruct.cs index 3d326c2f6ba..634c452f606 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelStruct.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelStruct.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace CustomizationsInTsp.Models { /// Model to make to a struct. public readonly partial struct ModelStruct { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private readonly IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Required int. /// Optional int. @@ -21,6 +56,24 @@ public ModelStruct(int requiredInt, int? optionalInt, string optionalString) OptionalString = optionalString; } + /// Initializes a new instance of . + /// Required int. + /// Optional int. + /// Optional string. + /// Keeps track of any properties unknown to the library. + internal ModelStruct(int requiredInt, int? optionalInt, string optionalString, IDictionary serializedAdditionalRawData) + { + RequiredInt = requiredInt; + OptionalInt = optionalInt; + OptionalString = optionalString; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + public ModelStruct() + { + } + /// Required int. public int RequiredInt { get; } /// Optional int. diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToAddAdditionalSerializableProperty.Serialization.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToAddAdditionalSerializableProperty.Serialization.cs index e4c2b4f96ce..e34e32381d2 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToAddAdditionalSerializableProperty.Serialization.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToAddAdditionalSerializableProperty.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace CustomizationsInTsp.Models { - public partial class ModelToAddAdditionalSerializableProperty : IUtf8JsonSerializable + public partial class ModelToAddAdditionalSerializableProperty : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelToAddAdditionalSerializableProperty)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredInt"u8); WriteRequiredIntValue(writer); @@ -35,11 +46,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNull("additionalNullableSerializableProperty"); } } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelToAddAdditionalSerializableProperty DeserializeModelToAddAdditionalSerializableProperty(JsonElement element) + ModelToAddAdditionalSerializableProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelToAddAdditionalSerializableProperty)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelToAddAdditionalSerializableProperty(document.RootElement, options); + } + + internal static ModelToAddAdditionalSerializableProperty DeserializeModelToAddAdditionalSerializableProperty(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -47,6 +87,8 @@ internal static ModelToAddAdditionalSerializableProperty DeserializeModelToAddAd int requiredInt = default; Optional additionalSerializableProperty = default; Optional additionalNullableSerializableProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredInt"u8)) @@ -73,10 +115,46 @@ internal static ModelToAddAdditionalSerializableProperty DeserializeModelToAddAd additionalNullableSerializableProperty = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ModelToAddAdditionalSerializableProperty(requiredInt, additionalSerializableProperty, Optional.ToNullable(additionalNullableSerializableProperty)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelToAddAdditionalSerializableProperty(requiredInt, additionalSerializableProperty, Optional.ToNullable(additionalNullableSerializableProperty), serializedAdditionalRawData); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelToAddAdditionalSerializableProperty)} does not support '{options.Format}' format."); + } + } + + ModelToAddAdditionalSerializableProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelToAddAdditionalSerializableProperty(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelToAddAdditionalSerializableProperty)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ModelToAddAdditionalSerializableProperty FromResponse(Response response) diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToAddAdditionalSerializableProperty.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToAddAdditionalSerializableProperty.cs index 18ccfe77fe5..0ed10fe1463 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToAddAdditionalSerializableProperty.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToAddAdditionalSerializableProperty.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace CustomizationsInTsp.Models { /// Model to add additional serializable property. public partial class ModelToAddAdditionalSerializableProperty { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Required int. public ModelToAddAdditionalSerializableProperty(int requiredInt) @@ -21,11 +56,18 @@ public ModelToAddAdditionalSerializableProperty(int requiredInt) /// Required int. /// to be removed by post process. /// to be removed by post process. - internal ModelToAddAdditionalSerializableProperty(int requiredInt, int additionalSerializableProperty, int? additionalNullableSerializableProperty) + /// Keeps track of any properties unknown to the library. + internal ModelToAddAdditionalSerializableProperty(int requiredInt, int additionalSerializableProperty, int? additionalNullableSerializableProperty, IDictionary serializedAdditionalRawData) { RequiredInt = requiredInt; AdditionalSerializableProperty = additionalSerializableProperty; AdditionalNullableSerializableProperty = additionalNullableSerializableProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ModelToAddAdditionalSerializableProperty() + { } } } diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToChangeNamespace.Serialization.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToChangeNamespace.Serialization.cs index e462982de64..edd96d6e5bd 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToChangeNamespace.Serialization.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToChangeNamespace.Serialization.cs @@ -5,29 +5,71 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace CustomizationsInTsp.Models { - public partial class ModelToChangeNamespace : IUtf8JsonSerializable + public partial class ModelToChangeNamespace : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelToChangeNamespace)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredInt"u8); writer.WriteNumberValue(RequiredInt); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelToChangeNamespace DeserializeModelToChangeNamespace(JsonElement element) + ModelToChangeNamespace IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelToChangeNamespace)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelToChangeNamespace(document.RootElement, options); + } + + internal static ModelToChangeNamespace DeserializeModelToChangeNamespace(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } int requiredInt = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredInt"u8)) @@ -35,10 +77,46 @@ internal static ModelToChangeNamespace DeserializeModelToChangeNamespace(JsonEle requiredInt = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelToChangeNamespace(requiredInt, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelToChangeNamespace)} does not support '{options.Format}' format."); } - return new ModelToChangeNamespace(requiredInt); } + ModelToChangeNamespace IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelToChangeNamespace(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelToChangeNamespace)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ModelToChangeNamespace FromResponse(Response response) diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToChangeNamespace.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToChangeNamespace.cs index 787cba1034b..19a2de2f289 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToChangeNamespace.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToChangeNamespace.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace CustomizationsInTsp.Models { /// Model moved into custom namespace. public partial class ModelToChangeNamespace { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Required int. public ModelToChangeNamespace(int requiredInt) @@ -17,6 +52,20 @@ public ModelToChangeNamespace(int requiredInt) RequiredInt = requiredInt; } + /// Initializes a new instance of . + /// Required int. + /// Keeps track of any properties unknown to the library. + internal ModelToChangeNamespace(int requiredInt, IDictionary serializedAdditionalRawData) + { + RequiredInt = requiredInt; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ModelToChangeNamespace() + { + } + /// Required int. public int RequiredInt { get; set; } } diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToMakeInternal.Serialization.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToMakeInternal.Serialization.cs index a575428916f..3c9fb7d3a96 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToMakeInternal.Serialization.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToMakeInternal.Serialization.cs @@ -5,29 +5,71 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace CustomizationsInTsp.Models { - internal partial class ModelToMakeInternal : IUtf8JsonSerializable + internal partial class ModelToMakeInternal : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelToMakeInternal)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredInt"u8); writer.WriteNumberValue(RequiredInt); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelToMakeInternal DeserializeModelToMakeInternal(JsonElement element) + ModelToMakeInternal IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelToMakeInternal)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelToMakeInternal(document.RootElement, options); + } + + internal static ModelToMakeInternal DeserializeModelToMakeInternal(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } int requiredInt = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredInt"u8)) @@ -35,10 +77,46 @@ internal static ModelToMakeInternal DeserializeModelToMakeInternal(JsonElement e requiredInt = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelToMakeInternal(requiredInt, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelToMakeInternal)} does not support '{options.Format}' format."); } - return new ModelToMakeInternal(requiredInt); } + ModelToMakeInternal IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelToMakeInternal(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelToMakeInternal)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ModelToMakeInternal FromResponse(Response response) diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToMakeInternal.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToMakeInternal.cs index 2fdab74fd5b..527f8573814 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToMakeInternal.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelToMakeInternal.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace CustomizationsInTsp.Models { /// Public model made internal. internal partial class ModelToMakeInternal { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Required int. public ModelToMakeInternal(int requiredInt) @@ -17,6 +52,20 @@ public ModelToMakeInternal(int requiredInt) RequiredInt = requiredInt; } + /// Initializes a new instance of . + /// Required int. + /// Keeps track of any properties unknown to the library. + internal ModelToMakeInternal(int requiredInt, IDictionary serializedAdditionalRawData) + { + RequiredInt = requiredInt; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ModelToMakeInternal() + { + } + /// Required int. public int RequiredInt { get; set; } } diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelWithCustomizedProperties.Serialization.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelWithCustomizedProperties.Serialization.cs index 05d73d330bc..589050198b1 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelWithCustomizedProperties.Serialization.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelWithCustomizedProperties.Serialization.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -13,10 +14,18 @@ namespace CustomizationsInTsp.Models { - public partial class ModelWithCustomizedProperties : IUtf8JsonSerializable + public partial class ModelWithCustomizedProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithCustomizedProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("propertyToMakeInternal"u8); writer.WriteNumberValue(PropertyToMakeInternal); @@ -139,11 +148,101 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNull("vectorOptionalNullable"); } } + if (options.Format != "W") + { + writer.WritePropertyName("vectorReadOnly"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnly.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W" && Optional.IsDefined(VectorOptionalReadOnly)) + { + if (VectorOptionalReadOnly != null) + { + writer.WritePropertyName("vectorOptionalReadOnly"u8); + writer.WriteStartArray(); + foreach (var item in VectorOptionalReadOnly.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorOptionalReadOnly"); + } + } + if (options.Format != "W") + { + if (VectorNullableReadOnly != null) + { + writer.WritePropertyName("vectorNullableReadOnly"u8); + writer.WriteStartArray(); + foreach (var item in VectorNullableReadOnly.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorNullableReadOnly"); + } + } + if (options.Format != "W" && Optional.IsDefined(VectorOptionalNullableReadOnly)) + { + if (VectorOptionalNullableReadOnly != null) + { + writer.WritePropertyName("vectorOptionalNullableReadOnly"u8); + writer.WriteStartArray(); + foreach (var item in VectorOptionalNullableReadOnly.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorOptionalNullableReadOnly"); + } + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelWithCustomizedProperties DeserializeModelWithCustomizedProperties(JsonElement element) + ModelWithCustomizedProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithCustomizedProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelWithCustomizedProperties(document.RootElement, options); + } + + internal static ModelWithCustomizedProperties DeserializeModelWithCustomizedProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -168,6 +267,8 @@ internal static ModelWithCustomizedProperties DeserializeModelWithCustomizedProp Optional?> vectorOptionalReadOnly = default; ReadOnlyMemory? vectorNullableReadOnly = default; Optional?> vectorOptionalNullableReadOnly = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("propertyToMakeInternal"u8)) @@ -402,10 +503,46 @@ internal static ModelWithCustomizedProperties DeserializeModelWithCustomizedProp vectorOptionalNullableReadOnly = new ReadOnlyMemory?(array); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelWithCustomizedProperties(propertyToMakeInternal, propertyToRename, propertyToMakeFloat, propertyToMakeInt, propertyToMakeDuration, propertyToMakeString, propertyToMakeJsonElement, propertyToField, badListName, badDictionaryName, badListOfListName, badListOfDictionaryName, vector, Optional.ToNullable(vectorOptional), vectorNullable, Optional.ToNullable(vectorOptionalNullable), vectorReadOnly, Optional.ToNullable(vectorOptionalReadOnly), vectorNullableReadOnly, Optional.ToNullable(vectorOptionalNullableReadOnly), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelWithCustomizedProperties)} does not support '{options.Format}' format."); } - return new ModelWithCustomizedProperties(propertyToMakeInternal, propertyToRename, propertyToMakeFloat, propertyToMakeInt, propertyToMakeDuration, propertyToMakeString, propertyToMakeJsonElement, propertyToField, badListName, badDictionaryName, badListOfListName, badListOfDictionaryName, vector, Optional.ToNullable(vectorOptional), vectorNullable, Optional.ToNullable(vectorOptionalNullable), vectorReadOnly, Optional.ToNullable(vectorOptionalReadOnly), vectorNullableReadOnly, Optional.ToNullable(vectorOptionalNullableReadOnly)); } + ModelWithCustomizedProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelWithCustomizedProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelWithCustomizedProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ModelWithCustomizedProperties FromResponse(Response response) diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelWithCustomizedProperties.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelWithCustomizedProperties.cs index b52064d0291..ddac83fb55e 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelWithCustomizedProperties.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/ModelWithCustomizedProperties.cs @@ -16,6 +16,38 @@ namespace CustomizationsInTsp.Models /// Model with customized properties. public partial class ModelWithCustomizedProperties { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Public property made internal. /// Renamed property (original name: PropertyToRename). @@ -79,7 +111,8 @@ public ModelWithCustomizedProperties(int propertyToMakeInternal, int renamedProp /// Property type changed to ReadOnlyMemory<float>?. /// Property type changed to ReadOnlyMemory<float>?. /// Property type changed to ReadOnlyMemory<float>?. - internal ModelWithCustomizedProperties(int propertyToMakeInternal, int renamedProperty, float propertyToMakeFloat, int propertyToMakeInt, TimeSpan propertyToMakeDuration, string propertyToMakeString, JsonElement propertyToMakeJsonElement, string propertyToField, IList goodListName, IDictionary goodDictionaryName, IList> goodListOfListName, IList> goodListOfDictionaryName, ReadOnlyMemory vector, ReadOnlyMemory? vectorOptional, ReadOnlyMemory? vectorNullable, ReadOnlyMemory? vectorOptionalNullable, ReadOnlyMemory vectorReadOnly, ReadOnlyMemory? vectorOptionalReadOnly, ReadOnlyMemory? vectorNullableReadOnly, ReadOnlyMemory? vectorOptionalNullableReadOnly) + /// Keeps track of any properties unknown to the library. + internal ModelWithCustomizedProperties(int propertyToMakeInternal, int renamedProperty, float propertyToMakeFloat, int propertyToMakeInt, TimeSpan propertyToMakeDuration, string propertyToMakeString, JsonElement propertyToMakeJsonElement, string propertyToField, IList goodListName, IDictionary goodDictionaryName, IList> goodListOfListName, IList> goodListOfDictionaryName, ReadOnlyMemory vector, ReadOnlyMemory? vectorOptional, ReadOnlyMemory? vectorNullable, ReadOnlyMemory? vectorOptionalNullable, ReadOnlyMemory vectorReadOnly, ReadOnlyMemory? vectorOptionalReadOnly, ReadOnlyMemory? vectorNullableReadOnly, ReadOnlyMemory? vectorOptionalNullableReadOnly, IDictionary serializedAdditionalRawData) { PropertyToMakeInternal = propertyToMakeInternal; RenamedProperty = renamedProperty; @@ -101,6 +134,12 @@ internal ModelWithCustomizedProperties(int propertyToMakeInternal, int renamedPr VectorOptionalReadOnly = vectorOptionalReadOnly; VectorNullableReadOnly = vectorNullableReadOnly; VectorOptionalNullableReadOnly = vectorOptionalNullableReadOnly; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ModelWithCustomizedProperties() + { } } } diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RenamedModel.Serialization.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RenamedModel.Serialization.cs index 0d3c028d3b9..9dab1a00f0b 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RenamedModel.Serialization.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RenamedModel.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace CustomizationsInTsp.Models { - public partial class RenamedModel : IUtf8JsonSerializable + public partial class RenamedModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RenamedModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredInt"u8); writer.WriteNumberValue(RequiredInt); @@ -23,17 +34,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("optionalInt"u8); writer.WriteNumberValue(OptionalInt.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RenamedModel DeserializeRenamedModel(JsonElement element) + RenamedModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RenamedModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRenamedModel(document.RootElement, options); + } + + internal static RenamedModel DeserializeRenamedModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } int requiredInt = default; Optional optionalInt = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredInt"u8)) @@ -50,10 +92,46 @@ internal static RenamedModel DeserializeRenamedModel(JsonElement element) optionalInt = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new RenamedModel(requiredInt, Optional.ToNullable(optionalInt)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RenamedModel(requiredInt, Optional.ToNullable(optionalInt), serializedAdditionalRawData); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RenamedModel)} does not support '{options.Format}' format."); + } + } + + RenamedModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRenamedModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RenamedModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static RenamedModel FromResponse(Response response) diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RenamedModel.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RenamedModel.cs index b41d8d6b8f8..238886bafdc 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RenamedModel.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RenamedModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace CustomizationsInTsp.Models { /// Renamed model (original name: ModelToRename). public partial class RenamedModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Required int. public RenamedModel(int requiredInt) @@ -20,10 +55,17 @@ public RenamedModel(int requiredInt) /// Initializes a new instance of . /// Required int. /// Optional int. - internal RenamedModel(int requiredInt, int? optionalInt) + /// Keeps track of any properties unknown to the library. + internal RenamedModel(int requiredInt, int? optionalInt, IDictionary serializedAdditionalRawData) { RequiredInt = requiredInt; OptionalInt = optionalInt; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal RenamedModel() + { } /// Required int. diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RootModel.Serialization.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RootModel.Serialization.cs index 4454b8f416e..c4502f46b17 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RootModel.Serialization.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RootModel.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace CustomizationsInTsp.Models { - public partial class RootModel : IUtf8JsonSerializable + public partial class RootModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RootModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(PropertyExtensibleEnum)) { @@ -71,11 +82,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("propertyModelStruct"u8); writer.WriteObjectValue(PropertyModelStruct); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RootModel DeserializeRootModel(JsonElement element) + RootModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RootModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRootModel(document.RootElement, options); + } + + internal static RootModel DeserializeRootModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -91,6 +131,8 @@ internal static RootModel DeserializeRootModel(JsonElement element) Optional propertyModelToAddAdditionalSerializableProperty = default; Optional propertyToMoveToCustomization = default; Optional propertyModelStruct = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("propertyExtensibleEnum"u8)) @@ -192,10 +234,46 @@ internal static RootModel DeserializeRootModel(JsonElement element) propertyModelStruct = ModelStruct.DeserializeModelStruct(property.Value); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new RootModel(Optional.ToNullable(propertyExtensibleEnum), propertyModelToMakeInternal.Value, propertyModelToRename.Value, propertyModelToChangeNamespace.Value, propertyModelWithCustomizedProperties.Value, Optional.ToNullable(propertyEnumToRename), Optional.ToNullable(propertyEnumWithValueToRename), Optional.ToNullable(propertyEnumToBeMadeExtensible), propertyModelToAddAdditionalSerializableProperty.Value, Optional.ToNullable(propertyToMoveToCustomization), Optional.ToNullable(propertyModelStruct)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RootModel(Optional.ToNullable(propertyExtensibleEnum), propertyModelToMakeInternal.Value, propertyModelToRename.Value, propertyModelToChangeNamespace.Value, propertyModelWithCustomizedProperties.Value, Optional.ToNullable(propertyEnumToRename), Optional.ToNullable(propertyEnumWithValueToRename), Optional.ToNullable(propertyEnumToBeMadeExtensible), propertyModelToAddAdditionalSerializableProperty.Value, Optional.ToNullable(propertyToMoveToCustomization), Optional.ToNullable(propertyModelStruct), serializedAdditionalRawData); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RootModel)} does not support '{options.Format}' format."); + } + } + + RootModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRootModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RootModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static RootModel FromResponse(Response response) diff --git a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RootModel.cs b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RootModel.cs index 6d6258e3bc0..1f15bfd26bc 100644 --- a/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RootModel.cs +++ b/test/TestProjects/Customizations-TypeSpec/src/Generated/Models/RootModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace CustomizationsInTsp.Models { /// Root RoundTrip model to reference all other types to ensure generation. public partial class RootModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public RootModel() { @@ -27,7 +62,8 @@ public RootModel() /// ModelToAddAdditionalSerializableProperty. /// Enum type property to move to customization code. /// ModelStruct. - internal RootModel(ExtensibleEnumWithOperator? propertyExtensibleEnum, ModelToMakeInternal propertyModelToMakeInternal, RenamedModel propertyModelToRename, ModelToChangeNamespace propertyModelToChangeNamespace, ModelWithCustomizedProperties propertyModelWithCustomizedProperties, RenamedEnum? propertyEnumToRename, EnumWithValueToRename? propertyEnumWithValueToRename, EnumToBeMadeExtensible? propertyEnumToBeMadeExtensible, ModelToAddAdditionalSerializableProperty propertyModelToAddAdditionalSerializableProperty, NormalEnum? propertyToMoveToCustomization, ModelStruct? propertyModelStruct) + /// Keeps track of any properties unknown to the library. + internal RootModel(ExtensibleEnumWithOperator? propertyExtensibleEnum, ModelToMakeInternal propertyModelToMakeInternal, RenamedModel propertyModelToRename, ModelToChangeNamespace propertyModelToChangeNamespace, ModelWithCustomizedProperties propertyModelWithCustomizedProperties, RenamedEnum? propertyEnumToRename, EnumWithValueToRename? propertyEnumWithValueToRename, EnumToBeMadeExtensible? propertyEnumToBeMadeExtensible, ModelToAddAdditionalSerializableProperty propertyModelToAddAdditionalSerializableProperty, NormalEnum? propertyToMoveToCustomization, ModelStruct? propertyModelStruct, IDictionary serializedAdditionalRawData) { PropertyExtensibleEnum = propertyExtensibleEnum; PropertyModelToMakeInternal = propertyModelToMakeInternal; @@ -40,6 +76,7 @@ internal RootModel(ExtensibleEnumWithOperator? propertyExtensibleEnum, ModelToMa PropertyModelToAddAdditionalSerializableProperty = propertyModelToAddAdditionalSerializableProperty; PropertyToMoveToCustomization = propertyToMoveToCustomization; PropertyModelStruct = propertyModelStruct; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// ExtensibleEnumWithOperator. diff --git a/test/TestProjects/Customizations-TypeSpec/tspconfig.yaml b/test/TestProjects/Customizations-TypeSpec/tspconfig.yaml index b74ff790d83..224bace85df 100644 --- a/test/TestProjects/Customizations-TypeSpec/tspconfig.yaml +++ b/test/TestProjects/Customizations-TypeSpec/tspconfig.yaml @@ -1,3 +1,4 @@ options: "@azure-tools/typespec-csharp": generate-convenience-methods: false + use-model-reader-writer: true diff --git a/test/TestProjects/FirstTest-TypeSpec/src/Generated/Configuration.json b/test/TestProjects/FirstTest-TypeSpec/src/Generated/Configuration.json index 2b718f74370..7d2b05da11c 100644 --- a/test/TestProjects/FirstTest-TypeSpec/src/Generated/Configuration.json +++ b/test/TestProjects/FirstTest-TypeSpec/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "../../../../../artifacts/bin/AutoRest.CSharp/Debug/net7.0/Azure.Core.Shared" ], "head-as-boolean": true, - "deserialize-null-collection-as-null-value": true + "deserialize-null-collection-as-null-value": true, + "use-model-reader-writer": false } diff --git a/test/TestProjects/FirstTest-TypeSpec/tspconfig.yaml b/test/TestProjects/FirstTest-TypeSpec/tspconfig.yaml index 4c7f3f9b9b7..defcc6d8b81 100644 --- a/test/TestProjects/FirstTest-TypeSpec/tspconfig.yaml +++ b/test/TestProjects/FirstTest-TypeSpec/tspconfig.yaml @@ -3,3 +3,4 @@ options: generate-convenience-methods: false deserialize-null-collection-as-null-value: true head-as-boolean: true + use-model-reader-writer: false diff --git a/test/TestProjects/MgmtXmlDeserialization/Custom/Models/XmlInstanceData.Serialization.cs b/test/TestProjects/MgmtXmlDeserialization/Custom/Models/XmlInstanceData.Serialization.cs deleted file mode 100644 index 2e1f0e9b95a..00000000000 --- a/test/TestProjects/MgmtXmlDeserialization/Custom/Models/XmlInstanceData.Serialization.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#nullable disable - -using System.Text.Json; -using System.Xml; -using System.Xml.Linq; -using Azure.Core; -using Azure.ResourceManager.Models; - -namespace MgmtXmlDeserialization -{ - public partial class XmlInstanceData : IUtf8JsonSerializable, IXmlSerializable - { - internal static XmlInstanceData DeserializeXmlInstanceData(XElement element) - { - ResourceIdentifier id = default; - string name = default; - ResourceType type = default; - if (element.Element("id") is XElement idElement) - { - id = new ResourceIdentifier((string)idElement); - } - if (element.Element("name") is XElement nameElement) - { - name = (string)nameElement; - } - if (element.Element("type") is XElement typeElement) - { - type = (string)typeElement; - } - return new XmlInstanceData(id, name, type, null); - } - } -} diff --git a/test/TestProjects/MgmtXmlDeserialization/Generated/ArmMgmtXmlDeserializationModelFactory.cs b/test/TestProjects/MgmtXmlDeserialization/Generated/ArmMgmtXmlDeserializationModelFactory.cs index 6c0ff7c40af..753e12e43b4 100644 --- a/test/TestProjects/MgmtXmlDeserialization/Generated/ArmMgmtXmlDeserializationModelFactory.cs +++ b/test/TestProjects/MgmtXmlDeserialization/Generated/ArmMgmtXmlDeserializationModelFactory.cs @@ -22,7 +22,7 @@ public static partial class ArmMgmtXmlDeserializationModelFactory /// A new instance for mocking. public static XmlInstanceData XmlInstanceData(ResourceIdentifier id = null, string name = null, ResourceType resourceType = default, SystemData systemData = null) { - return new XmlInstanceData(id, name, resourceType, systemData); + return new XmlInstanceData(id, name, resourceType, systemData, serializedAdditionalRawData: null); } } } diff --git a/test/TestProjects/MgmtXmlDeserialization/Generated/Configuration.json b/test/TestProjects/MgmtXmlDeserialization/Generated/Configuration.json index 1d771583fca..535db965d1b 100644 --- a/test/TestProjects/MgmtXmlDeserialization/Generated/Configuration.json +++ b/test/TestProjects/MgmtXmlDeserialization/Generated/Configuration.json @@ -9,5 +9,6 @@ "azure-arm": true, "public-clients": true, "head-as-boolean": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlCollection.Serialization.cs b/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlCollection.Serialization.cs index bb283530794..1d478416cbd 100644 --- a/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlCollection.Serialization.cs +++ b/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlCollection.Serialization.cs @@ -5,18 +5,51 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; using System.Text.Json; +using System.Xml; using System.Xml.Linq; using Azure.Core; using MgmtXmlDeserialization; namespace MgmtXmlDeserialization.Models { - internal partial class XmlCollection + internal partial class XmlCollection : IUtf8JsonSerializable, IJsonModel, IXmlSerializable, IPersistableModel { - internal static XmlCollection DeserializeXmlCollection(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "XmlCollection"); + if (Optional.IsDefined(Count)) + { + writer.WriteStartElement("count"); + writer.WriteValue(Count.Value); + writer.WriteEndElement(); + } + if (Optional.IsDefined(NextLink)) + { + writer.WriteStartElement("nextLink"); + writer.WriteValue(NextLink); + writer.WriteEndElement(); + } + if (Optional.IsCollectionDefined(Value)) + { + foreach (var item in Value) + { + writer.WriteObjectValue(item, "XmlInstance"); + } + } + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static XmlCollection DeserializeXmlCollection(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + long? count = default; string nextLink = default; IReadOnlyList value = default; @@ -34,11 +67,74 @@ internal static XmlCollection DeserializeXmlCollection(XElement element) array.Add(XmlInstanceData.DeserializeXmlInstanceData(e)); } value = array; - return new XmlCollection(value, count, nextLink); + return new XmlCollection(value, count, nextLink, serializedAdditionalRawData: null); + } + + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(XmlCollection)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsCollectionDefined(Value)) + { + writer.WritePropertyName("value"u8); + writer.WriteStartArray(); + foreach (var item in Value) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(Count)) + { + writer.WritePropertyName("count"u8); + writer.WriteNumberValue(Count.Value); + } + if (Optional.IsDefined(NextLink)) + { + writer.WritePropertyName("nextLink"u8); + writer.WriteStringValue(NextLink); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); } - internal static XmlCollection DeserializeXmlCollection(JsonElement element) + XmlCollection IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(XmlCollection)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeXmlCollection(document.RootElement, options); + } + + internal static XmlCollection DeserializeXmlCollection(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -46,6 +142,8 @@ internal static XmlCollection DeserializeXmlCollection(JsonElement element) Optional> value = default; Optional count = default; Optional nextLink = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("value"u8)) @@ -76,8 +174,54 @@ internal static XmlCollection DeserializeXmlCollection(JsonElement element) nextLink = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new XmlCollection(Optional.ToList(value), Optional.ToNullable(count), nextLink.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(XmlCollection)} does not support '{options.Format}' format."); } - return new XmlCollection(Optional.ToList(value), Optional.ToNullable(count), nextLink.Value); } + + XmlCollection IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeXmlCollection(document.RootElement, options); + } + case "X": + return DeserializeXmlCollection(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(XmlCollection)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlCollection.cs b/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlCollection.cs index e7629ee8c0a..aa1e8d5df0a 100644 --- a/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlCollection.cs +++ b/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlCollection.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; using MgmtXmlDeserialization; @@ -14,6 +15,38 @@ namespace MgmtXmlDeserialization.Models /// Paged Xml list representation. internal partial class XmlCollection { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal XmlCollection() { @@ -24,11 +57,13 @@ internal XmlCollection() /// Page values. /// Total record count number across all pages. /// Next page link if any. - internal XmlCollection(IReadOnlyList value, long? count, string nextLink) + /// Keeps track of any properties unknown to the library. + internal XmlCollection(IReadOnlyList value, long? count, string nextLink, IDictionary serializedAdditionalRawData) { Value = value; Count = count; NextLink = nextLink; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Page values. diff --git a/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlInstanceData.Serialization.cs b/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlInstanceData.Serialization.cs index 9e2a62b84e4..7980c9dedee 100644 --- a/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlInstanceData.Serialization.cs +++ b/test/TestProjects/MgmtXmlDeserialization/Generated/Models/XmlInstanceData.Serialization.cs @@ -5,6 +5,10 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.IO; using System.Text.Json; using System.Xml; using System.Xml.Linq; @@ -13,21 +17,30 @@ namespace MgmtXmlDeserialization { - public partial class XmlInstanceData : IUtf8JsonSerializable, IXmlSerializable + public partial class XmlInstanceData : IUtf8JsonSerializable, IJsonModel, IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "XmlInstance"); - writer.WriteStartElement("id"); - writer.WriteValue(Id); - writer.WriteEndElement(); - writer.WriteStartElement("name"); - writer.WriteValue(Name); - writer.WriteEndElement(); - writer.WriteStartElement("type"); - writer.WriteValue(ResourceType); - writer.WriteEndElement(); - if (Optional.IsDefined(SystemData)) + if (options.Format != "W") + { + writer.WriteStartElement("id"); + writer.WriteValue(Id); + writer.WriteEndElement(); + } + if (options.Format != "W") + { + writer.WriteStartElement("name"); + writer.WriteValue(Name); + writer.WriteEndElement(); + } + if (options.Format != "W") + { + writer.WriteStartElement("type"); + writer.WriteValue(ResourceType); + writer.WriteEndElement(); + } + if (options.Format != "W" && Optional.IsDefined(SystemData)) { writer.WriteStartElement("systemData"); writer.WriteValue(SystemData); @@ -36,14 +49,100 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static XmlInstanceData DeserializeXmlInstanceData(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + ResourceIdentifier id = default; + string name = default; + ResourceType resourceType = default; + SystemData systemData = default; + if (element.Element("id") is XElement idElement) + { + id = new ResourceIdentifier((string)idElement); + } + if (element.Element("name") is XElement nameElement) + { + name = (string)nameElement; + } + if (element.Element("type") is XElement typeElement) + { + resourceType = (string)typeElement; + } + if (element.Element("systemData") is XElement systemDataElement) + { + systemData = null; + } + return new XmlInstanceData(id, name, resourceType, systemData, serializedAdditionalRawData: null); + } + + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(XmlInstanceData)} does not support '{format}' format."); + } + writer.WriteStartObject(); + if (options.Format != "W") + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (options.Format != "W") + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + if (options.Format != "W") + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(ResourceType); + } + if (options.Format != "W" && Optional.IsDefined(SystemData)) + { + writer.WritePropertyName("systemData"u8); + JsonSerializer.Serialize(writer, SystemData); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static XmlInstanceData DeserializeXmlInstanceData(JsonElement element) + XmlInstanceData IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(XmlInstanceData)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeXmlInstanceData(document.RootElement, options); + } + + internal static XmlInstanceData DeserializeXmlInstanceData(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -52,6 +151,8 @@ internal static XmlInstanceData DeserializeXmlInstanceData(JsonElement element) string name = default; ResourceType type = default; Optional systemData = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -78,8 +179,54 @@ internal static XmlInstanceData DeserializeXmlInstanceData(JsonElement element) systemData = JsonSerializer.Deserialize(property.Value.GetRawText()); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new XmlInstanceData(id, name, type, systemData.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new XmlInstanceData(id, name, type, systemData.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(XmlInstanceData)} does not support '{options.Format}' format."); + } + } + + XmlInstanceData IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeXmlInstanceData(document.RootElement, options); + } + case "X": + return DeserializeXmlInstanceData(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(XmlInstanceData)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestProjects/MgmtXmlDeserialization/Generated/XmlInstanceData.cs b/test/TestProjects/MgmtXmlDeserialization/Generated/XmlInstanceData.cs index 981691574d4..4ba9f852a5b 100644 --- a/test/TestProjects/MgmtXmlDeserialization/Generated/XmlInstanceData.cs +++ b/test/TestProjects/MgmtXmlDeserialization/Generated/XmlInstanceData.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.Collections.Generic; using Azure.Core; using Azure.ResourceManager.Models; @@ -16,6 +18,38 @@ namespace MgmtXmlDeserialization /// public partial class XmlInstanceData : ResourceData { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public XmlInstanceData() { @@ -26,8 +60,10 @@ public XmlInstanceData() /// The name. /// The resourceType. /// The systemData. - internal XmlInstanceData(ResourceIdentifier id, string name, ResourceType resourceType, SystemData systemData) : base(id, name, resourceType, systemData) + /// Keeps track of any properties unknown to the library. + internal XmlInstanceData(ResourceIdentifier id, string name, ResourceType resourceType, SystemData systemData, IDictionary serializedAdditionalRawData) : base(id, name, resourceType, systemData) { + _serializedAdditionalRawData = serializedAdditionalRawData; } } } diff --git a/test/TestProjects/MgmtXmlDeserialization/MgmtXmlDeserialization.csproj b/test/TestProjects/MgmtXmlDeserialization/MgmtXmlDeserialization.csproj index fc0c9a42c53..30b161aed0e 100644 --- a/test/TestProjects/MgmtXmlDeserialization/MgmtXmlDeserialization.csproj +++ b/test/TestProjects/MgmtXmlDeserialization/MgmtXmlDeserialization.csproj @@ -9,5 +9,6 @@ + diff --git a/test/TestProjects/MgmtXmlDeserialization/readme.md b/test/TestProjects/MgmtXmlDeserialization/readme.md index 714ac8fda28..deb88ff1ab8 100644 --- a/test/TestProjects/MgmtXmlDeserialization/readme.md +++ b/test/TestProjects/MgmtXmlDeserialization/readme.md @@ -11,4 +11,5 @@ azure-arm: true model-namespace: false input-file: $(this-folder)/MgmtXmlDeserialization.json namespace: Azure.XmlDeserialization +use-model-reader-writer: true ``` diff --git a/test/TestProjects/ModelShapes/Generated/Configuration.json b/test/TestProjects/ModelShapes/Generated/Configuration.json index 84f9da7a77b..85e820fbffb 100644 --- a/test/TestProjects/ModelShapes/Generated/Configuration.json +++ b/test/TestProjects/ModelShapes/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestProjects/ModelShapes/Generated/ModelShapesModelFactory.cs b/test/TestProjects/ModelShapes/Generated/ModelShapesModelFactory.cs index c6f10eaff3b..834db865207 100644 --- a/test/TestProjects/ModelShapes/Generated/ModelShapesModelFactory.cs +++ b/test/TestProjects/ModelShapes/Generated/ModelShapesModelFactory.cs @@ -14,6 +14,46 @@ namespace ModelShapes.Models /// Model factory for models. public static partial class ModelShapesModelFactory { + /// Initializes a new instance of . + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The vector representation of a search query. + /// The vector representation of a search query. + /// The vector representation of a search query. + /// The vector representation of a search query. + /// The vector representation of a search query. + /// The vector representation of a search query. + /// The vector representation of a search query. + /// The vector representation of a search query. + /// A new instance for mocking. + public static InputModel InputModel(string requiredString = null, int requiredInt = default, IEnumerable requiredStringList = null, IEnumerable requiredIntList = null, string nonRequiredString = null, int? nonRequiredInt = null, IEnumerable nonRequiredStringList = null, IEnumerable nonRequiredIntList = null, string requiredNullableString = null, int? requiredNullableInt = null, IEnumerable requiredNullableStringList = null, IEnumerable requiredNullableIntList = null, string nonRequiredNullableString = null, int? nonRequiredNullableInt = null, IEnumerable nonRequiredNullableStringList = null, IEnumerable nonRequiredNullableIntList = null, ReadOnlyMemory vector = default, ReadOnlyMemory vectorReadOnly = default, ReadOnlyMemory vectorReadOnlyRequired = default, ReadOnlyMemory vectorRequired = default, ReadOnlyMemory? vectorNullable = null, ReadOnlyMemory? vectorReadOnlyNullable = null, ReadOnlyMemory? vectorReadOnlyRequiredNullable = null, ReadOnlyMemory? vectorRequiredNullable = null) + { + requiredStringList ??= new List(); + requiredIntList ??= new List(); + nonRequiredStringList ??= new List(); + nonRequiredIntList ??= new List(); + requiredNullableStringList ??= new List(); + requiredNullableIntList ??= new List(); + nonRequiredNullableStringList ??= new List(); + nonRequiredNullableIntList ??= new List(); + + return new InputModel(requiredString, requiredInt, requiredStringList?.ToList(), requiredIntList?.ToList(), nonRequiredString, nonRequiredInt, nonRequiredStringList?.ToList(), nonRequiredIntList?.ToList(), requiredNullableString, requiredNullableInt, requiredNullableStringList?.ToList(), requiredNullableIntList?.ToList(), nonRequiredNullableString, nonRequiredNullableInt, nonRequiredNullableStringList?.ToList(), nonRequiredNullableIntList?.ToList(), vector, vectorReadOnly, vectorReadOnlyRequired, vectorRequired, vectorNullable, vectorReadOnlyNullable, vectorReadOnlyRequiredNullable, vectorRequiredNullable, serializedAdditionalRawData: null); + } + /// Initializes a new instance of . /// /// @@ -53,7 +93,7 @@ public static MixedModel MixedModel(string requiredString = null, int requiredIn nonRequiredNullableStringList ??= new List(); nonRequiredNullableIntList ??= new List(); - return new MixedModel(requiredString, requiredInt, requiredStringList?.ToList(), requiredIntList?.ToList(), nonRequiredString, nonRequiredInt, nonRequiredStringList?.ToList(), nonRequiredIntList?.ToList(), requiredNullableString, requiredNullableInt, requiredNullableStringList?.ToList(), requiredNullableIntList?.ToList(), nonRequiredNullableString, nonRequiredNullableInt, nonRequiredNullableStringList?.ToList(), nonRequiredNullableIntList?.ToList(), requiredReadonlyInt, nonRequiredReadonlyInt, vector, vectorReadOnly, vectorReadOnlyRequired, vectorRequired, vectorNullable, vectorReadOnlyNullable, vectorReadOnlyRequiredNullable, vectorRequiredNullable); + return new MixedModel(requiredString, requiredInt, requiredStringList?.ToList(), requiredIntList?.ToList(), nonRequiredString, nonRequiredInt, nonRequiredStringList?.ToList(), nonRequiredIntList?.ToList(), requiredNullableString, requiredNullableInt, requiredNullableStringList?.ToList(), requiredNullableIntList?.ToList(), nonRequiredNullableString, nonRequiredNullableInt, nonRequiredNullableStringList?.ToList(), nonRequiredNullableIntList?.ToList(), requiredReadonlyInt, nonRequiredReadonlyInt, vector, vectorReadOnly, vectorReadOnlyRequired, vectorRequired, vectorNullable, vectorReadOnlyNullable, vectorReadOnlyRequiredNullable, vectorRequiredNullable, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -95,7 +135,7 @@ public static OutputModel OutputModel(string requiredString = null, int required nonRequiredNullableStringList ??= new List(); nonRequiredNullableIntList ??= new List(); - return new OutputModel(requiredString, requiredInt, requiredStringList?.ToList(), requiredIntList?.ToList(), nonRequiredString, nonRequiredInt, nonRequiredStringList?.ToList(), nonRequiredIntList?.ToList(), requiredNullableString, requiredNullableInt, requiredNullableStringList?.ToList(), requiredNullableIntList?.ToList(), nonRequiredNullableString, nonRequiredNullableInt, nonRequiredNullableStringList?.ToList(), nonRequiredNullableIntList?.ToList(), requiredReadonlyInt, nonRequiredReadonlyInt, vector, vectorReadOnly, vectorReadOnlyRequired, vectorRequired, vectorNullable, vectorReadOnlyNullable, vectorReadOnlyRequiredNullable, vectorRequiredNullable); + return new OutputModel(requiredString, requiredInt, requiredStringList?.ToList(), requiredIntList?.ToList(), nonRequiredString, nonRequiredInt, nonRequiredStringList?.ToList(), nonRequiredIntList?.ToList(), requiredNullableString, requiredNullableInt, requiredNullableStringList?.ToList(), requiredNullableIntList?.ToList(), nonRequiredNullableString, nonRequiredNullableInt, nonRequiredNullableStringList?.ToList(), nonRequiredNullableIntList?.ToList(), requiredReadonlyInt, nonRequiredReadonlyInt, vector, vectorReadOnly, vectorReadOnlyRequired, vectorRequired, vectorNullable, vectorReadOnlyNullable, vectorReadOnlyRequiredNullable, vectorRequiredNullable, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -106,7 +146,7 @@ public static MixedModelWithReadonlyProperty MixedModelWithReadonlyProperty(Read { readonlyListProperty ??= new List(); - return new MixedModelWithReadonlyProperty(readonlyProperty, readonlyListProperty?.ToList()); + return new MixedModelWithReadonlyProperty(readonlyProperty, readonlyListProperty?.ToList(), serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -114,7 +154,7 @@ public static MixedModelWithReadonlyProperty MixedModelWithReadonlyProperty(Read /// A new instance for mocking. public static ReadonlyModel ReadonlyModel(string name = null) { - return new ReadonlyModel(name); + return new ReadonlyModel(name, serializedAdditionalRawData: null); } } } diff --git a/test/TestProjects/ModelShapes/Generated/Models/ErrorModel.Serialization.cs b/test/TestProjects/ModelShapes/Generated/Models/ErrorModel.Serialization.cs index 5e5b9bcf241..64cb5ee972d 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/ErrorModel.Serialization.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/ErrorModel.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace ModelShapes.Models { - internal partial class ErrorModel + internal partial class ErrorModel : IUtf8JsonSerializable, IJsonModel { - internal static ErrorModel DeserializeErrorModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ErrorModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Code)) + { + writer.WritePropertyName("Code"u8); + writer.WriteStringValue(Code); + } + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("Status"u8); + writer.WriteStringValue(Status); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ErrorModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ErrorModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeErrorModel(document.RootElement, options); + } + + internal static ErrorModel DeserializeErrorModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional code = default; Optional status = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("Code"u8)) @@ -32,8 +90,44 @@ internal static ErrorModel DeserializeErrorModel(JsonElement element) status = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ErrorModel(code.Value, status.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ErrorModel)} does not support '{options.Format}' format."); } - return new ErrorModel(code.Value, status.Value); } + + ErrorModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeErrorModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ErrorModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/ModelShapes/Generated/Models/ErrorModel.cs b/test/TestProjects/ModelShapes/Generated/Models/ErrorModel.cs index 25900631b30..a60f71a40d4 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/ErrorModel.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/ErrorModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelShapes.Models { /// The ErrorModel. internal partial class ErrorModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ErrorModel() { @@ -18,10 +53,12 @@ internal ErrorModel() /// Initializes a new instance of . /// /// - internal ErrorModel(string code, string status) + /// Keeps track of any properties unknown to the library. + internal ErrorModel(string code, string status, IDictionary serializedAdditionalRawData) { Code = code; Status = status; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the code. diff --git a/test/TestProjects/ModelShapes/Generated/Models/InputModel.Serialization.cs b/test/TestProjects/ModelShapes/Generated/Models/InputModel.Serialization.cs index ba41a13f4ec..d7904d32188 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/InputModel.Serialization.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/InputModel.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace ModelShapes.Models { - public partial class InputModel : IUtf8JsonSerializable + public partial class InputModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("RequiredString"u8); writer.WriteStringValue(RequiredString); @@ -177,6 +188,26 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && Optional.IsDefined(VectorReadOnly)) + { + writer.WritePropertyName("vectorReadOnly"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnly.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W") + { + writer.WritePropertyName("vectorReadOnlyRequired"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnlyRequired.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } writer.WritePropertyName("vectorRequired"u8); writer.WriteStartArray(); foreach (var item in VectorRequired.Span) @@ -201,6 +232,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNull("vectorNullable"); } } + if (options.Format != "W" && Optional.IsDefined(VectorReadOnlyNullable)) + { + if (VectorReadOnlyNullable != null) + { + writer.WritePropertyName("vectorReadOnlyNullable"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnlyNullable.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorReadOnlyNullable"); + } + } + if (options.Format != "W") + { + if (VectorReadOnlyRequiredNullable != null) + { + writer.WritePropertyName("vectorReadOnlyRequiredNullable"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnlyRequiredNullable.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorReadOnlyRequiredNullable"); + } + } if (VectorRequiredNullable != null) { writer.WritePropertyName("vectorRequiredNullable"u8); @@ -215,7 +280,408 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) { writer.WriteNull("vectorRequiredNullable"); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + InputModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInputModel(document.RootElement, options); + } + + internal static InputModel DeserializeInputModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string requiredString = default; + int requiredInt = default; + IList requiredStringList = default; + IList requiredIntList = default; + Optional nonRequiredString = default; + Optional nonRequiredInt = default; + Optional> nonRequiredStringList = default; + Optional> nonRequiredIntList = default; + string requiredNullableString = default; + int? requiredNullableInt = default; + IList requiredNullableStringList = default; + IList requiredNullableIntList = default; + Optional nonRequiredNullableString = default; + Optional nonRequiredNullableInt = default; + Optional> nonRequiredNullableStringList = default; + Optional> nonRequiredNullableIntList = default; + Optional> vector = default; + Optional> vectorReadOnly = default; + ReadOnlyMemory vectorReadOnlyRequired = default; + ReadOnlyMemory vectorRequired = default; + Optional?> vectorNullable = default; + Optional?> vectorReadOnlyNullable = default; + ReadOnlyMemory? vectorReadOnlyRequiredNullable = default; + ReadOnlyMemory? vectorRequiredNullable = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("RequiredString"u8)) + { + requiredString = property.Value.GetString(); + continue; + } + if (property.NameEquals("RequiredInt"u8)) + { + requiredInt = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("RequiredStringList"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + requiredStringList = array; + continue; + } + if (property.NameEquals("RequiredIntList"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + requiredIntList = array; + continue; + } + if (property.NameEquals("NonRequiredString"u8)) + { + nonRequiredString = property.Value.GetString(); + continue; + } + if (property.NameEquals("NonRequiredInt"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + nonRequiredInt = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("NonRequiredStringList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + nonRequiredStringList = array; + continue; + } + if (property.NameEquals("NonRequiredIntList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + nonRequiredIntList = array; + continue; + } + if (property.NameEquals("RequiredNullableString"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + requiredNullableString = null; + continue; + } + requiredNullableString = property.Value.GetString(); + continue; + } + if (property.NameEquals("RequiredNullableInt"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + requiredNullableInt = null; + continue; + } + requiredNullableInt = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("RequiredNullableStringList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + requiredNullableStringList = new ChangeTrackingList(); + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + requiredNullableStringList = array; + continue; + } + if (property.NameEquals("RequiredNullableIntList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + requiredNullableIntList = new ChangeTrackingList(); + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + requiredNullableIntList = array; + continue; + } + if (property.NameEquals("NonRequiredNullableString"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + nonRequiredNullableString = null; + continue; + } + nonRequiredNullableString = property.Value.GetString(); + continue; + } + if (property.NameEquals("NonRequiredNullableInt"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + nonRequiredNullableInt = null; + continue; + } + nonRequiredNullableInt = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("NonRequiredNullableStringList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + nonRequiredNullableStringList = array; + continue; + } + if (property.NameEquals("NonRequiredNullableIntList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + nonRequiredNullableIntList = array; + continue; + } + if (property.NameEquals("vector"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + int index = 0; + float[] array = new float[property.Value.GetArrayLength()]; + foreach (var item in property.Value.EnumerateArray()) + { + array[index] = item.GetSingle(); + index++; + } + vector = new ReadOnlyMemory(array); + continue; + } + if (property.NameEquals("vectorReadOnly"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + int index = 0; + float[] array = new float[property.Value.GetArrayLength()]; + foreach (var item in property.Value.EnumerateArray()) + { + array[index] = item.GetSingle(); + index++; + } + vectorReadOnly = new ReadOnlyMemory(array); + continue; + } + if (property.NameEquals("vectorReadOnlyRequired"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + int index = 0; + float[] array = new float[property.Value.GetArrayLength()]; + foreach (var item in property.Value.EnumerateArray()) + { + array[index] = item.GetSingle(); + index++; + } + vectorReadOnlyRequired = new ReadOnlyMemory(array); + continue; + } + if (property.NameEquals("vectorRequired"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + int index = 0; + float[] array = new float[property.Value.GetArrayLength()]; + foreach (var item in property.Value.EnumerateArray()) + { + array[index] = item.GetSingle(); + index++; + } + vectorRequired = new ReadOnlyMemory(array); + continue; + } + if (property.NameEquals("vectorNullable"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + int index = 0; + float[] array = new float[property.Value.GetArrayLength()]; + foreach (var item in property.Value.EnumerateArray()) + { + array[index] = item.GetSingle(); + index++; + } + vectorNullable = new ReadOnlyMemory?(array); + continue; + } + if (property.NameEquals("vectorReadOnlyNullable"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + int index = 0; + float[] array = new float[property.Value.GetArrayLength()]; + foreach (var item in property.Value.EnumerateArray()) + { + array[index] = item.GetSingle(); + index++; + } + vectorReadOnlyNullable = new ReadOnlyMemory?(array); + continue; + } + if (property.NameEquals("vectorReadOnlyRequiredNullable"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + int index = 0; + float[] array = new float[property.Value.GetArrayLength()]; + foreach (var item in property.Value.EnumerateArray()) + { + array[index] = item.GetSingle(); + index++; + } + vectorReadOnlyRequiredNullable = new ReadOnlyMemory?(array); + continue; + } + if (property.NameEquals("vectorRequiredNullable"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + int index = 0; + float[] array = new float[property.Value.GetArrayLength()]; + foreach (var item in property.Value.EnumerateArray()) + { + array[index] = item.GetSingle(); + index++; + } + vectorRequiredNullable = new ReadOnlyMemory?(array); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new InputModel(requiredString, requiredInt, requiredStringList, requiredIntList, nonRequiredString.Value, Optional.ToNullable(nonRequiredInt), Optional.ToList(nonRequiredStringList), Optional.ToList(nonRequiredIntList), requiredNullableString, requiredNullableInt, requiredNullableStringList, requiredNullableIntList, nonRequiredNullableString.Value, Optional.ToNullable(nonRequiredNullableInt), Optional.ToList(nonRequiredNullableStringList), Optional.ToList(nonRequiredNullableIntList), vector, vectorReadOnly, vectorReadOnlyRequired, vectorRequired, Optional.ToNullable(vectorNullable), Optional.ToNullable(vectorReadOnlyNullable), vectorReadOnlyRequiredNullable, vectorRequiredNullable, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InputModel)} does not support '{options.Format}' format."); + } + } + + InputModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeInputModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InputModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/ModelShapes/Generated/Models/InputModel.cs b/test/TestProjects/ModelShapes/Generated/Models/InputModel.cs index 5cc4031b77a..9a3301cf7c0 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/InputModel.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/InputModel.cs @@ -15,6 +15,38 @@ namespace ModelShapes.Models /// The InputModel. public partial class InputModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// @@ -80,7 +112,8 @@ public InputModel(string requiredString, int requiredInt, IEnumerable re /// The vector representation of a search query. /// The vector representation of a search query. /// The vector representation of a search query. - internal InputModel(string requiredString, int requiredInt, IList requiredStringList, IList requiredIntList, string nonRequiredString, int? nonRequiredInt, IList nonRequiredStringList, IList nonRequiredIntList, string requiredNullableString, int? requiredNullableInt, IList requiredNullableStringList, IList requiredNullableIntList, string nonRequiredNullableString, int? nonRequiredNullableInt, IList nonRequiredNullableStringList, IList nonRequiredNullableIntList, ReadOnlyMemory vector, ReadOnlyMemory vectorReadOnly, ReadOnlyMemory vectorReadOnlyRequired, ReadOnlyMemory vectorRequired, ReadOnlyMemory? vectorNullable, ReadOnlyMemory? vectorReadOnlyNullable, ReadOnlyMemory? vectorReadOnlyRequiredNullable, ReadOnlyMemory? vectorRequiredNullable) + /// Keeps track of any properties unknown to the library. + internal InputModel(string requiredString, int requiredInt, IList requiredStringList, IList requiredIntList, string nonRequiredString, int? nonRequiredInt, IList nonRequiredStringList, IList nonRequiredIntList, string requiredNullableString, int? requiredNullableInt, IList requiredNullableStringList, IList requiredNullableIntList, string nonRequiredNullableString, int? nonRequiredNullableInt, IList nonRequiredNullableStringList, IList nonRequiredNullableIntList, ReadOnlyMemory vector, ReadOnlyMemory vectorReadOnly, ReadOnlyMemory vectorReadOnlyRequired, ReadOnlyMemory vectorRequired, ReadOnlyMemory? vectorNullable, ReadOnlyMemory? vectorReadOnlyNullable, ReadOnlyMemory? vectorReadOnlyRequiredNullable, ReadOnlyMemory? vectorRequiredNullable, IDictionary serializedAdditionalRawData) { RequiredString = requiredString; RequiredInt = requiredInt; @@ -106,6 +139,12 @@ internal InputModel(string requiredString, int requiredInt, IList requir VectorReadOnlyNullable = vectorReadOnlyNullable; VectorReadOnlyRequiredNullable = vectorReadOnlyRequiredNullable; VectorRequiredNullable = vectorRequiredNullable; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal InputModel() + { } /// Gets the required string. diff --git a/test/TestProjects/ModelShapes/Generated/Models/MixedModel.Serialization.cs b/test/TestProjects/ModelShapes/Generated/Models/MixedModel.Serialization.cs index a23b909bc52..42bd754905c 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/MixedModel.Serialization.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/MixedModel.Serialization.cs @@ -6,16 +6,25 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace ModelShapes.Models { - public partial class MixedModel : IUtf8JsonSerializable + public partial class MixedModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MixedModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("RequiredString"u8); writer.WriteStringValue(RequiredString); @@ -169,6 +178,16 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNull("NonRequiredNullableIntList"); } } + if (options.Format != "W") + { + writer.WritePropertyName("RequiredReadonlyInt"u8); + writer.WriteNumberValue(RequiredReadonlyInt); + } + if (options.Format != "W" && Optional.IsDefined(NonRequiredReadonlyInt)) + { + writer.WritePropertyName("NonRequiredReadonlyInt"u8); + writer.WriteNumberValue(NonRequiredReadonlyInt.Value); + } if (Optional.IsDefined(Vector)) { writer.WritePropertyName("vector"u8); @@ -179,6 +198,26 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && Optional.IsDefined(VectorReadOnly)) + { + writer.WritePropertyName("vectorReadOnly"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnly.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W") + { + writer.WritePropertyName("vectorReadOnlyRequired"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnlyRequired.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } writer.WritePropertyName("vectorRequired"u8); writer.WriteStartArray(); foreach (var item in VectorRequired.Span) @@ -203,6 +242,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNull("vectorNullable"); } } + if (options.Format != "W" && Optional.IsDefined(VectorReadOnlyNullable)) + { + if (VectorReadOnlyNullable != null) + { + writer.WritePropertyName("vectorReadOnlyNullable"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnlyNullable.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorReadOnlyNullable"); + } + } + if (options.Format != "W") + { + if (VectorReadOnlyRequiredNullable != null) + { + writer.WritePropertyName("vectorReadOnlyRequiredNullable"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnlyRequiredNullable.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorReadOnlyRequiredNullable"); + } + } if (VectorRequiredNullable != null) { writer.WritePropertyName("vectorRequiredNullable"u8); @@ -217,11 +290,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) { writer.WriteNull("vectorRequiredNullable"); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static MixedModel DeserializeMixedModel(JsonElement element) + MixedModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MixedModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeMixedModel(document.RootElement, options); + } + + internal static MixedModel DeserializeMixedModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -252,6 +354,8 @@ internal static MixedModel DeserializeMixedModel(JsonElement element) Optional?> vectorReadOnlyNullable = default; ReadOnlyMemory? vectorReadOnlyRequiredNullable = default; ReadOnlyMemory? vectorRequiredNullable = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("RequiredString"u8)) @@ -566,8 +670,44 @@ internal static MixedModel DeserializeMixedModel(JsonElement element) vectorRequiredNullable = new ReadOnlyMemory?(array); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new MixedModel(requiredString, requiredInt, requiredStringList, requiredIntList, nonRequiredString.Value, Optional.ToNullable(nonRequiredInt), Optional.ToList(nonRequiredStringList), Optional.ToList(nonRequiredIntList), requiredNullableString, requiredNullableInt, requiredNullableStringList, requiredNullableIntList, nonRequiredNullableString.Value, Optional.ToNullable(nonRequiredNullableInt), Optional.ToList(nonRequiredNullableStringList), Optional.ToList(nonRequiredNullableIntList), requiredReadonlyInt, Optional.ToNullable(nonRequiredReadonlyInt), vector, vectorReadOnly, vectorReadOnlyRequired, vectorRequired, Optional.ToNullable(vectorNullable), Optional.ToNullable(vectorReadOnlyNullable), vectorReadOnlyRequiredNullable, vectorRequiredNullable, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(MixedModel)} does not support '{options.Format}' format."); } - return new MixedModel(requiredString, requiredInt, requiredStringList, requiredIntList, nonRequiredString.Value, Optional.ToNullable(nonRequiredInt), Optional.ToList(nonRequiredStringList), Optional.ToList(nonRequiredIntList), requiredNullableString, requiredNullableInt, requiredNullableStringList, requiredNullableIntList, nonRequiredNullableString.Value, Optional.ToNullable(nonRequiredNullableInt), Optional.ToList(nonRequiredNullableStringList), Optional.ToList(nonRequiredNullableIntList), requiredReadonlyInt, Optional.ToNullable(nonRequiredReadonlyInt), vector, vectorReadOnly, vectorReadOnlyRequired, vectorRequired, Optional.ToNullable(vectorNullable), Optional.ToNullable(vectorReadOnlyNullable), vectorReadOnlyRequiredNullable, vectorRequiredNullable); } + + MixedModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeMixedModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(MixedModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/ModelShapes/Generated/Models/MixedModel.cs b/test/TestProjects/ModelShapes/Generated/Models/MixedModel.cs index 0ef6c1a6be6..e3806093b16 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/MixedModel.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/MixedModel.cs @@ -15,6 +15,38 @@ namespace ModelShapes.Models /// The MixedModel. public partial class MixedModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// @@ -84,7 +116,8 @@ public MixedModel(string requiredString, int requiredInt, IEnumerable re /// The vector representation of a search query. /// The vector representation of a search query. /// The vector representation of a search query. - internal MixedModel(string requiredString, int requiredInt, IList requiredStringList, IList requiredIntList, string nonRequiredString, int? nonRequiredInt, IList nonRequiredStringList, IList nonRequiredIntList, string requiredNullableString, int? requiredNullableInt, IList requiredNullableStringList, IList requiredNullableIntList, string nonRequiredNullableString, int? nonRequiredNullableInt, IList nonRequiredNullableStringList, IList nonRequiredNullableIntList, int requiredReadonlyInt, int? nonRequiredReadonlyInt, ReadOnlyMemory vector, ReadOnlyMemory vectorReadOnly, ReadOnlyMemory vectorReadOnlyRequired, ReadOnlyMemory vectorRequired, ReadOnlyMemory? vectorNullable, ReadOnlyMemory? vectorReadOnlyNullable, ReadOnlyMemory? vectorReadOnlyRequiredNullable, ReadOnlyMemory? vectorRequiredNullable) + /// Keeps track of any properties unknown to the library. + internal MixedModel(string requiredString, int requiredInt, IList requiredStringList, IList requiredIntList, string nonRequiredString, int? nonRequiredInt, IList nonRequiredStringList, IList nonRequiredIntList, string requiredNullableString, int? requiredNullableInt, IList requiredNullableStringList, IList requiredNullableIntList, string nonRequiredNullableString, int? nonRequiredNullableInt, IList nonRequiredNullableStringList, IList nonRequiredNullableIntList, int requiredReadonlyInt, int? nonRequiredReadonlyInt, ReadOnlyMemory vector, ReadOnlyMemory vectorReadOnly, ReadOnlyMemory vectorReadOnlyRequired, ReadOnlyMemory vectorRequired, ReadOnlyMemory? vectorNullable, ReadOnlyMemory? vectorReadOnlyNullable, ReadOnlyMemory? vectorReadOnlyRequiredNullable, ReadOnlyMemory? vectorRequiredNullable, IDictionary serializedAdditionalRawData) { RequiredString = requiredString; RequiredInt = requiredInt; @@ -112,6 +145,12 @@ internal MixedModel(string requiredString, int requiredInt, IList requir VectorReadOnlyNullable = vectorReadOnlyNullable; VectorReadOnlyRequiredNullable = vectorReadOnlyRequiredNullable; VectorRequiredNullable = vectorRequiredNullable; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal MixedModel() + { } /// Gets or sets the required string. diff --git a/test/TestProjects/ModelShapes/Generated/Models/MixedModelWithReadonlyProperty.Serialization.cs b/test/TestProjects/ModelShapes/Generated/Models/MixedModelWithReadonlyProperty.Serialization.cs index f3f38681eee..511697820e3 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/MixedModelWithReadonlyProperty.Serialization.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/MixedModelWithReadonlyProperty.Serialization.cs @@ -5,28 +5,84 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace ModelShapes.Models { - public partial class MixedModelWithReadonlyProperty : IUtf8JsonSerializable + public partial class MixedModelWithReadonlyProperty : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MixedModelWithReadonlyProperty)} does not support '{format}' format."); + } + writer.WriteStartObject(); + if (options.Format != "W" && Optional.IsDefined(ReadonlyProperty)) + { + writer.WritePropertyName("ReadonlyProperty"u8); + writer.WriteObjectValue(ReadonlyProperty); + } + if (options.Format != "W" && Optional.IsCollectionDefined(ReadonlyListProperty)) + { + writer.WritePropertyName("ReadonlyListProperty"u8); + writer.WriteStartArray(); + foreach (var item in ReadonlyListProperty) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static MixedModelWithReadonlyProperty DeserializeMixedModelWithReadonlyProperty(JsonElement element) + MixedModelWithReadonlyProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MixedModelWithReadonlyProperty)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeMixedModelWithReadonlyProperty(document.RootElement, options); + } + + internal static MixedModelWithReadonlyProperty DeserializeMixedModelWithReadonlyProperty(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional readonlyProperty = default; Optional> readonlyListProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("ReadonlyProperty"u8)) @@ -52,8 +108,44 @@ internal static MixedModelWithReadonlyProperty DeserializeMixedModelWithReadonly readonlyListProperty = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new MixedModelWithReadonlyProperty(readonlyProperty.Value, Optional.ToList(readonlyListProperty), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(MixedModelWithReadonlyProperty)} does not support '{options.Format}' format."); + } + } + + MixedModelWithReadonlyProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeMixedModelWithReadonlyProperty(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(MixedModelWithReadonlyProperty)} does not support '{options.Format}' format."); } - return new MixedModelWithReadonlyProperty(readonlyProperty.Value, Optional.ToList(readonlyListProperty)); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/ModelShapes/Generated/Models/MixedModelWithReadonlyProperty.cs b/test/TestProjects/ModelShapes/Generated/Models/MixedModelWithReadonlyProperty.cs index a5a82f0a54d..656ba5c650d 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/MixedModelWithReadonlyProperty.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/MixedModelWithReadonlyProperty.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace ModelShapes.Models /// The MixedModelWithReadonlyProperty. public partial class MixedModelWithReadonlyProperty { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public MixedModelWithReadonlyProperty() { @@ -22,10 +55,12 @@ public MixedModelWithReadonlyProperty() /// Initializes a new instance of . /// /// - internal MixedModelWithReadonlyProperty(ReadonlyModel readonlyProperty, IReadOnlyList readonlyListProperty) + /// Keeps track of any properties unknown to the library. + internal MixedModelWithReadonlyProperty(ReadonlyModel readonlyProperty, IReadOnlyList readonlyListProperty, IDictionary serializedAdditionalRawData) { ReadonlyProperty = readonlyProperty; ReadonlyListProperty = readonlyListProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the readonly property. diff --git a/test/TestProjects/ModelShapes/Generated/Models/OutputModel.Serialization.cs b/test/TestProjects/ModelShapes/Generated/Models/OutputModel.Serialization.cs index eeeee71652d..8d81e20845a 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/OutputModel.Serialization.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/OutputModel.Serialization.cs @@ -6,16 +6,324 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace ModelShapes.Models { - public partial class OutputModel + public partial class OutputModel : IUtf8JsonSerializable, IJsonModel { - internal static OutputModel DeserializeOutputModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("RequiredString"u8); + writer.WriteStringValue(RequiredString); + writer.WritePropertyName("RequiredInt"u8); + writer.WriteNumberValue(RequiredInt); + writer.WritePropertyName("RequiredStringList"u8); + writer.WriteStartArray(); + foreach (var item in RequiredStringList) + { + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + writer.WritePropertyName("RequiredIntList"u8); + writer.WriteStartArray(); + foreach (var item in RequiredIntList) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + if (Optional.IsDefined(NonRequiredString)) + { + writer.WritePropertyName("NonRequiredString"u8); + writer.WriteStringValue(NonRequiredString); + } + if (Optional.IsDefined(NonRequiredInt)) + { + writer.WritePropertyName("NonRequiredInt"u8); + writer.WriteNumberValue(NonRequiredInt.Value); + } + if (Optional.IsCollectionDefined(NonRequiredStringList)) + { + writer.WritePropertyName("NonRequiredStringList"u8); + writer.WriteStartArray(); + foreach (var item in NonRequiredStringList) + { + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(NonRequiredIntList)) + { + writer.WritePropertyName("NonRequiredIntList"u8); + writer.WriteStartArray(); + foreach (var item in NonRequiredIntList) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + if (RequiredNullableString != null) + { + writer.WritePropertyName("RequiredNullableString"u8); + writer.WriteStringValue(RequiredNullableString); + } + else + { + writer.WriteNull("RequiredNullableString"); + } + if (RequiredNullableInt != null) + { + writer.WritePropertyName("RequiredNullableInt"u8); + writer.WriteNumberValue(RequiredNullableInt.Value); + } + else + { + writer.WriteNull("RequiredNullableInt"); + } + if (RequiredNullableStringList != null && Optional.IsCollectionDefined(RequiredNullableStringList)) + { + writer.WritePropertyName("RequiredNullableStringList"u8); + writer.WriteStartArray(); + foreach (var item in RequiredNullableStringList) + { + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("RequiredNullableStringList"); + } + if (RequiredNullableIntList != null && Optional.IsCollectionDefined(RequiredNullableIntList)) + { + writer.WritePropertyName("RequiredNullableIntList"u8); + writer.WriteStartArray(); + foreach (var item in RequiredNullableIntList) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("RequiredNullableIntList"); + } + if (Optional.IsDefined(NonRequiredNullableString)) + { + if (NonRequiredNullableString != null) + { + writer.WritePropertyName("NonRequiredNullableString"u8); + writer.WriteStringValue(NonRequiredNullableString); + } + else + { + writer.WriteNull("NonRequiredNullableString"); + } + } + if (Optional.IsDefined(NonRequiredNullableInt)) + { + if (NonRequiredNullableInt != null) + { + writer.WritePropertyName("NonRequiredNullableInt"u8); + writer.WriteNumberValue(NonRequiredNullableInt.Value); + } + else + { + writer.WriteNull("NonRequiredNullableInt"); + } + } + if (Optional.IsCollectionDefined(NonRequiredNullableStringList)) + { + if (NonRequiredNullableStringList != null) + { + writer.WritePropertyName("NonRequiredNullableStringList"u8); + writer.WriteStartArray(); + foreach (var item in NonRequiredNullableStringList) + { + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("NonRequiredNullableStringList"); + } + } + if (Optional.IsCollectionDefined(NonRequiredNullableIntList)) + { + if (NonRequiredNullableIntList != null) + { + writer.WritePropertyName("NonRequiredNullableIntList"u8); + writer.WriteStartArray(); + foreach (var item in NonRequiredNullableIntList) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("NonRequiredNullableIntList"); + } + } + if (options.Format != "W") + { + writer.WritePropertyName("RequiredReadonlyInt"u8); + writer.WriteNumberValue(RequiredReadonlyInt); + } + if (options.Format != "W" && Optional.IsDefined(NonRequiredReadonlyInt)) + { + writer.WritePropertyName("NonRequiredReadonlyInt"u8); + writer.WriteNumberValue(NonRequiredReadonlyInt.Value); + } + if (Optional.IsDefined(Vector)) + { + writer.WritePropertyName("vector"u8); + writer.WriteStartArray(); + foreach (var item in Vector.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W" && Optional.IsDefined(VectorReadOnly)) + { + writer.WritePropertyName("vectorReadOnly"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnly.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W") + { + writer.WritePropertyName("vectorReadOnlyRequired"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnlyRequired.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + writer.WritePropertyName("vectorRequired"u8); + writer.WriteStartArray(); + foreach (var item in VectorRequired.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + if (Optional.IsDefined(VectorNullable)) + { + if (VectorNullable != null) + { + writer.WritePropertyName("vectorNullable"u8); + writer.WriteStartArray(); + foreach (var item in VectorNullable.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorNullable"); + } + } + if (options.Format != "W" && Optional.IsDefined(VectorReadOnlyNullable)) + { + if (VectorReadOnlyNullable != null) + { + writer.WritePropertyName("vectorReadOnlyNullable"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnlyNullable.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorReadOnlyNullable"); + } + } + if (options.Format != "W") + { + if (VectorReadOnlyRequiredNullable != null) + { + writer.WritePropertyName("vectorReadOnlyRequiredNullable"u8); + writer.WriteStartArray(); + foreach (var item in VectorReadOnlyRequiredNullable.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorReadOnlyRequiredNullable"); + } + } + if (VectorRequiredNullable != null) + { + writer.WritePropertyName("vectorRequiredNullable"u8); + writer.WriteStartArray(); + foreach (var item in VectorRequiredNullable.Value.Span) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("vectorRequiredNullable"); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + OutputModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeOutputModel(document.RootElement, options); + } + + internal static OutputModel DeserializeOutputModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -46,6 +354,8 @@ internal static OutputModel DeserializeOutputModel(JsonElement element) Optional?> vectorReadOnlyNullable = default; ReadOnlyMemory? vectorReadOnlyRequiredNullable = default; ReadOnlyMemory? vectorRequiredNullable = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("RequiredString"u8)) @@ -360,8 +670,44 @@ internal static OutputModel DeserializeOutputModel(JsonElement element) vectorRequiredNullable = new ReadOnlyMemory?(array); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new OutputModel(requiredString, requiredInt, requiredStringList, requiredIntList, nonRequiredString.Value, Optional.ToNullable(nonRequiredInt), Optional.ToList(nonRequiredStringList), Optional.ToList(nonRequiredIntList), requiredNullableString, requiredNullableInt, requiredNullableStringList, requiredNullableIntList, nonRequiredNullableString.Value, Optional.ToNullable(nonRequiredNullableInt), Optional.ToList(nonRequiredNullableStringList), Optional.ToList(nonRequiredNullableIntList), requiredReadonlyInt, Optional.ToNullable(nonRequiredReadonlyInt), vector, vectorReadOnly, vectorReadOnlyRequired, vectorRequired, Optional.ToNullable(vectorNullable), Optional.ToNullable(vectorReadOnlyNullable), vectorReadOnlyRequiredNullable, vectorRequiredNullable, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(OutputModel)} does not support '{options.Format}' format."); } - return new OutputModel(requiredString, requiredInt, requiredStringList, requiredIntList, nonRequiredString.Value, Optional.ToNullable(nonRequiredInt), Optional.ToList(nonRequiredStringList), Optional.ToList(nonRequiredIntList), requiredNullableString, requiredNullableInt, requiredNullableStringList, requiredNullableIntList, nonRequiredNullableString.Value, Optional.ToNullable(nonRequiredNullableInt), Optional.ToList(nonRequiredNullableStringList), Optional.ToList(nonRequiredNullableIntList), requiredReadonlyInt, Optional.ToNullable(nonRequiredReadonlyInt), vector, vectorReadOnly, vectorReadOnlyRequired, vectorRequired, Optional.ToNullable(vectorNullable), Optional.ToNullable(vectorReadOnlyNullable), vectorReadOnlyRequiredNullable, vectorRequiredNullable); } + + OutputModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeOutputModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(OutputModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/ModelShapes/Generated/Models/OutputModel.cs b/test/TestProjects/ModelShapes/Generated/Models/OutputModel.cs index 1d5ea3be10a..cf1a22b912f 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/OutputModel.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/OutputModel.cs @@ -15,6 +15,38 @@ namespace ModelShapes.Models /// The OutputModel. public partial class OutputModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// @@ -84,7 +116,8 @@ internal OutputModel(string requiredString, int requiredInt, IEnumerable /// The vector representation of a search query. /// The vector representation of a search query. /// The vector representation of a search query. - internal OutputModel(string requiredString, int requiredInt, IReadOnlyList requiredStringList, IReadOnlyList requiredIntList, string nonRequiredString, int? nonRequiredInt, IReadOnlyList nonRequiredStringList, IReadOnlyList nonRequiredIntList, string requiredNullableString, int? requiredNullableInt, IReadOnlyList requiredNullableStringList, IReadOnlyList requiredNullableIntList, string nonRequiredNullableString, int? nonRequiredNullableInt, IReadOnlyList nonRequiredNullableStringList, IReadOnlyList nonRequiredNullableIntList, int requiredReadonlyInt, int? nonRequiredReadonlyInt, ReadOnlyMemory vector, ReadOnlyMemory vectorReadOnly, ReadOnlyMemory vectorReadOnlyRequired, ReadOnlyMemory vectorRequired, ReadOnlyMemory? vectorNullable, ReadOnlyMemory? vectorReadOnlyNullable, ReadOnlyMemory? vectorReadOnlyRequiredNullable, ReadOnlyMemory? vectorRequiredNullable) + /// Keeps track of any properties unknown to the library. + internal OutputModel(string requiredString, int requiredInt, IReadOnlyList requiredStringList, IReadOnlyList requiredIntList, string nonRequiredString, int? nonRequiredInt, IReadOnlyList nonRequiredStringList, IReadOnlyList nonRequiredIntList, string requiredNullableString, int? requiredNullableInt, IReadOnlyList requiredNullableStringList, IReadOnlyList requiredNullableIntList, string nonRequiredNullableString, int? nonRequiredNullableInt, IReadOnlyList nonRequiredNullableStringList, IReadOnlyList nonRequiredNullableIntList, int requiredReadonlyInt, int? nonRequiredReadonlyInt, ReadOnlyMemory vector, ReadOnlyMemory vectorReadOnly, ReadOnlyMemory vectorReadOnlyRequired, ReadOnlyMemory vectorRequired, ReadOnlyMemory? vectorNullable, ReadOnlyMemory? vectorReadOnlyNullable, ReadOnlyMemory? vectorReadOnlyRequiredNullable, ReadOnlyMemory? vectorRequiredNullable, IDictionary serializedAdditionalRawData) { RequiredString = requiredString; RequiredInt = requiredInt; @@ -112,6 +145,12 @@ internal OutputModel(string requiredString, int requiredInt, IReadOnlyList Initializes a new instance of for deserialization. + internal OutputModel() + { } /// Gets the required string. diff --git a/test/TestProjects/ModelShapes/Generated/Models/ParametersModel.Serialization.cs b/test/TestProjects/ModelShapes/Generated/Models/ParametersModel.Serialization.cs index bf93e0d47a1..4d1cb9c296a 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/ParametersModel.Serialization.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/ParametersModel.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace ModelShapes.Models { - internal partial class ParametersModel : IUtf8JsonSerializable + internal partial class ParametersModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ParametersModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Code)) { @@ -25,7 +36,98 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("Status"u8); writer.WriteStringValue(Status); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + ParametersModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ParametersModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeParametersModel(document.RootElement, options); + } + + internal static ParametersModel DeserializeParametersModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional code = default; + Optional status = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("Code"u8)) + { + code = property.Value.GetString(); + continue; + } + if (property.NameEquals("Status"u8)) + { + status = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ParametersModel(code.Value, status.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ParametersModel)} does not support '{options.Format}' format."); + } + } + + ParametersModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeParametersModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ParametersModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/ModelShapes/Generated/Models/ParametersModel.cs b/test/TestProjects/ModelShapes/Generated/Models/ParametersModel.cs index 59db32a7fe7..d8a43f905e2 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/ParametersModel.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/ParametersModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelShapes.Models { /// The ParametersModel. internal partial class ParametersModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ParametersModel() { @@ -18,10 +53,12 @@ public ParametersModel() /// Initializes a new instance of . /// /// - internal ParametersModel(string code, string status) + /// Keeps track of any properties unknown to the library. + internal ParametersModel(string code, string status, IDictionary serializedAdditionalRawData) { Code = code; Status = status; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the code. diff --git a/test/TestProjects/ModelShapes/Generated/Models/ReadonlyModel.Serialization.cs b/test/TestProjects/ModelShapes/Generated/Models/ReadonlyModel.Serialization.cs index cac8b9465ee..afc2a141702 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/ReadonlyModel.Serialization.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/ReadonlyModel.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace ModelShapes.Models { - public partial class ReadonlyModel + public partial class ReadonlyModel : IUtf8JsonSerializable, IJsonModel { - internal static ReadonlyModel DeserializeReadonlyModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ReadonlyModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Name)) + { + writer.WritePropertyName("Name"u8); + writer.WriteStringValue(Name); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ReadonlyModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ReadonlyModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeReadonlyModel(document.RootElement, options); + } + + internal static ReadonlyModel DeserializeReadonlyModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("Name"u8)) @@ -26,8 +79,44 @@ internal static ReadonlyModel DeserializeReadonlyModel(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ReadonlyModel(name.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ReadonlyModel(name.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ReadonlyModel)} does not support '{options.Format}' format."); + } + } + + ReadonlyModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeReadonlyModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ReadonlyModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/ModelShapes/Generated/Models/ReadonlyModel.cs b/test/TestProjects/ModelShapes/Generated/Models/ReadonlyModel.cs index f0f7dde3cca..7a222e877d3 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/ReadonlyModel.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/ReadonlyModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelShapes.Models { /// The ReadonlyModel. public partial class ReadonlyModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ReadonlyModel() { @@ -17,9 +52,11 @@ internal ReadonlyModel() /// Initializes a new instance of . /// - internal ReadonlyModel(string name) + /// Keeps track of any properties unknown to the library. + internal ReadonlyModel(string name, IDictionary serializedAdditionalRawData) { Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the name. diff --git a/test/TestProjects/ModelShapes/Generated/Models/UnusedModel.cs b/test/TestProjects/ModelShapes/Generated/Models/UnusedModel.cs index 0b7c70aa938..6a3add6e297 100644 --- a/test/TestProjects/ModelShapes/Generated/Models/UnusedModel.cs +++ b/test/TestProjects/ModelShapes/Generated/Models/UnusedModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelShapes.Models { /// The UnusedModel. internal partial class UnusedModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal UnusedModel() { @@ -17,9 +52,11 @@ internal UnusedModel() /// Initializes a new instance of . /// - internal UnusedModel(string unusedString) + /// Keeps track of any properties unknown to the library. + internal UnusedModel(string unusedString, IDictionary serializedAdditionalRawData) { UnusedString = unusedString; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the unused string. diff --git a/test/TestProjects/ModelShapes/ModelShapes.csproj b/test/TestProjects/ModelShapes/ModelShapes.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestProjects/ModelShapes/ModelShapes.csproj +++ b/test/TestProjects/ModelShapes/ModelShapes.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestProjects/ModelShapes/readme.md b/test/TestProjects/ModelShapes/readme.md new file mode 100644 index 00000000000..202645e5144 --- /dev/null +++ b/test/TestProjects/ModelShapes/readme.md @@ -0,0 +1,13 @@ +# ModelShapes + +### AutoRest Configuration +> see https://aka.ms/autorest + +``` yaml +generation1-convenience-client: true +require: $(this-folder)/../../../readme.md +input-file: $(this-folder)/ModelShapes.json +namespace: ModelShapes + +use-model-reader-writer: true +``` diff --git a/test/TestProjects/ModelWithConverterUsage/Customized/ModelStruct.cs b/test/TestProjects/ModelWithConverterUsage/Customized/ModelStruct.cs index af39225eaa4..e7fbd46f735 100644 --- a/test/TestProjects/ModelWithConverterUsage/Customized/ModelStruct.cs +++ b/test/TestProjects/ModelWithConverterUsage/Customized/ModelStruct.cs @@ -5,7 +5,7 @@ namespace ModelWithConverterUsage.Models { - [CodeGenModel(Usage = new[] { "converter"})] + [CodeGenModel(Usage = new[] { "converter" })] public partial struct ModelStruct { } diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Configuration.json b/test/TestProjects/ModelWithConverterUsage/Generated/Configuration.json index 39048a52998..bb1b611a094 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Configuration.json +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/ModelWithConverterUsageModelFactory.cs b/test/TestProjects/ModelWithConverterUsage/Generated/ModelWithConverterUsageModelFactory.cs index 6c09cee60ee..ee97be199fb 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/ModelWithConverterUsageModelFactory.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/ModelWithConverterUsageModelFactory.cs @@ -15,7 +15,7 @@ public static partial class ModelWithConverterUsageModelFactory /// A new instance for mocking. public static OutputModel OutputModel(string outputModelProperty = null) { - return new OutputModel(outputModelProperty); + return new OutputModel(outputModelProperty, serializedAdditionalRawData: null); } } } diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Models/InputModel.Serialization.cs b/test/TestProjects/ModelWithConverterUsage/Generated/Models/InputModel.Serialization.cs index 5b20c34ba82..13aa9636a8a 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Models/InputModel.Serialization.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Models/InputModel.Serialization.cs @@ -6,6 +6,8 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; using Azure.Core; @@ -13,19 +15,112 @@ namespace ModelWithConverterUsage.Models { [JsonConverter(typeof(InputModelConverter))] - public partial class InputModel : IUtf8JsonSerializable + public partial class InputModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(InputModelProperty)) { writer.WritePropertyName("Input_Model_Property"u8); writer.WriteStringValue(InputModelProperty); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + InputModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInputModel(document.RootElement, options); + } + + internal static InputModel DeserializeInputModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional inputModelProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("Input_Model_Property"u8)) + { + inputModelProperty = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new InputModel(inputModelProperty.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InputModel)} does not support '{options.Format}' format."); + } + } + + InputModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeInputModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InputModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + internal partial class InputModelConverter : JsonConverter { public override void Write(Utf8JsonWriter writer, InputModel model, JsonSerializerOptions options) @@ -34,7 +129,8 @@ public override void Write(Utf8JsonWriter writer, InputModel model, JsonSerializ } public override InputModel Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - throw new NotImplementedException(); + using var document = JsonDocument.ParseValue(ref reader); + return DeserializeInputModel(document.RootElement); } } } diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Models/InputModel.cs b/test/TestProjects/ModelWithConverterUsage/Generated/Models/InputModel.cs index 52afdf1f7ff..5c70d92d10f 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Models/InputModel.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Models/InputModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelWithConverterUsage.Models { /// The product documentation. public partial class InputModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public InputModel() { @@ -17,9 +52,11 @@ public InputModel() /// Initializes a new instance of . /// Constant string. - internal InputModel(string inputModelProperty) + /// Keeps track of any properties unknown to the library. + internal InputModel(string inputModelProperty, IDictionary serializedAdditionalRawData) { InputModelProperty = inputModelProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Constant string. diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelClass.Serialization.cs b/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelClass.Serialization.cs index 5e5d795c19b..19cffc12025 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelClass.Serialization.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelClass.Serialization.cs @@ -6,6 +6,8 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; using Azure.Core; @@ -13,10 +15,18 @@ namespace ModelWithConverterUsage.Models { [JsonConverter(typeof(ModelClassConverter))] - public partial class ModelClass : IUtf8JsonSerializable + public partial class ModelClass : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelClass)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(StringProperty)) { @@ -30,11 +40,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("Obj_Property"u8); writer.WriteObjectValue(ObjProperty); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelClass DeserializeModelClass(JsonElement element) + ModelClass IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelClass)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelClass(document.RootElement, options); + } + + internal static ModelClass DeserializeModelClass(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -42,6 +81,8 @@ internal static ModelClass DeserializeModelClass(JsonElement element) Optional stringProperty = default; EnumProperty enumProperty = default; Optional objProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("String_Property"u8)) @@ -63,10 +104,46 @@ internal static ModelClass DeserializeModelClass(JsonElement element) objProperty = Product.DeserializeProduct(property.Value); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ModelClass(stringProperty.Value, enumProperty, objProperty.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelClass(stringProperty.Value, enumProperty, objProperty.Value, serializedAdditionalRawData); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelClass)} does not support '{options.Format}' format."); + } + } + + ModelClass IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelClass(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelClass)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + internal partial class ModelClassConverter : JsonConverter { public override void Write(Utf8JsonWriter writer, ModelClass model, JsonSerializerOptions options) diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelClass.cs b/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelClass.cs index 107518e49dc..f5478df16c5 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelClass.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelClass.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelWithConverterUsage.Models { /// . public partial class ModelClass { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// More Letters. public ModelClass(EnumProperty enumProperty) @@ -21,11 +56,18 @@ public ModelClass(EnumProperty enumProperty) /// /// More Letters. /// The product documentation. - internal ModelClass(string stringProperty, EnumProperty enumProperty, Product objProperty) + /// Keeps track of any properties unknown to the library. + internal ModelClass(string stringProperty, EnumProperty enumProperty, Product objProperty, IDictionary serializedAdditionalRawData) { StringProperty = stringProperty; EnumProperty = enumProperty; ObjProperty = objProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ModelClass() + { } /// Gets or sets the string property. diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelStruct.Serialization.cs b/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelStruct.Serialization.cs index eea411a692d..26928db5a2f 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelStruct.Serialization.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelStruct.Serialization.cs @@ -6,6 +6,8 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; using Azure.Core; @@ -13,22 +15,65 @@ namespace ModelWithConverterUsage.Models { [JsonConverter(typeof(ModelStructConverter))] - public partial struct ModelStruct : IUtf8JsonSerializable + public partial struct ModelStruct : IUtf8JsonSerializable, IJsonModel, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelStruct)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(ModelProperty)) { writer.WritePropertyName("Model_Property"u8); writer.WriteStringValue(ModelProperty); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelStruct DeserializeModelStruct(JsonElement element) + ModelStruct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelStruct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelStruct(document.RootElement, options); + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => ((IJsonModel)this).Write(writer, options); + + object IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => ((IJsonModel)this).Create(ref reader, options); + + internal static ModelStruct DeserializeModelStruct(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + Optional modelProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("Model_Property"u8)) @@ -36,10 +81,52 @@ internal static ModelStruct DeserializeModelStruct(JsonElement element) modelProperty = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ModelStruct(modelProperty.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelStruct(modelProperty.Value, serializedAdditionalRawData); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelStruct)} does not support '{options.Format}' format."); + } + } + + ModelStruct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelStruct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelStruct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => ((IPersistableModel)this).Write(options); + + object IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => ((IPersistableModel)this).Create(data, options); + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => ((IPersistableModel)this).GetFormatFromOptions(options); + internal partial class ModelStructConverter : JsonConverter { public override void Write(Utf8JsonWriter writer, ModelStruct model, JsonSerializerOptions options) diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelStruct.cs b/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelStruct.cs index 6b30e3a501c..8c2557215f9 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelStruct.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Models/ModelStruct.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace ModelWithConverterUsage.Models @@ -13,6 +14,38 @@ namespace ModelWithConverterUsage.Models /// The ModelStruct. public readonly partial struct ModelStruct { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private readonly IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// . /// is null. @@ -23,6 +56,20 @@ public ModelStruct(string modelProperty) ModelProperty = modelProperty; } + /// Initializes a new instance of . + /// . + /// Keeps track of any properties unknown to the library. + internal ModelStruct(string modelProperty, IDictionary serializedAdditionalRawData) + { + ModelProperty = modelProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + public ModelStruct() + { + } + /// . public string ModelProperty { get; } } diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Models/OutputModel.Serialization.cs b/test/TestProjects/ModelWithConverterUsage/Generated/Models/OutputModel.Serialization.cs index 385d89f7a03..4f2142ffdf5 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Models/OutputModel.Serialization.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Models/OutputModel.Serialization.cs @@ -6,6 +6,8 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; using Azure.Core; @@ -13,15 +15,65 @@ namespace ModelWithConverterUsage.Models { [JsonConverter(typeof(OutputModelConverter))] - public partial class OutputModel + public partial class OutputModel : IUtf8JsonSerializable, IJsonModel { - internal static OutputModel DeserializeOutputModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(OutputModelProperty)) + { + writer.WritePropertyName("Output_Model_Property"u8); + writer.WriteStringValue(OutputModelProperty); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + OutputModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeOutputModel(document.RootElement, options); + } + + internal static OutputModel DeserializeOutputModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional outputModelProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("Output_Model_Property"u8)) @@ -29,15 +81,51 @@ internal static OutputModel DeserializeOutputModel(JsonElement element) outputModelProperty = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new OutputModel(outputModelProperty.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new OutputModel(outputModelProperty.Value, serializedAdditionalRawData); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(OutputModel)} does not support '{options.Format}' format."); + } + } + + OutputModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeOutputModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(OutputModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + internal partial class OutputModelConverter : JsonConverter { public override void Write(Utf8JsonWriter writer, OutputModel model, JsonSerializerOptions options) { - throw new NotImplementedException(); + writer.WriteObjectValue(model); } public override OutputModel Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Models/OutputModel.cs b/test/TestProjects/ModelWithConverterUsage/Generated/Models/OutputModel.cs index 47a83ef06fc..f83e6e5dd74 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Models/OutputModel.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Models/OutputModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelWithConverterUsage.Models { /// The product documentation. public partial class OutputModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal OutputModel() { @@ -17,9 +52,11 @@ internal OutputModel() /// Initializes a new instance of . /// Constant string. - internal OutputModel(string outputModelProperty) + /// Keeps track of any properties unknown to the library. + internal OutputModel(string outputModelProperty, IDictionary serializedAdditionalRawData) { OutputModelProperty = outputModelProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Constant string. diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Models/Product.Serialization.cs b/test/TestProjects/ModelWithConverterUsage/Generated/Models/Product.Serialization.cs index 50f16533a76..2a17ed52035 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Models/Product.Serialization.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Models/Product.Serialization.cs @@ -5,31 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace ModelWithConverterUsage.Models { - public partial class Product : IUtf8JsonSerializable + public partial class Product : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(ConstProperty)) { writer.WritePropertyName("Const_Property"u8); writer.WriteStringValue(ConstProperty); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Product DeserializeProduct(JsonElement element) + Product IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProduct(document.RootElement, options); + } + + internal static Product DeserializeProduct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional constProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("Const_Property"u8)) @@ -37,8 +79,44 @@ internal static Product DeserializeProduct(JsonElement element) constProperty = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Product(constProperty.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); } - return new Product(constProperty.Value); } + + Product IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/ModelWithConverterUsage/Generated/Models/Product.cs b/test/TestProjects/ModelWithConverterUsage/Generated/Models/Product.cs index 732ee1d4dfc..922bec36e42 100644 --- a/test/TestProjects/ModelWithConverterUsage/Generated/Models/Product.cs +++ b/test/TestProjects/ModelWithConverterUsage/Generated/Models/Product.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelWithConverterUsage.Models { /// The product documentation. public partial class Product { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Product() { @@ -17,9 +52,11 @@ public Product() /// Initializes a new instance of . /// Constant string. - internal Product(string constProperty) + /// Keeps track of any properties unknown to the library. + internal Product(string constProperty, IDictionary serializedAdditionalRawData) { ConstProperty = constProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Constant string. diff --git a/test/TestProjects/ModelWithConverterUsage/ModelWithConverterUsage.csproj b/test/TestProjects/ModelWithConverterUsage/ModelWithConverterUsage.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestProjects/ModelWithConverterUsage/ModelWithConverterUsage.csproj +++ b/test/TestProjects/ModelWithConverterUsage/ModelWithConverterUsage.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestProjects/ModelWithConverterUsage/readme.md b/test/TestProjects/ModelWithConverterUsage/readme.md index ba20e373dbc..5d2c6cbfb50 100644 --- a/test/TestProjects/ModelWithConverterUsage/readme.md +++ b/test/TestProjects/ModelWithConverterUsage/readme.md @@ -8,4 +8,6 @@ generation1-convenience-client: true require: $(this-folder)/../../../readme.md input-file: $(this-folder)/ModelWithConverterUsage.json namespace: Azure.ModelWithConverterUsage + +use-model-reader-writer: true ``` diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Configuration.json b/test/TestProjects/Models-TypeSpec/src/Generated/Configuration.json index c542d7687f9..5ee2dc6ea13 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Configuration.json +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Configuration.json @@ -5,5 +5,6 @@ "shared-source-folders": [ "../../../../../artifacts/bin/AutoRest.CSharp/Debug/net7.0/Generator.Shared", "../../../../../artifacts/bin/AutoRest.CSharp/Debug/net7.0/Azure.Core.Shared" - ] + ], + "use-model-reader-writer": true } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModel.Serialization.cs index 8aeffcba616..8315319da6b 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModel.Serialization.cs @@ -5,19 +5,118 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; +using Azure; using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class BaseModel : IUtf8JsonSerializable + public partial class BaseModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + BaseModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeBaseModel(document.RootElement, options); + } + + internal static BaseModel DeserializeBaseModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new BaseModel(serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(BaseModel)} does not support '{options.Format}' format."); + } + } + + BaseModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeBaseModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(BaseModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static BaseModel FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeBaseModel(document.RootElement); + } + /// Convert into a Utf8JsonRequestContent. internal virtual RequestContent ToRequestContent() { diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModel.cs index acbd4db3021..720f15daf30 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModel.cs @@ -5,14 +5,56 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// Base model. public partial class BaseModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public BaseModel() { } + + /// Initializes a new instance of . + /// Keeps track of any properties unknown to the library. + internal BaseModel(IDictionary serializedAdditionalRawData) + { + _serializedAdditionalRawData = serializedAdditionalRawData; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithDiscriminator.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithDiscriminator.Serialization.cs index 9e9ce0707c0..daa9e51c9ca 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithDiscriminator.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithDiscriminator.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; using Azure; using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class BaseModelWithDiscriminator : IUtf8JsonSerializable + [PersistableModelProxy(typeof(UnknownBaseModelWithDiscriminator))] + public partial class BaseModelWithDiscriminator : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseModelWithDiscriminator)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("discriminatorProperty"u8); writer.WriteStringValue(DiscriminatorProperty); @@ -25,11 +36,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WritePropertyName("requiredPropertyOnBase"u8); writer.WriteNumberValue(RequiredPropertyOnBase); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static BaseModelWithDiscriminator DeserializeBaseModelWithDiscriminator(JsonElement element) + BaseModelWithDiscriminator IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseModelWithDiscriminator)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeBaseModelWithDiscriminator(document.RootElement, options); + } + + internal static BaseModelWithDiscriminator DeserializeBaseModelWithDiscriminator(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -45,6 +85,37 @@ internal static BaseModelWithDiscriminator DeserializeBaseModelWithDiscriminator return UnknownBaseModelWithDiscriminator.DeserializeUnknownBaseModelWithDiscriminator(element); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(BaseModelWithDiscriminator)} does not support '{options.Format}' format."); + } + } + + BaseModelWithDiscriminator IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeBaseModelWithDiscriminator(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(BaseModelWithDiscriminator)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static BaseModelWithDiscriminator FromResponse(Response response) diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithDiscriminator.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithDiscriminator.cs index 71ddad3f7c0..d042e54ff19 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithDiscriminator.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithDiscriminator.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// @@ -14,6 +17,38 @@ namespace ModelsTypeSpec.Models /// public abstract partial class BaseModelWithDiscriminator { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Required property on base. protected BaseModelWithDiscriminator(int requiredPropertyOnBase) @@ -25,11 +60,18 @@ protected BaseModelWithDiscriminator(int requiredPropertyOnBase) /// Discriminator. /// Optional property on base. /// Required property on base. - internal BaseModelWithDiscriminator(string discriminatorProperty, string optionalPropertyOnBase, int requiredPropertyOnBase) + /// Keeps track of any properties unknown to the library. + internal BaseModelWithDiscriminator(string discriminatorProperty, string optionalPropertyOnBase, int requiredPropertyOnBase, IDictionary serializedAdditionalRawData) { DiscriminatorProperty = discriminatorProperty; OptionalPropertyOnBase = optionalPropertyOnBase; RequiredPropertyOnBase = requiredPropertyOnBase; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal BaseModelWithDiscriminator() + { } /// Discriminator. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithProperties.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithProperties.Serialization.cs new file mode 100644 index 00000000000..3f5cc8fe9de --- /dev/null +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithProperties.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure; +using Azure.Core; + +namespace ModelsTypeSpec.Models +{ + public partial class BaseModelWithProperties : IUtf8JsonSerializable, IJsonModel + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseModelWithProperties)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(OptionalPropertyOnBase)) + { + writer.WritePropertyName("optionalPropertyOnBase"u8); + writer.WriteStringValue(OptionalPropertyOnBase); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + BaseModelWithProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseModelWithProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeBaseModelWithProperties(document.RootElement, options); + } + + internal static BaseModelWithProperties DeserializeBaseModelWithProperties(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional optionalPropertyOnBase = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("optionalPropertyOnBase"u8)) + { + optionalPropertyOnBase = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new BaseModelWithProperties(optionalPropertyOnBase.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(BaseModelWithProperties)} does not support '{options.Format}' format."); + } + } + + BaseModelWithProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeBaseModelWithProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(BaseModelWithProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static BaseModelWithProperties FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeBaseModelWithProperties(document.RootElement); + } + + /// Convert into a Utf8JsonRequestContent. + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } + } +} diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithProperties.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithProperties.cs index 049342d5abb..2b4277a722a 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithProperties.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/BaseModelWithProperties.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// Base model with properties. public partial class BaseModelWithProperties { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal BaseModelWithProperties() { @@ -17,9 +52,11 @@ internal BaseModelWithProperties() /// Initializes a new instance of . /// Optional properties on base. - internal BaseModelWithProperties(string optionalPropertyOnBase) + /// Keeps track of any properties unknown to the library. + internal BaseModelWithProperties(string optionalPropertyOnBase, IDictionary serializedAdditionalRawData) { OptionalPropertyOnBase = optionalPropertyOnBase; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Optional properties on base. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/CollectionItem.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/CollectionItem.Serialization.cs index 108daaa577f..68630f3f9f0 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/CollectionItem.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/CollectionItem.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace ModelsTypeSpec.Models { - public partial class CollectionItem : IUtf8JsonSerializable + public partial class CollectionItem : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(CollectionItem)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredModelRecord"u8); writer.WriteStartObject(); @@ -25,16 +35,47 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteObjectValue(item.Value); } writer.WriteEndObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static CollectionItem DeserializeCollectionItem(JsonElement element) + CollectionItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(CollectionItem)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeCollectionItem(document.RootElement, options); + } + + internal static CollectionItem DeserializeCollectionItem(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } IDictionary requiredModelRecord = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredModelRecord"u8)) @@ -47,10 +88,46 @@ internal static CollectionItem DeserializeCollectionItem(JsonElement element) requiredModelRecord = dictionary; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new CollectionItem(requiredModelRecord); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new CollectionItem(requiredModelRecord, serializedAdditionalRawData); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(CollectionItem)} does not support '{options.Format}' format."); + } + } + + CollectionItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeCollectionItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(CollectionItem)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static CollectionItem FromResponse(Response response) diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/CollectionItem.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/CollectionItem.cs index 221237b3241..e7a81f46e40 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/CollectionItem.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/CollectionItem.cs @@ -14,6 +14,38 @@ namespace ModelsTypeSpec.Models /// Collection item model. public partial class CollectionItem { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Required model record. /// is null. @@ -24,6 +56,20 @@ public CollectionItem(IDictionary requiredModelRecord) RequiredModelRecord = requiredModelRecord; } + /// Initializes a new instance of . + /// Required model record. + /// Keeps track of any properties unknown to the library. + internal CollectionItem(IDictionary requiredModelRecord, IDictionary serializedAdditionalRawData) + { + RequiredModelRecord = requiredModelRecord; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal CollectionItem() + { + } + /// Required model record. public IDictionary RequiredModelRecord { get; } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModel.Serialization.cs index 80900a4569d..4da0f602f15 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModel.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace ModelsTypeSpec.Models { - public partial class DerivedModel : IUtf8JsonSerializable + public partial class DerivedModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DerivedModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredList"u8); writer.WriteStartArray(); @@ -24,16 +34,47 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteObjectValue(item); } writer.WriteEndArray(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static DerivedModel DeserializeDerivedModel(JsonElement element) + DerivedModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DerivedModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDerivedModel(document.RootElement, options); + } + + internal static DerivedModel DeserializeDerivedModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } IList requiredList = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredList"u8)) @@ -46,13 +87,49 @@ internal static DerivedModel DeserializeDerivedModel(JsonElement element) requiredList = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new DerivedModel(requiredList); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DerivedModel(serializedAdditionalRawData, requiredList); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DerivedModel)} does not support '{options.Format}' format."); + } + } + + DerivedModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDerivedModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DerivedModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. - internal static DerivedModel FromResponse(Response response) + internal static new DerivedModel FromResponse(Response response) { using var document = JsonDocument.Parse(response.Content); return DeserializeDerivedModel(document.RootElement); diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModel.cs index dea1dbe5b9c..fb5e50b971e 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModel.cs @@ -26,12 +26,18 @@ public DerivedModel(IEnumerable requiredList) } /// Initializes a new instance of . + /// Keeps track of any properties unknown to the library. /// Required collection. - internal DerivedModel(IList requiredList) + internal DerivedModel(IDictionary serializedAdditionalRawData, IList requiredList) : base(serializedAdditionalRawData) { RequiredList = requiredList; } + /// Initializes a new instance of for deserialization. + internal DerivedModel() + { + } + /// Required collection. public IList RequiredList { get; } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorA.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorA.Serialization.cs index 1f5803c506c..1ad1e9b0b05 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorA.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorA.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class DerivedModelWithDiscriminatorA : IUtf8JsonSerializable + public partial class DerivedModelWithDiscriminatorA : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DerivedModelWithDiscriminatorA)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredString"u8); writer.WriteStringValue(RequiredString); @@ -27,11 +38,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WritePropertyName("requiredPropertyOnBase"u8); writer.WriteNumberValue(RequiredPropertyOnBase); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static DerivedModelWithDiscriminatorA DeserializeDerivedModelWithDiscriminatorA(JsonElement element) + DerivedModelWithDiscriminatorA IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DerivedModelWithDiscriminatorA)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDerivedModelWithDiscriminatorA(document.RootElement, options); + } + + internal static DerivedModelWithDiscriminatorA DeserializeDerivedModelWithDiscriminatorA(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -40,6 +80,8 @@ internal static DerivedModelWithDiscriminatorA DeserializeDerivedModelWithDiscri string discriminatorProperty = default; Optional optionalPropertyOnBase = default; int requiredPropertyOnBase = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredString"u8)) @@ -62,10 +104,46 @@ internal static DerivedModelWithDiscriminatorA DeserializeDerivedModelWithDiscri requiredPropertyOnBase = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DerivedModelWithDiscriminatorA(discriminatorProperty, optionalPropertyOnBase.Value, requiredPropertyOnBase, serializedAdditionalRawData, requiredString); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DerivedModelWithDiscriminatorA)} does not support '{options.Format}' format."); } - return new DerivedModelWithDiscriminatorA(discriminatorProperty, optionalPropertyOnBase.Value, requiredPropertyOnBase, requiredString); } + DerivedModelWithDiscriminatorA IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDerivedModelWithDiscriminatorA(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DerivedModelWithDiscriminatorA)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new DerivedModelWithDiscriminatorA FromResponse(Response response) diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorA.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorA.cs index 504a6ba2338..e5f27ba0517 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorA.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorA.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace ModelsTypeSpec.Models @@ -29,12 +30,18 @@ public DerivedModelWithDiscriminatorA(int requiredPropertyOnBase, string require /// Discriminator. /// Optional property on base. /// Required property on base. + /// Keeps track of any properties unknown to the library. /// Required string. - internal DerivedModelWithDiscriminatorA(string discriminatorProperty, string optionalPropertyOnBase, int requiredPropertyOnBase, string requiredString) : base(discriminatorProperty, optionalPropertyOnBase, requiredPropertyOnBase) + internal DerivedModelWithDiscriminatorA(string discriminatorProperty, string optionalPropertyOnBase, int requiredPropertyOnBase, IDictionary serializedAdditionalRawData, string requiredString) : base(discriminatorProperty, optionalPropertyOnBase, requiredPropertyOnBase, serializedAdditionalRawData) { RequiredString = requiredString; } + /// Initializes a new instance of for deserialization. + internal DerivedModelWithDiscriminatorA() + { + } + /// Required string. public string RequiredString { get; set; } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorB.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorB.Serialization.cs index 328e5937391..5a3dc0dc9d9 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorB.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorB.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class DerivedModelWithDiscriminatorB : IUtf8JsonSerializable + public partial class DerivedModelWithDiscriminatorB : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DerivedModelWithDiscriminatorB)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredInt"u8); writer.WriteNumberValue(RequiredInt); @@ -27,11 +38,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WritePropertyName("requiredPropertyOnBase"u8); writer.WriteNumberValue(RequiredPropertyOnBase); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static DerivedModelWithDiscriminatorB DeserializeDerivedModelWithDiscriminatorB(JsonElement element) + DerivedModelWithDiscriminatorB IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DerivedModelWithDiscriminatorB)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDerivedModelWithDiscriminatorB(document.RootElement, options); + } + + internal static DerivedModelWithDiscriminatorB DeserializeDerivedModelWithDiscriminatorB(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -40,6 +80,8 @@ internal static DerivedModelWithDiscriminatorB DeserializeDerivedModelWithDiscri string discriminatorProperty = default; Optional optionalPropertyOnBase = default; int requiredPropertyOnBase = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredInt"u8)) @@ -62,10 +104,46 @@ internal static DerivedModelWithDiscriminatorB DeserializeDerivedModelWithDiscri requiredPropertyOnBase = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DerivedModelWithDiscriminatorB(discriminatorProperty, optionalPropertyOnBase.Value, requiredPropertyOnBase, serializedAdditionalRawData, requiredInt); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DerivedModelWithDiscriminatorB)} does not support '{options.Format}' format."); } - return new DerivedModelWithDiscriminatorB(discriminatorProperty, optionalPropertyOnBase.Value, requiredPropertyOnBase, requiredInt); } + DerivedModelWithDiscriminatorB IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDerivedModelWithDiscriminatorB(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DerivedModelWithDiscriminatorB)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new DerivedModelWithDiscriminatorB FromResponse(Response response) diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorB.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorB.cs index ffcd2ffbef9..7657408d904 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorB.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithDiscriminatorB.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// Deriver model with discriminator property. @@ -23,12 +26,18 @@ public DerivedModelWithDiscriminatorB(int requiredPropertyOnBase, int requiredIn /// Discriminator. /// Optional property on base. /// Required property on base. + /// Keeps track of any properties unknown to the library. /// Required int. - internal DerivedModelWithDiscriminatorB(string discriminatorProperty, string optionalPropertyOnBase, int requiredPropertyOnBase, int requiredInt) : base(discriminatorProperty, optionalPropertyOnBase, requiredPropertyOnBase) + internal DerivedModelWithDiscriminatorB(string discriminatorProperty, string optionalPropertyOnBase, int requiredPropertyOnBase, IDictionary serializedAdditionalRawData, int requiredInt) : base(discriminatorProperty, optionalPropertyOnBase, requiredPropertyOnBase, serializedAdditionalRawData) { RequiredInt = requiredInt; } + /// Initializes a new instance of for deserialization. + internal DerivedModelWithDiscriminatorB() + { + } + /// Required int. public int RequiredInt { get; set; } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithProperties.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithProperties.Serialization.cs index ca490ab66c5..23e603d43b0 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithProperties.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithProperties.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace ModelsTypeSpec.Models { - public partial class DerivedModelWithProperties : IUtf8JsonSerializable + public partial class DerivedModelWithProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DerivedModelWithProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredList"u8); writer.WriteStartArray(); @@ -29,17 +39,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("optionalPropertyOnBase"u8); writer.WriteStringValue(OptionalPropertyOnBase); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static DerivedModelWithProperties DeserializeDerivedModelWithProperties(JsonElement element) + DerivedModelWithProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DerivedModelWithProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDerivedModelWithProperties(document.RootElement, options); + } + + internal static DerivedModelWithProperties DeserializeDerivedModelWithProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } IList requiredList = default; Optional optionalPropertyOnBase = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredList"u8)) @@ -57,20 +98,56 @@ internal static DerivedModelWithProperties DeserializeDerivedModelWithProperties optionalPropertyOnBase = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new DerivedModelWithProperties(optionalPropertyOnBase.Value, requiredList); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DerivedModelWithProperties(optionalPropertyOnBase.Value, serializedAdditionalRawData, requiredList); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DerivedModelWithProperties)} does not support '{options.Format}' format."); + } + } + + DerivedModelWithProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDerivedModelWithProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DerivedModelWithProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. - internal static DerivedModelWithProperties FromResponse(Response response) + internal static new DerivedModelWithProperties FromResponse(Response response) { using var document = JsonDocument.Parse(response.Content); return DeserializeDerivedModelWithProperties(document.RootElement); } /// Convert into a Utf8JsonRequestContent. - internal virtual RequestContent ToRequestContent() + internal override RequestContent ToRequestContent() { var content = new Utf8JsonRequestContent(); content.JsonWriter.WriteObjectValue(this); diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithProperties.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithProperties.cs index 7ac7719162c..7abe23b5dfc 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithProperties.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/DerivedModelWithProperties.cs @@ -27,12 +27,18 @@ public DerivedModelWithProperties(IEnumerable requiredList) /// Initializes a new instance of . /// Optional properties on base. + /// Keeps track of any properties unknown to the library. /// Required collection. - internal DerivedModelWithProperties(string optionalPropertyOnBase, IList requiredList) : base(optionalPropertyOnBase) + internal DerivedModelWithProperties(string optionalPropertyOnBase, IDictionary serializedAdditionalRawData, IList requiredList) : base(optionalPropertyOnBase, serializedAdditionalRawData) { RequiredList = requiredList; } + /// Initializes a new instance of for deserialization. + internal DerivedModelWithProperties() + { + } + /// Required collection. public IList RequiredList { get; } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/ErrorModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/ErrorModel.Serialization.cs index ab5eefcfda9..3d9a1575281 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/ErrorModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/ErrorModel.Serialization.cs @@ -5,22 +5,80 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class ErrorModel + public partial class ErrorModel : IUtf8JsonSerializable, IJsonModel { - internal static ErrorModel DeserializeErrorModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ErrorModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (options.Format != "W") + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && Optional.IsDefined(InnerError)) + { + writer.WritePropertyName("innerError"u8); + writer.WriteObjectValue(InnerError); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ErrorModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ErrorModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeErrorModel(document.RootElement, options); + } + + internal static ErrorModel DeserializeErrorModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } string message = default; Optional innerError = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("message"u8)) @@ -37,10 +95,46 @@ internal static ErrorModel DeserializeErrorModel(JsonElement element) innerError = DeserializeErrorModel(property.Value); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ErrorModel(message, innerError.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ErrorModel)} does not support '{options.Format}' format."); + } + } + + ErrorModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeErrorModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ErrorModel)} does not support '{options.Format}' format."); } - return new ErrorModel(message, innerError.Value); } + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static ErrorModel FromResponse(Response response) @@ -48,5 +142,13 @@ internal static ErrorModel FromResponse(Response response) using var document = JsonDocument.Parse(response.Content); return DeserializeErrorModel(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/ErrorModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/ErrorModel.cs index a4f6912807a..c6cea2b108f 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/ErrorModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/ErrorModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// Output model that has property of its own type. public partial class ErrorModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ErrorModel() { @@ -18,10 +53,12 @@ internal ErrorModel() /// Initializes a new instance of . /// Error message. /// Required Record. - internal ErrorModel(string message, ErrorModel innerError) + /// Keeps track of any properties unknown to the library. + internal ErrorModel(string message, ErrorModel innerError, IDictionary serializedAdditionalRawData) { Message = message; InnerError = innerError; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Error message. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/Facet.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/Facet.Serialization.cs new file mode 100644 index 00000000000..398ab18b456 --- /dev/null +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/Facet.Serialization.cs @@ -0,0 +1,136 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure; +using Azure.Core; + +namespace ModelsTypeSpec.Models +{ + public partial class Facet : IUtf8JsonSerializable, IJsonModel + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Facet)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("field"u8); + writer.WriteStringValue(Field); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Facet IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Facet)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeFacet(document.RootElement, options); + } + + internal static Facet DeserializeFacet(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string field = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("field"u8)) + { + field = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Facet(field, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Facet)} does not support '{options.Format}' format."); + } + } + + Facet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeFacet(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Facet)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static Facet FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeFacet(document.RootElement); + } + + /// Convert into a Utf8JsonRequestContent. + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } + } +} diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/Facet.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/Facet.cs index 93cfa62478f..ea3d058e5f8 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/Facet.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/Facet.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace ModelsTypeSpec.Models @@ -13,6 +14,38 @@ namespace ModelsTypeSpec.Models /// Facet. public partial class Facet { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// A field to facet by, where the field is attributed as 'facetable'. /// is null. @@ -23,6 +56,20 @@ internal Facet(string field) Field = field; } + /// Initializes a new instance of . + /// A field to facet by, where the field is attributed as 'facetable'. + /// Keeps track of any properties unknown to the library. + internal Facet(string field, IDictionary serializedAdditionalRawData) + { + Field = field; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Facet() + { + } + /// A field to facet by, where the field is attributed as 'facetable'. public string Field { get; } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/FirstDerivedOutputModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/FirstDerivedOutputModel.Serialization.cs index 99bb50948ef..30ee7d92a2e 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/FirstDerivedOutputModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/FirstDerivedOutputModel.Serialization.cs @@ -5,21 +5,74 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; +using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class FirstDerivedOutputModel + public partial class FirstDerivedOutputModel : IUtf8JsonSerializable, IJsonModel { - internal static FirstDerivedOutputModel DeserializeFirstDerivedOutputModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(FirstDerivedOutputModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("first"u8); + writer.WriteBooleanValue(First); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + FirstDerivedOutputModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(FirstDerivedOutputModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeFirstDerivedOutputModel(document.RootElement, options); + } + + internal static FirstDerivedOutputModel DeserializeFirstDerivedOutputModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } bool first = default; string kind = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("first"u8)) @@ -32,10 +85,46 @@ internal static FirstDerivedOutputModel DeserializeFirstDerivedOutputModel(JsonE kind = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new FirstDerivedOutputModel(kind, serializedAdditionalRawData, first); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(FirstDerivedOutputModel)} does not support '{options.Format}' format."); + } + } + + FirstDerivedOutputModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeFirstDerivedOutputModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(FirstDerivedOutputModel)} does not support '{options.Format}' format."); } - return new FirstDerivedOutputModel(kind, first); } + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new FirstDerivedOutputModel FromResponse(Response response) @@ -43,5 +132,13 @@ internal static FirstDerivedOutputModel DeserializeFirstDerivedOutputModel(JsonE using var document = JsonDocument.Parse(response.Content); return DeserializeFirstDerivedOutputModel(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal override RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/FirstDerivedOutputModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/FirstDerivedOutputModel.cs index f77116bf14b..d96481032b5 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/FirstDerivedOutputModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/FirstDerivedOutputModel.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// First derived model as an output. @@ -20,12 +23,18 @@ internal FirstDerivedOutputModel(bool first) /// Initializes a new instance of . /// Discriminator. + /// Keeps track of any properties unknown to the library. /// - internal FirstDerivedOutputModel(string kind, bool first) : base(kind) + internal FirstDerivedOutputModel(string kind, IDictionary serializedAdditionalRawData, bool first) : base(kind, serializedAdditionalRawData) { First = first; } + /// Initializes a new instance of for deserialization. + internal FirstDerivedOutputModel() + { + } + /// Gets the first. public bool First { get; } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputModel.Serialization.cs index d46d25f83a1..603fefb2f92 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputModel.Serialization.cs @@ -5,15 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; +using Azure; using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class InputModel : IUtf8JsonSerializable + public partial class InputModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredString"u8); writer.WriteStringValue(RequiredString); @@ -241,9 +253,382 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNull("nonRequiredNullableIntList"); } } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + InputModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInputModel(document.RootElement, options); + } + + internal static InputModel DeserializeInputModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string requiredString = default; + int requiredInt = default; + int? requiredNullableInt = default; + string requiredNullableString = default; + Optional nonRequiredNullableInt = default; + Optional nonRequiredNullableString = default; + BaseModel requiredModel = default; + BaseModel requiredModel2 = default; + IList requiredIntList = default; + IList requiredStringList = default; + IList requiredModelList = default; + IDictionary requiredModelRecord = default; + IList requiredCollectionWithNullableFloatElement = default; + IList requiredCollectionWithNullableBooleanElement = default; + IList requiredNullableModelList = default; + IList requiredNullableStringList = default; + IList requiredNullableIntList = default; + Optional> nonRequiredModelList = default; + Optional> nonRequiredStringList = default; + Optional> nonRequiredIntList = default; + Optional> nonRequiredNullableModelList = default; + Optional> nonRequiredNullableStringList = default; + Optional> nonRequiredNullableIntList = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("requiredString"u8)) + { + requiredString = property.Value.GetString(); + continue; + } + if (property.NameEquals("requiredInt"u8)) + { + requiredInt = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("requiredNullableInt"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + requiredNullableInt = null; + continue; + } + requiredNullableInt = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("requiredNullableString"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + requiredNullableString = null; + continue; + } + requiredNullableString = property.Value.GetString(); + continue; + } + if (property.NameEquals("nonRequiredNullableInt"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + nonRequiredNullableInt = null; + continue; + } + nonRequiredNullableInt = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("nonRequiredNullableString"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + nonRequiredNullableString = null; + continue; + } + nonRequiredNullableString = property.Value.GetString(); + continue; + } + if (property.NameEquals("requiredModel"u8)) + { + requiredModel = BaseModel.DeserializeBaseModel(property.Value); + continue; + } + if (property.NameEquals("requiredModel2"u8)) + { + requiredModel2 = BaseModel.DeserializeBaseModel(property.Value); + continue; + } + if (property.NameEquals("requiredIntList"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + requiredIntList = array; + continue; + } + if (property.NameEquals("requiredStringList"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + requiredStringList = array; + continue; + } + if (property.NameEquals("requiredModelList"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(CollectionItem.DeserializeCollectionItem(item)); + } + requiredModelList = array; + continue; + } + if (property.NameEquals("requiredModelRecord"u8)) + { + Dictionary dictionary = new Dictionary(); + foreach (var property0 in property.Value.EnumerateObject()) + { + dictionary.Add(property0.Name, RecordItem.DeserializeRecordItem(property0.Value)); + } + requiredModelRecord = dictionary; + continue; + } + if (property.NameEquals("requiredCollectionWithNullableFloatElement"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + if (item.ValueKind == JsonValueKind.Null) + { + array.Add(null); + } + else + { + array.Add(item.GetSingle()); + } + } + requiredCollectionWithNullableFloatElement = array; + continue; + } + if (property.NameEquals("requiredCollectionWithNullableBooleanElement"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + if (item.ValueKind == JsonValueKind.Null) + { + array.Add(null); + } + else + { + array.Add(item.GetBoolean()); + } + } + requiredCollectionWithNullableBooleanElement = array; + continue; + } + if (property.NameEquals("requiredNullableModelList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + requiredNullableModelList = new ChangeTrackingList(); + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(CollectionItem.DeserializeCollectionItem(item)); + } + requiredNullableModelList = array; + continue; + } + if (property.NameEquals("requiredNullableStringList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + requiredNullableStringList = new ChangeTrackingList(); + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + requiredNullableStringList = array; + continue; + } + if (property.NameEquals("requiredNullableIntList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + requiredNullableIntList = new ChangeTrackingList(); + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + requiredNullableIntList = array; + continue; + } + if (property.NameEquals("nonRequiredModelList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(CollectionItem.DeserializeCollectionItem(item)); + } + nonRequiredModelList = array; + continue; + } + if (property.NameEquals("nonRequiredStringList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + nonRequiredStringList = array; + continue; + } + if (property.NameEquals("nonRequiredIntList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + nonRequiredIntList = array; + continue; + } + if (property.NameEquals("nonRequiredNullableModelList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(CollectionItem.DeserializeCollectionItem(item)); + } + nonRequiredNullableModelList = array; + continue; + } + if (property.NameEquals("nonRequiredNullableStringList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + nonRequiredNullableStringList = array; + continue; + } + if (property.NameEquals("nonRequiredNullableIntList"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + nonRequiredNullableIntList = array; + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new InputModel(requiredString, requiredInt, requiredNullableInt, requiredNullableString, Optional.ToNullable(nonRequiredNullableInt), nonRequiredNullableString.Value, requiredModel, requiredModel2, requiredIntList, requiredStringList, requiredModelList, requiredModelRecord, requiredCollectionWithNullableFloatElement, requiredCollectionWithNullableBooleanElement, requiredNullableModelList, requiredNullableStringList, requiredNullableIntList, Optional.ToList(nonRequiredModelList), Optional.ToList(nonRequiredStringList), Optional.ToList(nonRequiredIntList), Optional.ToList(nonRequiredNullableModelList), Optional.ToList(nonRequiredNullableStringList), Optional.ToList(nonRequiredNullableIntList), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InputModel)} does not support '{options.Format}' format."); + } + } + + InputModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeInputModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InputModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static InputModel FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeInputModel(document.RootElement); + } + /// Convert into a Utf8JsonRequestContent. internal virtual RequestContent ToRequestContent() { diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputModel.cs index 6656a28a4a6..c790f531fff 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputModel.cs @@ -15,6 +15,38 @@ namespace ModelsTypeSpec.Models /// Model used only as input. public partial class InputModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Required string. /// Required int. @@ -91,7 +123,8 @@ public InputModel(string requiredString, int requiredInt, int? requiredNullableI /// Optional model nullable collection. /// Optional string nullable collection. /// Optional int nullable collection. - internal InputModel(string requiredString, int requiredInt, int? requiredNullableInt, string requiredNullableString, int? nonRequiredNullableInt, string nonRequiredNullableString, BaseModel requiredModel, BaseModel requiredModel2, IList requiredIntList, IList requiredStringList, IList requiredModelList, IDictionary requiredModelRecord, IList requiredCollectionWithNullableFloatElement, IList requiredCollectionWithNullableBooleanElement, IList requiredNullableModelList, IList requiredNullableStringList, IList requiredNullableIntList, IList nonRequiredModelList, IList nonRequiredStringList, IList nonRequiredIntList, IList nonRequiredNullableModelList, IList nonRequiredNullableStringList, IList nonRequiredNullableIntList) + /// Keeps track of any properties unknown to the library. + internal InputModel(string requiredString, int requiredInt, int? requiredNullableInt, string requiredNullableString, int? nonRequiredNullableInt, string nonRequiredNullableString, BaseModel requiredModel, BaseModel requiredModel2, IList requiredIntList, IList requiredStringList, IList requiredModelList, IDictionary requiredModelRecord, IList requiredCollectionWithNullableFloatElement, IList requiredCollectionWithNullableBooleanElement, IList requiredNullableModelList, IList requiredNullableStringList, IList requiredNullableIntList, IList nonRequiredModelList, IList nonRequiredStringList, IList nonRequiredIntList, IList nonRequiredNullableModelList, IList nonRequiredNullableStringList, IList nonRequiredNullableIntList, IDictionary serializedAdditionalRawData) { RequiredString = requiredString; RequiredInt = requiredInt; @@ -116,6 +149,12 @@ internal InputModel(string requiredString, int requiredInt, int? requiredNullabl NonRequiredNullableModelList = nonRequiredNullableModelList; NonRequiredNullableStringList = nonRequiredNullableStringList; NonRequiredNullableIntList = nonRequiredNullableIntList; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal InputModel() + { } /// Required string. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputRecursiveModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputRecursiveModel.Serialization.cs index 7e6633bb179..d98ff0f08e5 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputRecursiveModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputRecursiveModel.Serialization.cs @@ -5,15 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; +using Azure; using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class InputRecursiveModel : IUtf8JsonSerializable + public partial class InputRecursiveModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputRecursiveModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("message"u8); writer.WriteStringValue(Message); @@ -22,9 +34,112 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("inner"u8); writer.WriteObjectValue(Inner); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + InputRecursiveModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputRecursiveModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInputRecursiveModel(document.RootElement, options); + } + + internal static InputRecursiveModel DeserializeInputRecursiveModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string message = default; + Optional inner = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("message"u8)) + { + message = property.Value.GetString(); + continue; + } + if (property.NameEquals("inner"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inner = DeserializeInputRecursiveModel(property.Value); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new InputRecursiveModel(message, inner.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InputRecursiveModel)} does not support '{options.Format}' format."); + } + } + + InputRecursiveModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeInputRecursiveModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InputRecursiveModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static InputRecursiveModel FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeInputRecursiveModel(document.RootElement); + } + /// Convert into a Utf8JsonRequestContent. internal virtual RequestContent ToRequestContent() { diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputRecursiveModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputRecursiveModel.cs index d6c0ffe9a10..78e4d0305c8 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputRecursiveModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/InputRecursiveModel.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace ModelsTypeSpec.Models @@ -13,6 +14,38 @@ namespace ModelsTypeSpec.Models /// Input model that has property of its own type. public partial class InputRecursiveModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Message. /// is null. @@ -26,10 +59,17 @@ public InputRecursiveModel(string message) /// Initializes a new instance of . /// Message. /// Required Record. - internal InputRecursiveModel(string message, InputRecursiveModel inner) + /// Keeps track of any properties unknown to the library. + internal InputRecursiveModel(string message, InputRecursiveModel inner, IDictionary serializedAdditionalRawData) { Message = message; Inner = inner; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal InputRecursiveModel() + { } /// Message. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/Int32ValuesFacet.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/Int32ValuesFacet.Serialization.cs index ca0b38a8432..dbb269b0254 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/Int32ValuesFacet.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/Int32ValuesFacet.Serialization.cs @@ -5,15 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; +using Azure; using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class Int32ValuesFacet : IUtf8JsonSerializable + public partial class Int32ValuesFacet : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Int32ValuesFacet)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("kind"u8); writer.WriteStringValue(Kind.ToString()); @@ -28,11 +40,127 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNumberValue(Value); writer.WritePropertyName("field"u8); writer.WriteStringValue(Field); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + Int32ValuesFacet IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Int32ValuesFacet)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInt32ValuesFacet(document.RootElement, options); + } + + internal static Int32ValuesFacet DeserializeInt32ValuesFacet(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Int32ValuesFacetKind kind = default; + IReadOnlyList values = default; + int value = default; + string field = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("kind"u8)) + { + kind = new Int32ValuesFacetKind(property.Value.GetString()); + continue; + } + if (property.NameEquals("values"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + values = array; + continue; + } + if (property.NameEquals("value"u8)) + { + value = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("field"u8)) + { + field = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Int32ValuesFacet(field, serializedAdditionalRawData, values, value, kind); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Int32ValuesFacet)} does not support '{options.Format}' format."); + } + } + + Int32ValuesFacet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeInt32ValuesFacet(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Int32ValuesFacet)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static new Int32ValuesFacet FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeInt32ValuesFacet(document.RootElement); + } + /// Convert into a Utf8JsonRequestContent. - internal virtual RequestContent ToRequestContent() + internal override RequestContent ToRequestContent() { var content = new Utf8JsonRequestContent(); content.JsonWriter.WriteObjectValue(this); diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/Int32ValuesFacet.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/Int32ValuesFacet.cs index 323c32a9da4..6f3ba3ad02b 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/Int32ValuesFacet.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/Int32ValuesFacet.cs @@ -27,17 +27,20 @@ public Int32ValuesFacet(string field, IEnumerable values, int value) : base /// Initializes a new instance of . /// A field to facet by, where the field is attributed as 'facetable'. + /// Keeps track of any properties unknown to the library. /// The facet ranges to produce. The values must be listed in ascending order to get the expected results. For example, values=10,20 produces three buckets: one for base rate 0 up to but not including 10, one for 10 up to but not including 20, and one for 20 and higher. /// /// The facet type. - /// is null. - internal Int32ValuesFacet(string field, IReadOnlyList values, int value, Int32ValuesFacetKind kind) : base(field, values, value) + internal Int32ValuesFacet(string field, IDictionary serializedAdditionalRawData, IReadOnlyList values, int value, Int32ValuesFacetKind kind) : base(field, serializedAdditionalRawData, values, value) { - Argument.AssertNotNull(field, nameof(field)); - Kind = kind; } + /// Initializes a new instance of for deserialization. + internal Int32ValuesFacet() + { + } + /// The facet type. public Int32ValuesFacetKind Kind { get; } = Int32ValuesFacetKind.Int32Values; } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/NoUseBase.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/NoUseBase.Serialization.cs new file mode 100644 index 00000000000..251440da50c --- /dev/null +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/NoUseBase.Serialization.cs @@ -0,0 +1,136 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure; +using Azure.Core; + +namespace ModelsTypeSpec.Models +{ + public partial class NoUseBase : IUtf8JsonSerializable, IJsonModel + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NoUseBase)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("baseModelProp"u8); + writer.WriteStringValue(BaseModelProp); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + NoUseBase IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NoUseBase)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeNoUseBase(document.RootElement, options); + } + + internal static NoUseBase DeserializeNoUseBase(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string baseModelProp = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("baseModelProp"u8)) + { + baseModelProp = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new NoUseBase(baseModelProp, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(NoUseBase)} does not support '{options.Format}' format."); + } + } + + NoUseBase IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeNoUseBase(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(NoUseBase)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static NoUseBase FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeNoUseBase(document.RootElement); + } + + /// Convert into a Utf8JsonRequestContent. + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } + } +} diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/NoUseBase.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/NoUseBase.cs index 9f238fe8ff7..6726343e15c 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/NoUseBase.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/NoUseBase.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace ModelsTypeSpec.Models @@ -13,6 +14,38 @@ namespace ModelsTypeSpec.Models /// Base model. public partial class NoUseBase { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// base model property. /// is null. @@ -23,6 +56,20 @@ internal NoUseBase(string baseModelProp) BaseModelProp = baseModelProp; } + /// Initializes a new instance of . + /// base model property. + /// Keeps track of any properties unknown to the library. + internal NoUseBase(string baseModelProp, IDictionary serializedAdditionalRawData) + { + BaseModelProp = baseModelProp; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal NoUseBase() + { + } + /// base model property. public string BaseModelProp { get; } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/NumericValuesFacetint32.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/NumericValuesFacetint32.Serialization.cs new file mode 100644 index 00000000000..d0320d75593 --- /dev/null +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/NumericValuesFacetint32.Serialization.cs @@ -0,0 +1,162 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure; +using Azure.Core; + +namespace ModelsTypeSpec.Models +{ + public partial class NumericValuesFacetint32 : IUtf8JsonSerializable, IJsonModel + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NumericValuesFacetint32)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("values"u8); + writer.WriteStartArray(); + foreach (var item in Values) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + writer.WritePropertyName("value"u8); + writer.WriteNumberValue(Value); + writer.WritePropertyName("field"u8); + writer.WriteStringValue(Field); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + NumericValuesFacetint32 IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NumericValuesFacetint32)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeNumericValuesFacetint32(document.RootElement, options); + } + + internal static NumericValuesFacetint32 DeserializeNumericValuesFacetint32(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IReadOnlyList values = default; + int value = default; + string field = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("values"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + values = array; + continue; + } + if (property.NameEquals("value"u8)) + { + value = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("field"u8)) + { + field = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new NumericValuesFacetint32(field, serializedAdditionalRawData, values, value); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(NumericValuesFacetint32)} does not support '{options.Format}' format."); + } + } + + NumericValuesFacetint32 IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeNumericValuesFacetint32(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(NumericValuesFacetint32)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// Deserializes the model from a raw response. + /// The response to deserialize the model from. + internal static new NumericValuesFacetint32 FromResponse(Response response) + { + using var document = JsonDocument.Parse(response.Content); + return DeserializeNumericValuesFacetint32(document.RootElement); + } + + /// Convert into a Utf8JsonRequestContent. + internal override RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } + } +} diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/NumericValuesFacetint32.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/NumericValuesFacetint32.cs index b7fa2d5215c..ffed7e82d9d 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/NumericValuesFacetint32.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/NumericValuesFacetint32.cs @@ -31,17 +31,20 @@ internal NumericValuesFacetint32(string field, IEnumerable values, int valu /// Initializes a new instance of . /// A field to facet by, where the field is attributed as 'facetable'. + /// Keeps track of any properties unknown to the library. /// The facet ranges to produce. The values must be listed in ascending order to get the expected results. For example, values=10,20 produces three buckets: one for base rate 0 up to but not including 10, one for 10 up to but not including 20, and one for 20 and higher. /// - /// is null. - internal NumericValuesFacetint32(string field, IReadOnlyList values, int value) : base(field) + internal NumericValuesFacetint32(string field, IDictionary serializedAdditionalRawData, IReadOnlyList values, int value) : base(field, serializedAdditionalRawData) { - Argument.AssertNotNull(field, nameof(field)); - Values = values; Value = value; } + /// Initializes a new instance of for deserialization. + internal NumericValuesFacetint32() + { + } + /// The facet ranges to produce. The values must be listed in ascending order to get the expected results. For example, values=10,20 produces three buckets: one for base rate 0 up to but not including 10, one for 10 up to but not including 20, and one for 20 and higher. public IReadOnlyList Values { get; } /// Gets the value. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputBaseModelWithDiscriminator.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputBaseModelWithDiscriminator.Serialization.cs index 29f2457f07a..ba2feaccc6c 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputBaseModelWithDiscriminator.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputBaseModelWithDiscriminator.Serialization.cs @@ -5,15 +5,64 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; using Azure; +using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class OutputBaseModelWithDiscriminator + [PersistableModelProxy(typeof(UnknownOutputBaseModelWithDiscriminator))] + public partial class OutputBaseModelWithDiscriminator : IUtf8JsonSerializable, IJsonModel { - internal static OutputBaseModelWithDiscriminator DeserializeOutputBaseModelWithDiscriminator(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputBaseModelWithDiscriminator)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + OutputBaseModelWithDiscriminator IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputBaseModelWithDiscriminator)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeOutputBaseModelWithDiscriminator(document.RootElement, options); + } + + internal static OutputBaseModelWithDiscriminator DeserializeOutputBaseModelWithDiscriminator(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -29,6 +78,37 @@ internal static OutputBaseModelWithDiscriminator DeserializeOutputBaseModelWithD return UnknownOutputBaseModelWithDiscriminator.DeserializeUnknownOutputBaseModelWithDiscriminator(element); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(OutputBaseModelWithDiscriminator)} does not support '{options.Format}' format."); + } + } + + OutputBaseModelWithDiscriminator IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeOutputBaseModelWithDiscriminator(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(OutputBaseModelWithDiscriminator)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static OutputBaseModelWithDiscriminator FromResponse(Response response) @@ -36,5 +116,13 @@ internal static OutputBaseModelWithDiscriminator FromResponse(Response response) using var document = JsonDocument.Parse(response.Content); return DeserializeOutputBaseModelWithDiscriminator(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputBaseModelWithDiscriminator.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputBaseModelWithDiscriminator.cs index ddd25af5812..db61e63d918 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputBaseModelWithDiscriminator.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputBaseModelWithDiscriminator.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// @@ -14,6 +17,38 @@ namespace ModelsTypeSpec.Models /// public abstract partial class OutputBaseModelWithDiscriminator { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . protected OutputBaseModelWithDiscriminator() { @@ -21,9 +56,11 @@ protected OutputBaseModelWithDiscriminator() /// Initializes a new instance of . /// Discriminator. - internal OutputBaseModelWithDiscriminator(string kind) + /// Keeps track of any properties unknown to the library. + internal OutputBaseModelWithDiscriminator(string kind, IDictionary serializedAdditionalRawData) { Kind = kind; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Discriminator. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputModel.Serialization.cs index 153268bc00e..d8566af64fb 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputModel.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,130 @@ namespace ModelsTypeSpec.Models { - public partial class OutputModel + public partial class OutputModel : IUtf8JsonSerializable, IJsonModel { - internal static OutputModel DeserializeOutputModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("requiredString"u8); + writer.WriteStringValue(RequiredString); + writer.WritePropertyName("requiredInt"u8); + writer.WriteNumberValue(RequiredInt); + writer.WritePropertyName("requiredModel"u8); + writer.WriteObjectValue(RequiredModel); + writer.WritePropertyName("requiredList"u8); + writer.WriteStartArray(); + foreach (var item in RequiredList) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + writer.WritePropertyName("requiredModelRecord"u8); + writer.WriteStartObject(); + foreach (var item in RequiredModelRecord) + { + writer.WritePropertyName(item.Key); + writer.WriteObjectValue(item.Value); + } + writer.WriteEndObject(); + if (Optional.IsCollectionDefined(OptionalList)) + { + writer.WritePropertyName("optionalList"u8); + writer.WriteStartArray(); + foreach (var item in OptionalList) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(OptionalNullableList)) + { + if (OptionalNullableList != null) + { + writer.WritePropertyName("optionalNullableList"u8); + writer.WriteStartArray(); + foreach (var item in OptionalNullableList) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + else + { + writer.WriteNull("optionalNullableList"); + } + } + if (Optional.IsCollectionDefined(OptionalRecord)) + { + writer.WritePropertyName("optionalRecord"u8); + writer.WriteStartObject(); + foreach (var item in OptionalRecord) + { + writer.WritePropertyName(item.Key); + writer.WriteObjectValue(item.Value); + } + writer.WriteEndObject(); + } + if (Optional.IsCollectionDefined(OptionalNullableRecord)) + { + if (OptionalNullableRecord != null) + { + writer.WritePropertyName("optionalNullableRecord"u8); + writer.WriteStartObject(); + foreach (var item in OptionalNullableRecord) + { + writer.WritePropertyName(item.Key); + writer.WriteObjectValue(item.Value); + } + writer.WriteEndObject(); + } + else + { + writer.WriteNull("optionalNullableRecord"); + } + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + OutputModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeOutputModel(document.RootElement, options); + } + + internal static OutputModel DeserializeOutputModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -29,6 +151,8 @@ internal static OutputModel DeserializeOutputModel(JsonElement element) Optional> optionalNullableList = default; Optional> optionalRecord = default; Optional> optionalNullableRecord = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredString"u8)) @@ -122,10 +246,46 @@ internal static OutputModel DeserializeOutputModel(JsonElement element) optionalNullableRecord = dictionary; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new OutputModel(requiredString, requiredInt, requiredModel, requiredList, requiredModelRecord, Optional.ToList(optionalList), Optional.ToList(optionalNullableList), Optional.ToDictionary(optionalRecord), Optional.ToDictionary(optionalNullableRecord), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(OutputModel)} does not support '{options.Format}' format."); } - return new OutputModel(requiredString, requiredInt, requiredModel, requiredList, requiredModelRecord, Optional.ToList(optionalList), Optional.ToList(optionalNullableList), Optional.ToDictionary(optionalRecord), Optional.ToDictionary(optionalNullableRecord)); } + OutputModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeOutputModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(OutputModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static OutputModel FromResponse(Response response) @@ -133,5 +293,13 @@ internal static OutputModel FromResponse(Response response) using var document = JsonDocument.Parse(response.Content); return DeserializeOutputModel(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputModel.cs index fb6856363a7..899c3ce3dca 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/OutputModel.cs @@ -15,6 +15,38 @@ namespace ModelsTypeSpec.Models /// Model used only as output. public partial class OutputModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Required string. /// Required int. @@ -50,7 +82,8 @@ internal OutputModel(string requiredString, int requiredInt, DerivedModel requir /// Optional model nullable collection. /// Optional model record. /// Optional model nullable record. - internal OutputModel(string requiredString, int requiredInt, DerivedModel requiredModel, IReadOnlyList requiredList, IReadOnlyDictionary requiredModelRecord, IReadOnlyList optionalList, IReadOnlyList optionalNullableList, IReadOnlyDictionary optionalRecord, IReadOnlyDictionary optionalNullableRecord) + /// Keeps track of any properties unknown to the library. + internal OutputModel(string requiredString, int requiredInt, DerivedModel requiredModel, IReadOnlyList requiredList, IReadOnlyDictionary requiredModelRecord, IReadOnlyList optionalList, IReadOnlyList optionalNullableList, IReadOnlyDictionary optionalRecord, IReadOnlyDictionary optionalNullableRecord, IDictionary serializedAdditionalRawData) { RequiredString = requiredString; RequiredInt = requiredInt; @@ -61,6 +94,12 @@ internal OutputModel(string requiredString, int requiredInt, DerivedModel requir OptionalNullableList = optionalNullableList; OptionalRecord = optionalRecord; OptionalNullableRecord = optionalNullableRecord; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal OutputModel() + { } /// Required string. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RecordItem.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RecordItem.Serialization.cs index 06722d0d0b2..80c2b24c620 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RecordItem.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RecordItem.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace ModelsTypeSpec.Models { - public partial class RecordItem : IUtf8JsonSerializable + public partial class RecordItem : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RecordItem)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredList"u8); writer.WriteStartArray(); @@ -24,16 +34,47 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteObjectValue(item); } writer.WriteEndArray(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RecordItem DeserializeRecordItem(JsonElement element) + RecordItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RecordItem)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRecordItem(document.RootElement, options); + } + + internal static RecordItem DeserializeRecordItem(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } IList requiredList = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredList"u8)) @@ -46,10 +87,46 @@ internal static RecordItem DeserializeRecordItem(JsonElement element) requiredList = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new RecordItem(requiredList); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RecordItem(serializedAdditionalRawData, requiredList); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RecordItem)} does not support '{options.Format}' format."); + } + } + + RecordItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRecordItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RecordItem)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new RecordItem FromResponse(Response response) diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RecordItem.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RecordItem.cs index e6711d0d1bd..0fa00e59a86 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RecordItem.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RecordItem.cs @@ -23,8 +23,14 @@ public RecordItem(IEnumerable requiredList) : base(requiredList) } /// Initializes a new instance of . + /// Keeps track of any properties unknown to the library. /// Required collection. - internal RecordItem(IList requiredList) : base(requiredList) + internal RecordItem(IDictionary serializedAdditionalRawData, IList requiredList) : base(serializedAdditionalRawData, requiredList) + { + } + + /// Initializes a new instance of for deserialization. + internal RecordItem() { } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs index 90dc295ad9f..85e4f3888a1 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -13,10 +14,18 @@ namespace ModelsTypeSpec.Models { - public partial class RoundTripModel : IUtf8JsonSerializable + public partial class RoundTripModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredString"u8); writer.WriteStringValue(RequiredString); @@ -74,6 +83,16 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNull("nonRequiredNullableString"); } } + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadonlyInt"u8); + writer.WriteNumberValue(RequiredReadonlyInt); + } + if (options.Format != "W" && Optional.IsDefined(NonRequiredReadonlyInt)) + { + writer.WritePropertyName("nonRequiredReadonlyInt"u8); + writer.WriteNumberValue(NonRequiredReadonlyInt.Value); + } writer.WritePropertyName("requiredModel"u8); writer.WriteObjectValue(RequiredModel); writer.WritePropertyName("requiredFixedStringEnum"u8); @@ -237,11 +256,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNull("nonRequiredNullableStringList"); } } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RoundTripModel DeserializeRoundTripModel(JsonElement element) + RoundTripModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRoundTripModel(document.RootElement, options); + } + + internal static RoundTripModel DeserializeRoundTripModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -276,6 +324,8 @@ internal static RoundTripModel DeserializeRoundTripModel(JsonElement element) IList requiredNullableStringList = default; Optional> nonRequiredNullableIntList = default; Optional> nonRequiredNullableStringList = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredString"u8)) @@ -550,13 +600,49 @@ internal static RoundTripModel DeserializeRoundTripModel(JsonElement element) nonRequiredNullableStringList = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RoundTripModel(serializedAdditionalRawData, requiredString, requiredInt, nonRequiredString.Value, Optional.ToNullable(nonRequiredInt), requiredNullableInt, requiredNullableString, Optional.ToNullable(nonRequiredNullableInt), nonRequiredNullableString.Value, requiredReadonlyInt, Optional.ToNullable(nonRequiredReadonlyInt), requiredModel, requiredFixedStringEnum, requiredFixedIntEnum, requiredExtensibleEnum, requiredList, requiredIntRecord, requiredStringRecord, requiredModelRecord, requiredBytes, optionalBytes.Value, requiredUint8Array, Optional.ToList(optionalUint8Array), requiredUnknown, optionalUnknown.Value, requiredInt8Array, Optional.ToList(optionalInt8Array), requiredNullableIntList, requiredNullableStringList, Optional.ToList(nonRequiredNullableIntList), Optional.ToList(nonRequiredNullableStringList)); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RoundTripModel)} does not support '{options.Format}' format."); + } + } + + RoundTripModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRoundTripModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RoundTripModel)} does not support '{options.Format}' format."); } - return new RoundTripModel(requiredString, requiredInt, nonRequiredString.Value, Optional.ToNullable(nonRequiredInt), requiredNullableInt, requiredNullableString, Optional.ToNullable(nonRequiredNullableInt), nonRequiredNullableString.Value, requiredReadonlyInt, Optional.ToNullable(nonRequiredReadonlyInt), requiredModel, requiredFixedStringEnum, requiredFixedIntEnum, requiredExtensibleEnum, requiredList, requiredIntRecord, requiredStringRecord, requiredModelRecord, requiredBytes, optionalBytes.Value, requiredUint8Array, Optional.ToList(optionalUint8Array), requiredUnknown, optionalUnknown.Value, requiredInt8Array, Optional.ToList(optionalInt8Array), requiredNullableIntList, requiredNullableStringList, Optional.ToList(nonRequiredNullableIntList), Optional.ToList(nonRequiredNullableStringList)); } + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. - internal static RoundTripModel FromResponse(Response response) + internal static new RoundTripModel FromResponse(Response response) { using var document = JsonDocument.Parse(response.Content); return DeserializeRoundTripModel(document.RootElement); diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripModel.cs index 0c22b243432..699ff0a229a 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripModel.cs @@ -73,6 +73,7 @@ public RoundTripModel(string requiredString, int requiredInt, int? requiredNulla } /// Initializes a new instance of . + /// Keeps track of any properties unknown to the library. /// Required string, illustrating a reference type property. /// Required int, illustrating a value type property. /// Optional string. @@ -103,7 +104,7 @@ public RoundTripModel(string requiredString, int requiredInt, int? requiredNulla /// Required nullable string list. /// Optional nullable model list. /// Optional nullable string list. - internal RoundTripModel(string requiredString, int requiredInt, string nonRequiredString, int? nonRequiredInt, int? requiredNullableInt, string requiredNullableString, int? nonRequiredNullableInt, string nonRequiredNullableString, int requiredReadonlyInt, int? nonRequiredReadonlyInt, BaseModelWithDiscriminator requiredModel, FixedStringEnum requiredFixedStringEnum, FixedIntEnum requiredFixedIntEnum, ExtensibleEnum requiredExtensibleEnum, IList requiredList, IDictionary requiredIntRecord, IDictionary requiredStringRecord, IDictionary requiredModelRecord, BinaryData requiredBytes, BinaryData optionalBytes, IList requiredUint8Array, IList optionalUint8Array, BinaryData requiredUnknown, BinaryData optionalUnknown, IList requiredInt8Array, IList optionalInt8Array, IList requiredNullableIntList, IList requiredNullableStringList, IList nonRequiredNullableIntList, IList nonRequiredNullableStringList) + internal RoundTripModel(IDictionary serializedAdditionalRawData, string requiredString, int requiredInt, string nonRequiredString, int? nonRequiredInt, int? requiredNullableInt, string requiredNullableString, int? nonRequiredNullableInt, string nonRequiredNullableString, int requiredReadonlyInt, int? nonRequiredReadonlyInt, BaseModelWithDiscriminator requiredModel, FixedStringEnum requiredFixedStringEnum, FixedIntEnum requiredFixedIntEnum, ExtensibleEnum requiredExtensibleEnum, IList requiredList, IDictionary requiredIntRecord, IDictionary requiredStringRecord, IDictionary requiredModelRecord, BinaryData requiredBytes, BinaryData optionalBytes, IList requiredUint8Array, IList optionalUint8Array, BinaryData requiredUnknown, BinaryData optionalUnknown, IList requiredInt8Array, IList optionalInt8Array, IList requiredNullableIntList, IList requiredNullableStringList, IList nonRequiredNullableIntList, IList nonRequiredNullableStringList) : base(serializedAdditionalRawData) { RequiredString = requiredString; RequiredInt = requiredInt; @@ -137,6 +138,11 @@ internal RoundTripModel(string requiredString, int requiredInt, string nonRequir NonRequiredNullableStringList = nonRequiredNullableStringList; } + /// Initializes a new instance of for deserialization. + internal RoundTripModel() + { + } + /// Required string, illustrating a reference type property. public string RequiredString { get; set; } /// Required int, illustrating a value type property. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOnNoUse.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOnNoUse.Serialization.cs index afbb72e3275..ed078d9fa75 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOnNoUse.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOnNoUse.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,18 @@ namespace ModelsTypeSpec.Models { - public partial class RoundTripOnNoUse : IUtf8JsonSerializable + public partial class RoundTripOnNoUse : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripOnNoUse)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredList"u8); writer.WriteStartArray(); @@ -26,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndArray(); writer.WritePropertyName("baseModelProp"u8); writer.WriteStringValue(BaseModelProp); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RoundTripOnNoUse DeserializeRoundTripOnNoUse(JsonElement element) + RoundTripOnNoUse IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripOnNoUse)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRoundTripOnNoUse(document.RootElement, options); + } + + internal static RoundTripOnNoUse DeserializeRoundTripOnNoUse(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } IList requiredList = default; string baseModelProp = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredList"u8)) @@ -54,20 +95,56 @@ internal static RoundTripOnNoUse DeserializeRoundTripOnNoUse(JsonElement element baseModelProp = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new RoundTripOnNoUse(baseModelProp, requiredList); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RoundTripOnNoUse(baseModelProp, serializedAdditionalRawData, requiredList); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RoundTripOnNoUse)} does not support '{options.Format}' format."); + } + } + + RoundTripOnNoUse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRoundTripOnNoUse(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RoundTripOnNoUse)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. - internal static RoundTripOnNoUse FromResponse(Response response) + internal static new RoundTripOnNoUse FromResponse(Response response) { using var document = JsonDocument.Parse(response.Content); return DeserializeRoundTripOnNoUse(document.RootElement); } /// Convert into a Utf8JsonRequestContent. - internal virtual RequestContent ToRequestContent() + internal override RequestContent ToRequestContent() { var content = new Utf8JsonRequestContent(); content.JsonWriter.WriteObjectValue(this); diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOnNoUse.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOnNoUse.cs index 5eab5a187b7..be2138d3c86 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOnNoUse.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOnNoUse.cs @@ -29,15 +29,18 @@ public RoundTripOnNoUse(string baseModelProp, IEnumerable requir /// Initializes a new instance of . /// base model property. + /// Keeps track of any properties unknown to the library. /// Required collection. - /// is null. - internal RoundTripOnNoUse(string baseModelProp, IList requiredList) : base(baseModelProp) + internal RoundTripOnNoUse(string baseModelProp, IDictionary serializedAdditionalRawData, IList requiredList) : base(baseModelProp, serializedAdditionalRawData) { - Argument.AssertNotNull(baseModelProp, nameof(baseModelProp)); - RequiredList = requiredList; } + /// Initializes a new instance of for deserialization. + internal RoundTripOnNoUse() + { + } + /// Required collection. public IList RequiredList { get; } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOptionalModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOptionalModel.Serialization.cs index ffba2999aa3..0de336ca4f8 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOptionalModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOptionalModel.Serialization.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -13,10 +14,18 @@ namespace ModelsTypeSpec.Models { - public partial class RoundTripOptionalModel : IUtf8JsonSerializable + public partial class RoundTripOptionalModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripOptionalModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(OptionalString)) { @@ -136,11 +145,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RoundTripOptionalModel DeserializeRoundTripOptionalModel(JsonElement element) + RoundTripOptionalModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripOptionalModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRoundTripOptionalModel(document.RootElement, options); + } + + internal static RoundTripOptionalModel DeserializeRoundTripOptionalModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -160,6 +198,8 @@ internal static RoundTripOptionalModel DeserializeRoundTripOptionalModel(JsonEle Optional optionalPlainDate = default; Optional optionalPlainTime = default; Optional> optionalCollectionWithNullableIntElement = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("optionalString"u8)) @@ -335,10 +375,46 @@ internal static RoundTripOptionalModel DeserializeRoundTripOptionalModel(JsonEle optionalCollectionWithNullableIntElement = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new RoundTripOptionalModel(optionalString.Value, Optional.ToNullable(optionalInt), Optional.ToList(optionalStringList), Optional.ToList(optionalIntList), Optional.ToList(optionalModelList), optionalModel.Value, optionalModelWithPropertiesOnBase.Value, Optional.ToNullable(optionalFixedStringEnum), Optional.ToNullable(optionalExtensibleEnum), Optional.ToDictionary(optionalIntRecord), Optional.ToDictionary(optionalStringRecord), Optional.ToDictionary(optionalModelRecord), Optional.ToNullable(optionalPlainDate), Optional.ToNullable(optionalPlainTime), Optional.ToList(optionalCollectionWithNullableIntElement)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RoundTripOptionalModel(optionalString.Value, Optional.ToNullable(optionalInt), Optional.ToList(optionalStringList), Optional.ToList(optionalIntList), Optional.ToList(optionalModelList), optionalModel.Value, optionalModelWithPropertiesOnBase.Value, Optional.ToNullable(optionalFixedStringEnum), Optional.ToNullable(optionalExtensibleEnum), Optional.ToDictionary(optionalIntRecord), Optional.ToDictionary(optionalStringRecord), Optional.ToDictionary(optionalModelRecord), Optional.ToNullable(optionalPlainDate), Optional.ToNullable(optionalPlainTime), Optional.ToList(optionalCollectionWithNullableIntElement), serializedAdditionalRawData); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RoundTripOptionalModel)} does not support '{options.Format}' format."); + } + } + + RoundTripOptionalModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRoundTripOptionalModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RoundTripOptionalModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static RoundTripOptionalModel FromResponse(Response response) diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOptionalModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOptionalModel.cs index d781db7e5e8..3ef374a7040 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOptionalModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripOptionalModel.cs @@ -15,6 +15,38 @@ namespace ModelsTypeSpec.Models [Obsolete("deprecated for test")] public partial class RoundTripOptionalModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public RoundTripOptionalModel() { @@ -43,7 +75,8 @@ public RoundTripOptionalModel() /// Optional plainDate. /// Optional plainTime. /// Optional collection of which the element is a nullable int. - internal RoundTripOptionalModel(string optionalString, int? optionalInt, IList optionalStringList, IList optionalIntList, IList optionalModelList, DerivedModel optionalModel, DerivedModelWithProperties optionalModelWithPropertiesOnBase, FixedStringEnum? optionalFixedStringEnum, ExtensibleEnum? optionalExtensibleEnum, IDictionary optionalIntRecord, IDictionary optionalStringRecord, IDictionary optionalModelRecord, DateTimeOffset? optionalPlainDate, TimeSpan? optionalPlainTime, IList optionalCollectionWithNullableIntElement) + /// Keeps track of any properties unknown to the library. + internal RoundTripOptionalModel(string optionalString, int? optionalInt, IList optionalStringList, IList optionalIntList, IList optionalModelList, DerivedModel optionalModel, DerivedModelWithProperties optionalModelWithPropertiesOnBase, FixedStringEnum? optionalFixedStringEnum, ExtensibleEnum? optionalExtensibleEnum, IDictionary optionalIntRecord, IDictionary optionalStringRecord, IDictionary optionalModelRecord, DateTimeOffset? optionalPlainDate, TimeSpan? optionalPlainTime, IList optionalCollectionWithNullableIntElement, IDictionary serializedAdditionalRawData) { OptionalString = optionalString; OptionalInt = optionalInt; @@ -60,6 +93,7 @@ internal RoundTripOptionalModel(string optionalString, int? optionalInt, IList Optional string, illustrating an optional reference type property. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripPrimitiveModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripPrimitiveModel.Serialization.cs index c0a04f83888..5f85d6fb50d 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripPrimitiveModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripPrimitiveModel.Serialization.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -13,10 +14,18 @@ namespace ModelsTypeSpec.Models { - public partial class RoundTripPrimitiveModel : IUtf8JsonSerializable + public partial class RoundTripPrimitiveModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripPrimitiveModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("requiredString"u8); writer.WriteStringValue(RequiredString); @@ -48,11 +57,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNumberValue(item.Value); } writer.WriteEndArray(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RoundTripPrimitiveModel DeserializeRoundTripPrimitiveModel(JsonElement element) + RoundTripPrimitiveModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripPrimitiveModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRoundTripPrimitiveModel(document.RootElement, options); + } + + internal static RoundTripPrimitiveModel DeserializeRoundTripPrimitiveModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -67,6 +105,8 @@ internal static RoundTripPrimitiveModel DeserializeRoundTripPrimitiveModel(JsonE DateTimeOffset requiredDateTimeOffset = default; TimeSpan requiredTimeSpan = default; IList requiredCollectionWithNullableFloatElement = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredString"u8)) @@ -131,13 +171,49 @@ internal static RoundTripPrimitiveModel DeserializeRoundTripPrimitiveModel(JsonE requiredCollectionWithNullableFloatElement = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new RoundTripPrimitiveModel(requiredString, requiredInt, requiredInt64, requiredSafeInt, requiredFloat, requiredDouble, requiredBoolean, requiredDateTimeOffset, requiredTimeSpan, requiredCollectionWithNullableFloatElement); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RoundTripPrimitiveModel(serializedAdditionalRawData, requiredString, requiredInt, requiredInt64, requiredSafeInt, requiredFloat, requiredDouble, requiredBoolean, requiredDateTimeOffset, requiredTimeSpan, requiredCollectionWithNullableFloatElement); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RoundTripPrimitiveModel)} does not support '{options.Format}' format."); + } + } + + RoundTripPrimitiveModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRoundTripPrimitiveModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RoundTripPrimitiveModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. - internal static RoundTripPrimitiveModel FromResponse(Response response) + internal static new RoundTripPrimitiveModel FromResponse(Response response) { using var document = JsonDocument.Parse(response.Content); return DeserializeRoundTripPrimitiveModel(document.RootElement); diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripPrimitiveModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripPrimitiveModel.cs index 664f9793f9f..4e91f6f3a18 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripPrimitiveModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripPrimitiveModel.cs @@ -45,6 +45,7 @@ public RoundTripPrimitiveModel(string requiredString, int requiredInt, long requ } /// Initializes a new instance of . + /// Keeps track of any properties unknown to the library. /// Required string, illustrating a reference type property. /// Required int, illustrating a value type property. /// Required int64, illustrating a value type property. @@ -55,7 +56,7 @@ public RoundTripPrimitiveModel(string requiredString, int requiredInt, long requ /// Required date time offset, illustrating a reference type property. /// Required time span, illustrating a value type property. /// Required collection of which the element is a nullable float. - internal RoundTripPrimitiveModel(string requiredString, int requiredInt, long requiredInt64, long requiredSafeInt, float requiredFloat, double requiredDouble, bool requiredBoolean, DateTimeOffset requiredDateTimeOffset, TimeSpan requiredTimeSpan, IList requiredCollectionWithNullableFloatElement) + internal RoundTripPrimitiveModel(IDictionary serializedAdditionalRawData, string requiredString, int requiredInt, long requiredInt64, long requiredSafeInt, float requiredFloat, double requiredDouble, bool requiredBoolean, DateTimeOffset requiredDateTimeOffset, TimeSpan requiredTimeSpan, IList requiredCollectionWithNullableFloatElement) : base(serializedAdditionalRawData) { RequiredString = requiredString; RequiredInt = requiredInt; @@ -69,6 +70,11 @@ internal RoundTripPrimitiveModel(string requiredString, int requiredInt, long re RequiredCollectionWithNullableFloatElement = requiredCollectionWithNullableFloatElement; } + /// Initializes a new instance of for deserialization. + internal RoundTripPrimitiveModel() + { + } + /// Required string, illustrating a reference type property. public string RequiredString { get; set; } /// Required int, illustrating a value type property. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripReadOnlyModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripReadOnlyModel.Serialization.cs index a519748bbcb..bae7083915d 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripReadOnlyModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripReadOnlyModel.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure; @@ -12,10 +14,250 @@ namespace ModelsTypeSpec.Models { - public partial class RoundTripReadOnlyModel + public partial class RoundTripReadOnlyModel : IUtf8JsonSerializable, IJsonModel { - internal static RoundTripReadOnlyModel DeserializeRoundTripReadOnlyModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripReadOnlyModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadonlyString"u8); + writer.WriteStringValue(RequiredReadonlyString); + } + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadonlyInt"u8); + writer.WriteNumberValue(RequiredReadonlyInt); + } + if (options.Format != "W" && Optional.IsDefined(OptionalReadonlyString)) + { + writer.WritePropertyName("optionalReadonlyString"u8); + writer.WriteStringValue(OptionalReadonlyString); + } + if (options.Format != "W" && Optional.IsDefined(OptionalReadonlyInt)) + { + writer.WritePropertyName("optionalReadonlyInt"u8); + writer.WriteNumberValue(OptionalReadonlyInt.Value); + } + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadonlyModel"u8); + writer.WriteObjectValue(RequiredReadonlyModel); + } + if (options.Format != "W" && Optional.IsDefined(OptionalReadonlyModel)) + { + writer.WritePropertyName("optionalReadonlyModel"u8); + writer.WriteObjectValue(OptionalReadonlyModel); + } + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadonlyFixedStringEnum"u8); + writer.WriteStringValue(RequiredReadonlyFixedStringEnum.ToSerialString()); + } + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadonlyExtensibleEnum"u8); + writer.WriteStringValue(RequiredReadonlyExtensibleEnum.ToString()); + } + if (options.Format != "W") + { + writer.WritePropertyName("optionalReadonlyFixedStringEnum"u8); + writer.WriteStringValue(OptionalReadonlyFixedStringEnum.ToSerialString()); + } + if (options.Format != "W") + { + writer.WritePropertyName("optionalReadonlyExtensibleEnum"u8); + writer.WriteStringValue(OptionalReadonlyExtensibleEnum.ToString()); + } + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadonlyStringList"u8); + writer.WriteStartArray(); + foreach (var item in RequiredReadonlyStringList) + { + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadonlyIntList"u8); + writer.WriteStartArray(); + foreach (var item in RequiredReadonlyIntList) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadOnlyModelList"u8); + writer.WriteStartArray(); + foreach (var item in RequiredReadOnlyModelList) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadOnlyIntRecord"u8); + writer.WriteStartObject(); + foreach (var item in RequiredReadOnlyIntRecord) + { + writer.WritePropertyName(item.Key); + writer.WriteNumberValue(item.Value); + } + writer.WriteEndObject(); + } + if (options.Format != "W") + { + writer.WritePropertyName("requiredStringRecord"u8); + writer.WriteStartObject(); + foreach (var item in RequiredStringRecord) + { + writer.WritePropertyName(item.Key); + writer.WriteStringValue(item.Value); + } + writer.WriteEndObject(); + } + if (options.Format != "W") + { + writer.WritePropertyName("requiredReadOnlyModelRecord"u8); + writer.WriteStartObject(); + foreach (var item in RequiredReadOnlyModelRecord) + { + writer.WritePropertyName(item.Key); + writer.WriteObjectValue(item.Value); + } + writer.WriteEndObject(); + } + if (options.Format != "W" && Optional.IsCollectionDefined(OptionalReadonlyStringList)) + { + writer.WritePropertyName("optionalReadonlyStringList"u8); + writer.WriteStartArray(); + foreach (var item in OptionalReadonlyStringList) + { + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W" && Optional.IsCollectionDefined(OptionalReadonlyIntList)) + { + writer.WritePropertyName("optionalReadonlyIntList"u8); + writer.WriteStartArray(); + foreach (var item in OptionalReadonlyIntList) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W" && Optional.IsCollectionDefined(OptionalReadOnlyModelList)) + { + writer.WritePropertyName("optionalReadOnlyModelList"u8); + writer.WriteStartArray(); + foreach (var item in OptionalReadOnlyModelList) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + writer.WritePropertyName("optionalReadOnlyIntRecord"u8); + writer.WriteStartObject(); + foreach (var item in OptionalReadOnlyIntRecord) + { + writer.WritePropertyName(item.Key); + writer.WriteNumberValue(item.Value); + } + writer.WriteEndObject(); + writer.WritePropertyName("optionalReadOnlyStringRecord"u8); + writer.WriteStartObject(); + foreach (var item in OptionalReadOnlyStringRecord) + { + writer.WritePropertyName(item.Key); + writer.WriteStringValue(item.Value); + } + writer.WriteEndObject(); + if (options.Format != "W" && Optional.IsCollectionDefined(OptionalModelRecord)) + { + writer.WritePropertyName("optionalModelRecord"u8); + writer.WriteStartObject(); + foreach (var item in OptionalModelRecord) + { + writer.WritePropertyName(item.Key); + writer.WriteObjectValue(item.Value); + } + writer.WriteEndObject(); + } + writer.WritePropertyName("requiredCollectionWithNullableIntElement"u8); + writer.WriteStartArray(); + foreach (var item in RequiredCollectionWithNullableIntElement) + { + if (item == null) + { + writer.WriteNullValue(); + continue; + } + writer.WriteNumberValue(item.Value); + } + writer.WriteEndArray(); + if (Optional.IsCollectionDefined(OptionalCollectionWithNullableBooleanElement)) + { + writer.WritePropertyName("optionalCollectionWithNullableBooleanElement"u8); + writer.WriteStartArray(); + foreach (var item in OptionalCollectionWithNullableBooleanElement) + { + if (item == null) + { + writer.WriteNullValue(); + continue; + } + writer.WriteBooleanValue(item.Value); + } + writer.WriteEndArray(); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + RoundTripReadOnlyModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripReadOnlyModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRoundTripReadOnlyModel(document.RootElement, options); + } + + internal static RoundTripReadOnlyModel DeserializeRoundTripReadOnlyModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -44,6 +286,8 @@ internal static RoundTripReadOnlyModel DeserializeRoundTripReadOnlyModel(JsonEle Optional> optionalModelRecord = default; IReadOnlyList requiredCollectionWithNullableIntElement = default; Optional> optionalCollectionWithNullableBooleanElement = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("requiredReadonlyString"u8)) @@ -278,10 +522,46 @@ internal static RoundTripReadOnlyModel DeserializeRoundTripReadOnlyModel(JsonEle optionalCollectionWithNullableBooleanElement = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new RoundTripReadOnlyModel(requiredReadonlyString, requiredReadonlyInt, optionalReadonlyString.Value, Optional.ToNullable(optionalReadonlyInt), requiredReadonlyModel, optionalReadonlyModel.Value, requiredReadonlyFixedStringEnum, requiredReadonlyExtensibleEnum, optionalReadonlyFixedStringEnum, optionalReadonlyExtensibleEnum, requiredReadonlyStringList, requiredReadonlyIntList, requiredReadOnlyModelList, requiredReadOnlyIntRecord, requiredStringRecord, requiredReadOnlyModelRecord, Optional.ToList(optionalReadonlyStringList), Optional.ToList(optionalReadonlyIntList), Optional.ToList(optionalReadOnlyModelList), optionalReadOnlyIntRecord, optionalReadOnlyStringRecord, Optional.ToDictionary(optionalModelRecord), requiredCollectionWithNullableIntElement, Optional.ToList(optionalCollectionWithNullableBooleanElement)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RoundTripReadOnlyModel(requiredReadonlyString, requiredReadonlyInt, optionalReadonlyString.Value, Optional.ToNullable(optionalReadonlyInt), requiredReadonlyModel, optionalReadonlyModel.Value, requiredReadonlyFixedStringEnum, requiredReadonlyExtensibleEnum, optionalReadonlyFixedStringEnum, optionalReadonlyExtensibleEnum, requiredReadonlyStringList, requiredReadonlyIntList, requiredReadOnlyModelList, requiredReadOnlyIntRecord, requiredStringRecord, requiredReadOnlyModelRecord, Optional.ToList(optionalReadonlyStringList), Optional.ToList(optionalReadonlyIntList), Optional.ToList(optionalReadOnlyModelList), optionalReadOnlyIntRecord, optionalReadOnlyStringRecord, Optional.ToDictionary(optionalModelRecord), requiredCollectionWithNullableIntElement, Optional.ToList(optionalCollectionWithNullableBooleanElement), serializedAdditionalRawData); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RoundTripReadOnlyModel)} does not support '{options.Format}' format."); + } + } + + RoundTripReadOnlyModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRoundTripReadOnlyModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RoundTripReadOnlyModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static RoundTripReadOnlyModel FromResponse(Response response) @@ -289,5 +569,13 @@ internal static RoundTripReadOnlyModel FromResponse(Response response) using var document = JsonDocument.Parse(response.Content); return DeserializeRoundTripReadOnlyModel(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripReadOnlyModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripReadOnlyModel.cs index c3b5f4899b5..b1018e32596 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripReadOnlyModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripReadOnlyModel.cs @@ -15,6 +15,38 @@ namespace ModelsTypeSpec.Models /// Output model with readonly properties. public partial class RoundTripReadOnlyModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Optional int record. /// Optional string record. @@ -67,7 +99,8 @@ internal RoundTripReadOnlyModel(IReadOnlyDictionary optionalReadOnl /// Optional model record. /// Required collection of which the element is a nullable int. /// Optional collection of which the element is a nullable boolean. - internal RoundTripReadOnlyModel(string requiredReadonlyString, int requiredReadonlyInt, string optionalReadonlyString, int? optionalReadonlyInt, DerivedModel requiredReadonlyModel, DerivedModel optionalReadonlyModel, FixedStringEnum requiredReadonlyFixedStringEnum, ExtensibleEnum requiredReadonlyExtensibleEnum, FixedStringEnum optionalReadonlyFixedStringEnum, ExtensibleEnum optionalReadonlyExtensibleEnum, IReadOnlyList requiredReadonlyStringList, IReadOnlyList requiredReadonlyIntList, IReadOnlyList requiredReadOnlyModelList, IReadOnlyDictionary requiredReadOnlyIntRecord, IReadOnlyDictionary requiredStringRecord, IReadOnlyDictionary requiredReadOnlyModelRecord, IReadOnlyList optionalReadonlyStringList, IReadOnlyList optionalReadonlyIntList, IReadOnlyList optionalReadOnlyModelList, IReadOnlyDictionary optionalReadOnlyIntRecord, IReadOnlyDictionary optionalReadOnlyStringRecord, IReadOnlyDictionary optionalModelRecord, IReadOnlyList requiredCollectionWithNullableIntElement, IReadOnlyList optionalCollectionWithNullableBooleanElement) + /// Keeps track of any properties unknown to the library. + internal RoundTripReadOnlyModel(string requiredReadonlyString, int requiredReadonlyInt, string optionalReadonlyString, int? optionalReadonlyInt, DerivedModel requiredReadonlyModel, DerivedModel optionalReadonlyModel, FixedStringEnum requiredReadonlyFixedStringEnum, ExtensibleEnum requiredReadonlyExtensibleEnum, FixedStringEnum optionalReadonlyFixedStringEnum, ExtensibleEnum optionalReadonlyExtensibleEnum, IReadOnlyList requiredReadonlyStringList, IReadOnlyList requiredReadonlyIntList, IReadOnlyList requiredReadOnlyModelList, IReadOnlyDictionary requiredReadOnlyIntRecord, IReadOnlyDictionary requiredStringRecord, IReadOnlyDictionary requiredReadOnlyModelRecord, IReadOnlyList optionalReadonlyStringList, IReadOnlyList optionalReadonlyIntList, IReadOnlyList optionalReadOnlyModelList, IReadOnlyDictionary optionalReadOnlyIntRecord, IReadOnlyDictionary optionalReadOnlyStringRecord, IReadOnlyDictionary optionalModelRecord, IReadOnlyList requiredCollectionWithNullableIntElement, IReadOnlyList optionalCollectionWithNullableBooleanElement, IDictionary serializedAdditionalRawData) { RequiredReadonlyString = requiredReadonlyString; RequiredReadonlyInt = requiredReadonlyInt; @@ -93,6 +126,12 @@ internal RoundTripReadOnlyModel(string requiredReadonlyString, int requiredReado OptionalModelRecord = optionalModelRecord; RequiredCollectionWithNullableIntElement = requiredCollectionWithNullableIntElement; OptionalCollectionWithNullableBooleanElement = optionalCollectionWithNullableBooleanElement; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal RoundTripReadOnlyModel() + { } /// Required string, illustrating a readonly reference type property. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripRecursiveModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripRecursiveModel.Serialization.cs index 1bbe1a1f1d8..72ab341cde7 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripRecursiveModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripRecursiveModel.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class RoundTripRecursiveModel : IUtf8JsonSerializable + public partial class RoundTripRecursiveModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripRecursiveModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("message"u8); writer.WriteStringValue(Message); @@ -23,17 +34,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("inner"u8); writer.WriteObjectValue(Inner); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RoundTripRecursiveModel DeserializeRoundTripRecursiveModel(JsonElement element) + RoundTripRecursiveModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RoundTripRecursiveModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRoundTripRecursiveModel(document.RootElement, options); + } + + internal static RoundTripRecursiveModel DeserializeRoundTripRecursiveModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } string message = default; Optional inner = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("message"u8)) @@ -50,10 +92,46 @@ internal static RoundTripRecursiveModel DeserializeRoundTripRecursiveModel(JsonE inner = DeserializeRoundTripRecursiveModel(property.Value); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new RoundTripRecursiveModel(message, inner.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RoundTripRecursiveModel(message, inner.Value, serializedAdditionalRawData); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RoundTripRecursiveModel)} does not support '{options.Format}' format."); + } + } + + RoundTripRecursiveModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRoundTripRecursiveModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RoundTripRecursiveModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static RoundTripRecursiveModel FromResponse(Response response) diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripRecursiveModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripRecursiveModel.cs index 53784b928c8..d0fb4941582 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripRecursiveModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/RoundTripRecursiveModel.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace ModelsTypeSpec.Models @@ -13,6 +14,38 @@ namespace ModelsTypeSpec.Models /// Roundtrip model that has property of its own type. public partial class RoundTripRecursiveModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Message. /// is null. @@ -26,10 +59,17 @@ public RoundTripRecursiveModel(string message) /// Initializes a new instance of . /// Message. /// Required Record. - internal RoundTripRecursiveModel(string message, RoundTripRecursiveModel inner) + /// Keeps track of any properties unknown to the library. + internal RoundTripRecursiveModel(string message, RoundTripRecursiveModel inner, IDictionary serializedAdditionalRawData) { Message = message; Inner = inner; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal RoundTripRecursiveModel() + { } /// Message. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/SecondDerivedOutputModel.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/SecondDerivedOutputModel.Serialization.cs index 95130d67dc0..39033103acd 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/SecondDerivedOutputModel.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/SecondDerivedOutputModel.Serialization.cs @@ -5,21 +5,74 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; +using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class SecondDerivedOutputModel + public partial class SecondDerivedOutputModel : IUtf8JsonSerializable, IJsonModel { - internal static SecondDerivedOutputModel DeserializeSecondDerivedOutputModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SecondDerivedOutputModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("second"u8); + writer.WriteBooleanValue(Second); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + SecondDerivedOutputModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SecondDerivedOutputModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSecondDerivedOutputModel(document.RootElement, options); + } + + internal static SecondDerivedOutputModel DeserializeSecondDerivedOutputModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } bool second = default; string kind = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("second"u8)) @@ -32,10 +85,46 @@ internal static SecondDerivedOutputModel DeserializeSecondDerivedOutputModel(Jso kind = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new SecondDerivedOutputModel(kind, serializedAdditionalRawData, second); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(SecondDerivedOutputModel)} does not support '{options.Format}' format."); + } + } + + SecondDerivedOutputModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSecondDerivedOutputModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SecondDerivedOutputModel)} does not support '{options.Format}' format."); } - return new SecondDerivedOutputModel(kind, second); } + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new SecondDerivedOutputModel FromResponse(Response response) @@ -43,5 +132,13 @@ internal static SecondDerivedOutputModel DeserializeSecondDerivedOutputModel(Jso using var document = JsonDocument.Parse(response.Content); return DeserializeSecondDerivedOutputModel(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal override RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/SecondDerivedOutputModel.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/SecondDerivedOutputModel.cs index 5ffd144a17f..ad914f96b5a 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/SecondDerivedOutputModel.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/SecondDerivedOutputModel.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// Second derived model as an output. @@ -20,12 +23,18 @@ internal SecondDerivedOutputModel(bool second) /// Initializes a new instance of . /// Discriminator. + /// Keeps track of any properties unknown to the library. /// - internal SecondDerivedOutputModel(string kind, bool second) : base(kind) + internal SecondDerivedOutputModel(string kind, IDictionary serializedAdditionalRawData, bool second) : base(kind, serializedAdditionalRawData) { Second = second; } + /// Initializes a new instance of for deserialization. + internal SecondDerivedOutputModel() + { + } + /// Gets the second. public bool Second { get; } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/SingleBase.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/SingleBase.Serialization.cs index c61ee17cfe4..70aa54ff4ef 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/SingleBase.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/SingleBase.Serialization.cs @@ -5,15 +5,66 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; using Azure; +using Azure.Core; namespace ModelsTypeSpec.Models { - public partial class SingleBase + [PersistableModelProxy(typeof(UnknownSingleBase))] + public partial class SingleBase : IUtf8JsonSerializable, IJsonModel { - internal static SingleBase DeserializeSingleBase(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SingleBase)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind); + writer.WritePropertyName("size"u8); + writer.WriteNumberValue(Size); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + SingleBase IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SingleBase)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSingleBase(document.RootElement, options); + } + + internal static SingleBase DeserializeSingleBase(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -21,6 +72,37 @@ internal static SingleBase DeserializeSingleBase(JsonElement element) return UnknownSingleBase.DeserializeUnknownSingleBase(element); } + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(SingleBase)} does not support '{options.Format}' format."); + } + } + + SingleBase IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSingleBase(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SingleBase)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static SingleBase FromResponse(Response response) @@ -28,5 +110,13 @@ internal static SingleBase FromResponse(Response response) using var document = JsonDocument.Parse(response.Content); return DeserializeSingleBase(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal virtual RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/SingleBase.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/SingleBase.cs index cada1cf0a17..e9f9df17a25 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/SingleBase.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/SingleBase.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// Single base model without any child model. public abstract partial class SingleBase { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// protected SingleBase(int size) @@ -20,10 +55,17 @@ protected SingleBase(int size) /// Initializes a new instance of . /// Discriminator. /// - internal SingleBase(string kind, int size) + /// Keeps track of any properties unknown to the library. + internal SingleBase(string kind, int size, IDictionary serializedAdditionalRawData) { Kind = kind; Size = size; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal SingleBase() + { } /// Discriminator. diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownBaseModelWithDiscriminator.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownBaseModelWithDiscriminator.Serialization.cs index 6f621bc7f69..f1e06e17746 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownBaseModelWithDiscriminator.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownBaseModelWithDiscriminator.Serialization.cs @@ -5,16 +5,71 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace ModelsTypeSpec.Models { - internal partial class UnknownBaseModelWithDiscriminator + internal partial class UnknownBaseModelWithDiscriminator : IUtf8JsonSerializable, IJsonModel { - internal static UnknownBaseModelWithDiscriminator DeserializeUnknownBaseModelWithDiscriminator(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseModelWithDiscriminator)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("discriminatorProperty"u8); + writer.WriteStringValue(DiscriminatorProperty); + if (Optional.IsDefined(OptionalPropertyOnBase)) + { + writer.WritePropertyName("optionalPropertyOnBase"u8); + writer.WriteStringValue(OptionalPropertyOnBase); + } + writer.WritePropertyName("requiredPropertyOnBase"u8); + writer.WriteNumberValue(RequiredPropertyOnBase); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + BaseModelWithDiscriminator IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseModelWithDiscriminator)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownBaseModelWithDiscriminator(document.RootElement, options); + } + + internal static UnknownBaseModelWithDiscriminator DeserializeUnknownBaseModelWithDiscriminator(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -22,6 +77,8 @@ internal static UnknownBaseModelWithDiscriminator DeserializeUnknownBaseModelWit string discriminatorProperty = "Unknown"; Optional optionalPropertyOnBase = default; int requiredPropertyOnBase = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("discriminatorProperty"u8)) @@ -39,10 +96,46 @@ internal static UnknownBaseModelWithDiscriminator DeserializeUnknownBaseModelWit requiredPropertyOnBase = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new UnknownBaseModelWithDiscriminator(discriminatorProperty, optionalPropertyOnBase.Value, requiredPropertyOnBase, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(BaseModelWithDiscriminator)} does not support '{options.Format}' format."); } - return new UnknownBaseModelWithDiscriminator(discriminatorProperty, optionalPropertyOnBase.Value, requiredPropertyOnBase); } + BaseModelWithDiscriminator IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownBaseModelWithDiscriminator(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(BaseModelWithDiscriminator)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new UnknownBaseModelWithDiscriminator FromResponse(Response response) @@ -50,5 +143,13 @@ internal static UnknownBaseModelWithDiscriminator DeserializeUnknownBaseModelWit using var document = JsonDocument.Parse(response.Content); return DeserializeUnknownBaseModelWithDiscriminator(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal override RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownBaseModelWithDiscriminator.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownBaseModelWithDiscriminator.cs index 765f28fff0f..c25d48d8a53 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownBaseModelWithDiscriminator.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownBaseModelWithDiscriminator.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// Unknown version of BaseModelWithDiscriminator. @@ -20,7 +23,13 @@ internal UnknownBaseModelWithDiscriminator(int requiredPropertyOnBase) : base(re /// Discriminator. /// Optional property on base. /// Required property on base. - internal UnknownBaseModelWithDiscriminator(string discriminatorProperty, string optionalPropertyOnBase, int requiredPropertyOnBase) : base(discriminatorProperty, optionalPropertyOnBase, requiredPropertyOnBase) + /// Keeps track of any properties unknown to the library. + internal UnknownBaseModelWithDiscriminator(string discriminatorProperty, string optionalPropertyOnBase, int requiredPropertyOnBase, IDictionary serializedAdditionalRawData) : base(discriminatorProperty, optionalPropertyOnBase, requiredPropertyOnBase, serializedAdditionalRawData) + { + } + + /// Initializes a new instance of for deserialization. + internal UnknownBaseModelWithDiscriminator() { } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownOutputBaseModelWithDiscriminator.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownOutputBaseModelWithDiscriminator.Serialization.cs index 2ec1a562978..855c51458a1 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownOutputBaseModelWithDiscriminator.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownOutputBaseModelWithDiscriminator.Serialization.cs @@ -5,20 +5,71 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; +using Azure.Core; namespace ModelsTypeSpec.Models { - internal partial class UnknownOutputBaseModelWithDiscriminator + internal partial class UnknownOutputBaseModelWithDiscriminator : IUtf8JsonSerializable, IJsonModel { - internal static UnknownOutputBaseModelWithDiscriminator DeserializeUnknownOutputBaseModelWithDiscriminator(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputBaseModelWithDiscriminator)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + OutputBaseModelWithDiscriminator IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OutputBaseModelWithDiscriminator)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownOutputBaseModelWithDiscriminator(document.RootElement, options); + } + + internal static UnknownOutputBaseModelWithDiscriminator DeserializeUnknownOutputBaseModelWithDiscriminator(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } string kind = "Unknown"; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("kind"u8)) @@ -26,10 +77,46 @@ internal static UnknownOutputBaseModelWithDiscriminator DeserializeUnknownOutput kind = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new UnknownOutputBaseModelWithDiscriminator(kind, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(OutputBaseModelWithDiscriminator)} does not support '{options.Format}' format."); + } + } + + OutputBaseModelWithDiscriminator IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownOutputBaseModelWithDiscriminator(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(OutputBaseModelWithDiscriminator)} does not support '{options.Format}' format."); } - return new UnknownOutputBaseModelWithDiscriminator(kind); } + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new UnknownOutputBaseModelWithDiscriminator FromResponse(Response response) @@ -37,5 +124,13 @@ internal static UnknownOutputBaseModelWithDiscriminator DeserializeUnknownOutput using var document = JsonDocument.Parse(response.Content); return DeserializeUnknownOutputBaseModelWithDiscriminator(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal override RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownOutputBaseModelWithDiscriminator.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownOutputBaseModelWithDiscriminator.cs index fccb8fac064..4cc3f728d09 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownOutputBaseModelWithDiscriminator.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownOutputBaseModelWithDiscriminator.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// Unknown version of OutputBaseModelWithDiscriminator. @@ -17,7 +20,8 @@ internal UnknownOutputBaseModelWithDiscriminator() /// Initializes a new instance of . /// Discriminator. - internal UnknownOutputBaseModelWithDiscriminator(string kind) : base(kind) + /// Keeps track of any properties unknown to the library. + internal UnknownOutputBaseModelWithDiscriminator(string kind, IDictionary serializedAdditionalRawData) : base(kind, serializedAdditionalRawData) { } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownSingleBase.Serialization.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownSingleBase.Serialization.cs index 8b364d095e1..a86d7643c39 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownSingleBase.Serialization.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownSingleBase.Serialization.cs @@ -5,21 +5,74 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; +using Azure.Core; namespace ModelsTypeSpec.Models { - internal partial class UnknownSingleBase + internal partial class UnknownSingleBase : IUtf8JsonSerializable, IJsonModel { - internal static UnknownSingleBase DeserializeUnknownSingleBase(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SingleBase)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind); + writer.WritePropertyName("size"u8); + writer.WriteNumberValue(Size); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + SingleBase IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SingleBase)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownSingleBase(document.RootElement, options); + } + + internal static UnknownSingleBase DeserializeUnknownSingleBase(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } string kind = "Unknown"; int size = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("kind"u8)) @@ -32,10 +85,46 @@ internal static UnknownSingleBase DeserializeUnknownSingleBase(JsonElement eleme size = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new UnknownSingleBase(kind, size, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(SingleBase)} does not support '{options.Format}' format."); + } + } + + SingleBase IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownSingleBase(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SingleBase)} does not support '{options.Format}' format."); } - return new UnknownSingleBase(kind, size); } + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + /// Deserializes the model from a raw response. /// The response to deserialize the model from. internal static new UnknownSingleBase FromResponse(Response response) @@ -43,5 +132,13 @@ internal static UnknownSingleBase DeserializeUnknownSingleBase(JsonElement eleme using var document = JsonDocument.Parse(response.Content); return DeserializeUnknownSingleBase(document.RootElement); } + + /// Convert into a Utf8JsonRequestContent. + internal override RequestContent ToRequestContent() + { + var content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(this); + return content; + } } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownSingleBase.cs b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownSingleBase.cs index 6be5139c282..85e18f45e33 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownSingleBase.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/Models/UnknownSingleBase.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace ModelsTypeSpec.Models { /// Unknown version of SingleBase. @@ -19,7 +22,13 @@ internal UnknownSingleBase(int size) : base(size) /// Initializes a new instance of . /// Discriminator. /// - internal UnknownSingleBase(string kind, int size) : base(kind, size) + /// Keeps track of any properties unknown to the library. + internal UnknownSingleBase(string kind, int size, IDictionary serializedAdditionalRawData) : base(kind, size, serializedAdditionalRawData) + { + } + + /// Initializes a new instance of for deserialization. + internal UnknownSingleBase() { } } diff --git a/test/TestProjects/Models-TypeSpec/src/Generated/ModelsTypeSpecModelFactory.cs b/test/TestProjects/Models-TypeSpec/src/Generated/ModelsTypeSpecModelFactory.cs index 7a7165d2215..f5e0b15eb81 100644 --- a/test/TestProjects/Models-TypeSpec/src/Generated/ModelsTypeSpecModelFactory.cs +++ b/test/TestProjects/Models-TypeSpec/src/Generated/ModelsTypeSpecModelFactory.cs @@ -14,6 +14,52 @@ namespace ModelsTypeSpec.Models /// Model factory for models. public static partial class ModelsTypeSpecModelFactory { + /// Initializes a new instance of . + /// Required string. + /// Required int. + /// Required nullable int. + /// Required nullable string. + /// Optional nullable int. + /// Optional nullable string. + /// Required model. + /// Required model. + /// Required primitive value type collection. + /// Required primitive reference type collection. + /// Required model collection. + /// Required model record. + /// Required collection of which the element is a nullable float. + /// Required collection of which the element is a nullable boolean. + /// Required model nullable collection. + /// Required string nullable collection. + /// Required int nullable collection. + /// Optional model collection. + /// Optional string collection. + /// Optional int collection. + /// Optional model nullable collection. + /// Optional string nullable collection. + /// Optional int nullable collection. + /// A new instance for mocking. + public static InputModel InputModel(string requiredString = null, int requiredInt = default, int? requiredNullableInt = null, string requiredNullableString = null, int? nonRequiredNullableInt = null, string nonRequiredNullableString = null, BaseModel requiredModel = null, BaseModel requiredModel2 = null, IEnumerable requiredIntList = null, IEnumerable requiredStringList = null, IEnumerable requiredModelList = null, IDictionary requiredModelRecord = null, IEnumerable requiredCollectionWithNullableFloatElement = null, IEnumerable requiredCollectionWithNullableBooleanElement = null, IEnumerable requiredNullableModelList = null, IEnumerable requiredNullableStringList = null, IEnumerable requiredNullableIntList = null, IEnumerable nonRequiredModelList = null, IEnumerable nonRequiredStringList = null, IEnumerable nonRequiredIntList = null, IEnumerable nonRequiredNullableModelList = null, IEnumerable nonRequiredNullableStringList = null, IEnumerable nonRequiredNullableIntList = null) + { + requiredIntList ??= new List(); + requiredStringList ??= new List(); + requiredModelList ??= new List(); + requiredModelRecord ??= new Dictionary(); + requiredCollectionWithNullableFloatElement ??= new List(); + requiredCollectionWithNullableBooleanElement ??= new List(); + requiredNullableModelList ??= new List(); + requiredNullableStringList ??= new List(); + requiredNullableIntList ??= new List(); + nonRequiredModelList ??= new List(); + nonRequiredStringList ??= new List(); + nonRequiredIntList ??= new List(); + nonRequiredNullableModelList ??= new List(); + nonRequiredNullableStringList ??= new List(); + nonRequiredNullableIntList ??= new List(); + + return new InputModel(requiredString, requiredInt, requiredNullableInt, requiredNullableString, nonRequiredNullableInt, nonRequiredNullableString, requiredModel, requiredModel2, requiredIntList?.ToList(), requiredStringList?.ToList(), requiredModelList?.ToList(), requiredModelRecord, requiredCollectionWithNullableFloatElement?.ToList(), requiredCollectionWithNullableBooleanElement?.ToList(), requiredNullableModelList?.ToList(), requiredNullableStringList?.ToList(), requiredNullableIntList?.ToList(), nonRequiredModelList?.ToList(), nonRequiredStringList?.ToList(), nonRequiredIntList?.ToList(), nonRequiredNullableModelList?.ToList(), nonRequiredNullableStringList?.ToList(), nonRequiredNullableIntList?.ToList(), serializedAdditionalRawData: null); + } + /// Initializes a new instance of . /// Required string, illustrating a reference type property. /// Required int, illustrating a value type property. @@ -61,7 +107,15 @@ public static RoundTripModel RoundTripModel(string requiredString = null, int re nonRequiredNullableIntList ??= new List(); nonRequiredNullableStringList ??= new List(); - return new RoundTripModel(requiredString, requiredInt, nonRequiredString, nonRequiredInt, requiredNullableInt, requiredNullableString, nonRequiredNullableInt, nonRequiredNullableString, requiredReadonlyInt, nonRequiredReadonlyInt, requiredModel, requiredFixedStringEnum, requiredFixedIntEnum, requiredExtensibleEnum, requiredList?.ToList(), requiredIntRecord, requiredStringRecord, requiredModelRecord, requiredBytes, optionalBytes, requiredUint8Array?.ToList(), optionalUint8Array?.ToList(), requiredUnknown, optionalUnknown, requiredInt8Array?.ToList(), optionalInt8Array?.ToList(), requiredNullableIntList?.ToList(), requiredNullableStringList?.ToList(), nonRequiredNullableIntList?.ToList(), nonRequiredNullableStringList?.ToList()); + return new RoundTripModel(serializedAdditionalRawData: null, requiredString, requiredInt, nonRequiredString, nonRequiredInt, requiredNullableInt, requiredNullableString, nonRequiredNullableInt, nonRequiredNullableString, requiredReadonlyInt, nonRequiredReadonlyInt, requiredModel, requiredFixedStringEnum, requiredFixedIntEnum, requiredExtensibleEnum, requiredList?.ToList(), requiredIntRecord, requiredStringRecord, requiredModelRecord, requiredBytes, optionalBytes, requiredUint8Array?.ToList(), optionalUint8Array?.ToList(), requiredUnknown, optionalUnknown, requiredInt8Array?.ToList(), optionalInt8Array?.ToList(), requiredNullableIntList?.ToList(), requiredNullableStringList?.ToList(), nonRequiredNullableIntList?.ToList(), nonRequiredNullableStringList?.ToList()); + } + + /// Initializes a new instance of . + /// Optional properties on base. + /// A new instance for mocking. + public static BaseModelWithProperties BaseModelWithProperties(string optionalPropertyOnBase = null) + { + return new BaseModelWithProperties(optionalPropertyOnBase, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -72,7 +126,7 @@ public static DerivedModelWithProperties DerivedModelWithProperties(string optio { requiredList ??= new List(); - return new DerivedModelWithProperties(optionalPropertyOnBase, requiredList?.ToList()); + return new DerivedModelWithProperties(optionalPropertyOnBase, serializedAdditionalRawData: null, requiredList?.ToList()); } /// Initializes a new instance of . @@ -118,7 +172,7 @@ public static RoundTripReadOnlyModel RoundTripReadOnlyModel(string requiredReado requiredCollectionWithNullableIntElement ??= new List(); optionalCollectionWithNullableBooleanElement ??= new List(); - return new RoundTripReadOnlyModel(requiredReadonlyString, requiredReadonlyInt, optionalReadonlyString, optionalReadonlyInt, requiredReadonlyModel, optionalReadonlyModel, requiredReadonlyFixedStringEnum, requiredReadonlyExtensibleEnum, optionalReadonlyFixedStringEnum, optionalReadonlyExtensibleEnum, requiredReadonlyStringList?.ToList(), requiredReadonlyIntList?.ToList(), requiredReadOnlyModelList?.ToList(), requiredReadOnlyIntRecord, requiredStringRecord, requiredReadOnlyModelRecord, optionalReadonlyStringList?.ToList(), optionalReadonlyIntList?.ToList(), optionalReadOnlyModelList?.ToList(), optionalReadOnlyIntRecord, optionalReadOnlyStringRecord, optionalModelRecord, requiredCollectionWithNullableIntElement?.ToList(), optionalCollectionWithNullableBooleanElement?.ToList()); + return new RoundTripReadOnlyModel(requiredReadonlyString, requiredReadonlyInt, optionalReadonlyString, optionalReadonlyInt, requiredReadonlyModel, optionalReadonlyModel, requiredReadonlyFixedStringEnum, requiredReadonlyExtensibleEnum, optionalReadonlyFixedStringEnum, optionalReadonlyExtensibleEnum, requiredReadonlyStringList?.ToList(), requiredReadonlyIntList?.ToList(), requiredReadOnlyModelList?.ToList(), requiredReadOnlyIntRecord, requiredStringRecord, requiredReadOnlyModelRecord, optionalReadonlyStringList?.ToList(), optionalReadonlyIntList?.ToList(), optionalReadOnlyModelList?.ToList(), optionalReadOnlyIntRecord, optionalReadOnlyStringRecord, optionalModelRecord, requiredCollectionWithNullableIntElement?.ToList(), optionalCollectionWithNullableBooleanElement?.ToList(), serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -141,7 +195,16 @@ public static OutputModel OutputModel(string requiredString = null, int required optionalRecord ??= new Dictionary(); optionalNullableRecord ??= new Dictionary(); - return new OutputModel(requiredString, requiredInt, requiredModel, requiredList?.ToList(), requiredModelRecord, optionalList?.ToList(), optionalNullableList?.ToList(), optionalRecord, optionalNullableRecord); + return new OutputModel(requiredString, requiredInt, requiredModel, requiredList?.ToList(), requiredModelRecord, optionalList?.ToList(), optionalNullableList?.ToList(), optionalRecord, optionalNullableRecord, serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// Message. + /// Required Record. + /// A new instance for mocking. + public static InputRecursiveModel InputRecursiveModel(string message = null, InputRecursiveModel inner = null) + { + return new InputRecursiveModel(message, inner, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -150,7 +213,15 @@ public static OutputModel OutputModel(string requiredString = null, int required /// A new instance for mocking. public static ErrorModel ErrorModel(string message = null, ErrorModel innerError = null) { - return new ErrorModel(message, innerError); + return new ErrorModel(message, innerError, serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// base model property. + /// A new instance for mocking. + public static NoUseBase NoUseBase(string baseModelProp = null) + { + return new NoUseBase(baseModelProp, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -159,7 +230,40 @@ public static ErrorModel ErrorModel(string message = null, ErrorModel innerError /// A new instance for mocking. public static SingleBase SingleBase(string kind = null, int size = default) { - return new UnknownSingleBase(kind, size); + return new UnknownSingleBase(kind, size, serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// A field to facet by, where the field is attributed as 'facetable'. + /// A new instance for mocking. + public static Facet Facet(string field = null) + { + return new Facet(field, serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// A field to facet by, where the field is attributed as 'facetable'. + /// The facet ranges to produce. The values must be listed in ascending order to get the expected results. For example, values=10,20 produces three buckets: one for base rate 0 up to but not including 10, one for 10 up to but not including 20, and one for 20 and higher. + /// + /// A new instance for mocking. + public static NumericValuesFacetint32 NumericValuesFacetint32(string field = null, IEnumerable values = null, int value = default) + { + values ??= new List(); + + return new NumericValuesFacetint32(field, serializedAdditionalRawData: null, values?.ToList(), value); + } + + /// Initializes a new instance of . + /// A field to facet by, where the field is attributed as 'facetable'. + /// The facet ranges to produce. The values must be listed in ascending order to get the expected results. For example, values=10,20 produces three buckets: one for base rate 0 up to but not including 10, one for 10 up to but not including 20, and one for 20 and higher. + /// + /// The facet type. + /// A new instance for mocking. + public static Int32ValuesFacet Int32ValuesFacet(string field = null, IEnumerable values = null, int value = default, Int32ValuesFacetKind kind = default) + { + values ??= new List(); + + return new Int32ValuesFacet(field, serializedAdditionalRawData: null, values?.ToList(), value, kind); } /// Initializes a new instance of . @@ -167,7 +271,7 @@ public static SingleBase SingleBase(string kind = null, int size = default) /// A new instance for mocking. public static FirstDerivedOutputModel FirstDerivedOutputModel(bool first = default) { - return new FirstDerivedOutputModel("first", first); + return new FirstDerivedOutputModel("first", serializedAdditionalRawData: null, first); } /// Initializes a new instance of . @@ -175,7 +279,7 @@ public static FirstDerivedOutputModel FirstDerivedOutputModel(bool first = defau /// A new instance for mocking. public static SecondDerivedOutputModel SecondDerivedOutputModel(bool second = default) { - return new SecondDerivedOutputModel("second", second); + return new SecondDerivedOutputModel("second", serializedAdditionalRawData: null, second); } } } diff --git a/test/TestProjects/Models-TypeSpec/src/ModelsTypeSpec.csproj b/test/TestProjects/Models-TypeSpec/src/ModelsTypeSpec.csproj index 11b5807e163..75937dcc8f1 100644 --- a/test/TestProjects/Models-TypeSpec/src/ModelsTypeSpec.csproj +++ b/test/TestProjects/Models-TypeSpec/src/ModelsTypeSpec.csproj @@ -15,5 +15,6 @@ + diff --git a/test/TestProjects/Models-TypeSpec/tspconfig.yaml b/test/TestProjects/Models-TypeSpec/tspconfig.yaml index b74ff790d83..224bace85df 100644 --- a/test/TestProjects/Models-TypeSpec/tspconfig.yaml +++ b/test/TestProjects/Models-TypeSpec/tspconfig.yaml @@ -1,3 +1,4 @@ options: "@azure-tools/typespec-csharp": generate-convenience-methods: false + use-model-reader-writer: true diff --git a/test/TestProjects/TypeSchemaMapping/Customized/CustomizedModel.cs b/test/TestProjects/TypeSchemaMapping/Customized/CustomizedModel.cs index e4660c3ffae..ddd9d9ea486 100644 --- a/test/TestProjects/TypeSchemaMapping/Customized/CustomizedModel.cs +++ b/test/TestProjects/TypeSchemaMapping/Customized/CustomizedModel.cs @@ -1,13 +1,16 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; using NamespaceForEnums; -[assembly:CodeGenSuppressType("ModelToBeSkipped")] -[assembly:CodeGenSuppressType("EnumToBeSkipped")] -[assembly:CodeGenSuppressType("EnumToBeSkippedExtensions")] +[assembly: CodeGenSuppressType("ModelToBeSkipped")] +[assembly: CodeGenSuppressType("EnumToBeSkipped")] +[assembly: CodeGenSuppressType("EnumToBeSkippedExtensions")] namespace CustomNamespace { @@ -24,8 +27,10 @@ internal partial class CustomizedModel: BaseClassForCustomizedModel [CodeGenMember("PropertyToField")] private readonly string _field; - internal static CustomizedModel DeserializeCustomizedModel(JsonElement element) + internal static CustomizedModel DeserializeCustomizedModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + int? propertyRenamedAndTypeChanged = default; CustomFruitEnum fruit = default; CustomDaysOfWeek daysOfWeek = default; @@ -57,7 +62,7 @@ internal static CustomizedModel DeserializeCustomizedModel(JsonElement element) continue; } } - return new CustomizedModel(propertyRenamedAndTypeChanged, field, fruit, daysOfWeek); + return new CustomizedModel(propertyRenamedAndTypeChanged, field, fruit, daysOfWeek, new Dictionary()); } } } diff --git a/test/TestProjects/TypeSchemaMapping/Customized/RenamedThirdModel.cs b/test/TestProjects/TypeSchemaMapping/Customized/RenamedThirdModel.cs index 729fade26ac..476b521cacc 100644 --- a/test/TestProjects/TypeSchemaMapping/Customized/RenamedThirdModel.cs +++ b/test/TestProjects/TypeSchemaMapping/Customized/RenamedThirdModel.cs @@ -11,9 +11,9 @@ namespace CustomNamespace internal partial class RenamedThirdModel { [CodeGenMember("ETag")] - public ETag CustomizedETagProperty { get; } + public ETag CustomizedETagProperty { get; set; } [CodeGenMember("CreatedAt")] - public DateTime CustomizedCreatedAtProperty { get; } + public DateTime CustomizedCreatedAtProperty { get; set; } } } diff --git a/test/TestProjects/TypeSchemaMapping/MainModelFactory.cs b/test/TestProjects/TypeSchemaMapping/MainModelFactory.cs index 1e1e82d7c54..5112edb9c61 100644 --- a/test/TestProjects/TypeSchemaMapping/MainModelFactory.cs +++ b/test/TestProjects/TypeSchemaMapping/MainModelFactory.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; +using System.Collections.Generic; using Azure.Core; namespace TypeSchemaMapping.Models @@ -10,7 +12,7 @@ internal partial class MainModelFactory { public static ModelWithAbstractModel ModelWithAbstractModel(AbstractModel abstractModelProperty = default) { - return new ModelWithAbstractModel(abstractModelProperty); + return new ModelWithAbstractModel(abstractModelProperty, new Dictionary()); } } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Configuration.json b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Configuration.json index 4f8d98361cb..ba9f5c6f6f6 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Configuration.json +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Configuration.json @@ -10,5 +10,6 @@ "skip-csproj": true, "skip-csproj-packagereference": true, "generation1-convenience-client": true, - "project-folder": "../../" + "project-folder": "../../", + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/MainModelFactory.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/MainModelFactory.cs index 92e4dc517ec..7c9c5b35964 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/MainModelFactory.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/MainModelFactory.cs @@ -17,7 +17,7 @@ internal static partial class MainModelFactory /// A new instance for mocking. public static ModelWithGuidProperty ModelWithGuidProperty(Guid? modelProperty = null) { - return new ModelWithGuidProperty(modelProperty); + return new ModelWithGuidProperty(modelProperty, serializedAdditionalRawData: null); } } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/AbstractModel.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/AbstractModel.Serialization.cs index f55db6fe397..b86311432fa 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/AbstractModel.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/AbstractModel.Serialization.cs @@ -5,14 +5,63 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; +using Azure.Core; namespace TypeSchemaMapping.Models { - public partial class AbstractModel + [PersistableModelProxy(typeof(UnknownAbstractModel))] + public partial class AbstractModel : IUtf8JsonSerializable, IJsonModel { - internal static AbstractModel DeserializeAbstractModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AbstractModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("DiscriminatorProperty"u8); + writer.WriteStringValue(DiscriminatorProperty); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + AbstractModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AbstractModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAbstractModel(document.RootElement, options); + } + + internal static AbstractModel DeserializeAbstractModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -26,5 +75,36 @@ internal static AbstractModel DeserializeAbstractModel(JsonElement element) } return UnknownAbstractModel.DeserializeUnknownAbstractModel(element); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(AbstractModel)} does not support '{options.Format}' format."); + } + } + + AbstractModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeAbstractModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AbstractModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/AbstractModel.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/AbstractModel.cs index 88a17e3be42..4337e8ff9c9 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/AbstractModel.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/AbstractModel.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace TypeSchemaMapping.Models { /// @@ -14,6 +17,38 @@ namespace TypeSchemaMapping.Models /// public abstract partial class AbstractModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . protected AbstractModel() { @@ -21,9 +56,11 @@ protected AbstractModel() /// Initializes a new instance of . /// - internal AbstractModel(string discriminatorProperty) + /// Keeps track of any properties unknown to the library. + internal AbstractModel(string discriminatorProperty, IDictionary serializedAdditionalRawData) { DiscriminatorProperty = discriminatorProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the discriminator property. diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/CustomizedModel.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/CustomizedModel.Serialization.cs index 05490994f56..fbbf1f46eea 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/CustomizedModel.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/CustomizedModel.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; using Azure.Core; using NamespaceForEnums; namespace CustomNamespace { - internal partial class CustomizedModel : IUtf8JsonSerializable + internal partial class CustomizedModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(CustomizedModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(PropertyRenamedAndTypeChanged)) { @@ -30,7 +40,65 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteStringValue(CustomizedFancyField.ToSerialString()); writer.WritePropertyName("DaysOfWeek"u8); writer.WriteStringValue(DaysOfWeek.ToString()); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + CustomizedModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(CustomizedModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeCustomizedModel(document.RootElement, options); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(CustomizedModel)} does not support '{options.Format}' format."); + } + } + + CustomizedModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeCustomizedModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(CustomizedModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/CustomizedModel.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/CustomizedModel.cs index 63f15bd8297..89507deeefe 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/CustomizedModel.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/CustomizedModel.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.Collections.Generic; using NamespaceForEnums; namespace CustomNamespace @@ -12,17 +14,56 @@ namespace CustomNamespace /// The Model. internal partial class CustomizedModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// . /// . /// Fruit. /// Day of week. - internal CustomizedModel(int? propertyRenamedAndTypeChanged, string field, CustomFruitEnum customizedFancyField, CustomDaysOfWeek daysOfWeek) + /// Keeps track of any properties unknown to the library. + internal CustomizedModel(int? propertyRenamedAndTypeChanged, string field, CustomFruitEnum customizedFancyField, CustomDaysOfWeek daysOfWeek, IDictionary serializedAdditionalRawData) { PropertyRenamedAndTypeChanged = propertyRenamedAndTypeChanged; _field = field; CustomizedFancyField = customizedFancyField; DaysOfWeek = daysOfWeek; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal CustomizedModel() + { } } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/DerivedFromAbstractModel.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/DerivedFromAbstractModel.Serialization.cs index f4eec76567e..78a5dc2cd73 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/DerivedFromAbstractModel.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/DerivedFromAbstractModel.Serialization.cs @@ -5,19 +5,70 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; +using Azure.Core; namespace TypeSchemaMapping.Models { - public partial class DerivedFromAbstractModel + public partial class DerivedFromAbstractModel : IUtf8JsonSerializable, IJsonModel { - internal static DerivedFromAbstractModel DeserializeDerivedFromAbstractModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DerivedFromAbstractModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("DiscriminatorProperty"u8); + writer.WriteStringValue(DiscriminatorProperty); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + DerivedFromAbstractModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DerivedFromAbstractModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDerivedFromAbstractModel(document.RootElement, options); + } + + internal static DerivedFromAbstractModel DeserializeDerivedFromAbstractModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } string discriminatorProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("DiscriminatorProperty"u8)) @@ -25,8 +76,44 @@ internal static DerivedFromAbstractModel DeserializeDerivedFromAbstractModel(Jso discriminatorProperty = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DerivedFromAbstractModel(discriminatorProperty, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DerivedFromAbstractModel)} does not support '{options.Format}' format."); + } + } + + DerivedFromAbstractModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDerivedFromAbstractModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DerivedFromAbstractModel)} does not support '{options.Format}' format."); } - return new DerivedFromAbstractModel(discriminatorProperty); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/DerivedFromAbstractModel.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/DerivedFromAbstractModel.cs index 21ec58d6f49..f4c348b33b4 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/DerivedFromAbstractModel.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/DerivedFromAbstractModel.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace TypeSchemaMapping.Models { /// The DerivedFromAbstractModel. @@ -18,7 +21,8 @@ internal DerivedFromAbstractModel() /// Initializes a new instance of . /// - internal DerivedFromAbstractModel(string discriminatorProperty) : base(discriminatorProperty) + /// Keeps track of any properties unknown to the library. + internal DerivedFromAbstractModel(string discriminatorProperty, IDictionary serializedAdditionalRawData) : base(discriminatorProperty, serializedAdditionalRawData) { DiscriminatorProperty = discriminatorProperty ?? "DerivedFromAbstractModel"; } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/InternalModel.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/InternalModel.Serialization.cs index 2c415de1137..bdca114eb2a 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/InternalModel.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/InternalModel.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace TypeSchemaMapping.Models { - internal partial class InternalModel + internal partial class InternalModel : IUtf8JsonSerializable, IJsonModel { - internal static InternalModel DeserializeInternalModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(StringProperty)) + { + writer.WritePropertyName("StringProperty"u8); + writer.WriteStringValue(StringProperty); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + InternalModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InternalModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInternalModel(document.RootElement, options); + } + + internal static InternalModel DeserializeInternalModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional stringProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("StringProperty"u8)) @@ -26,8 +79,44 @@ internal static InternalModel DeserializeInternalModel(JsonElement element) stringProperty = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new InternalModel(stringProperty.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new InternalModel(stringProperty.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(InternalModel)} does not support '{options.Format}' format."); + } + } + + InternalModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeInternalModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InternalModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/InternalModel.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/InternalModel.cs index 5ea37081581..558edf72b16 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/InternalModel.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/InternalModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace TypeSchemaMapping.Models { /// The InternalModel. internal partial class InternalModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal InternalModel() { @@ -17,9 +52,11 @@ internal InternalModel() /// Initializes a new instance of . /// - internal InternalModel(string stringProperty) + /// Keeps track of any properties unknown to the library. + internal InternalModel(string stringProperty, IDictionary serializedAdditionalRawData) { StringProperty = stringProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the string property. diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithAbstractModel.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithAbstractModel.Serialization.cs index 69ccf69c07e..d7803e0dc90 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithAbstractModel.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithAbstractModel.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace TypeSchemaMapping.Models { - public partial class ModelWithAbstractModel + public partial class ModelWithAbstractModel : IUtf8JsonSerializable, IJsonModel { - internal static ModelWithAbstractModel DeserializeModelWithAbstractModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithAbstractModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(AbstractModelProperty)) + { + writer.WritePropertyName("AbstractModelProperty"u8); + writer.WriteObjectValue(AbstractModelProperty); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ModelWithAbstractModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithAbstractModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelWithAbstractModel(document.RootElement, options); + } + + internal static ModelWithAbstractModel DeserializeModelWithAbstractModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional abstractModelProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("AbstractModelProperty"u8)) @@ -30,8 +83,44 @@ internal static ModelWithAbstractModel DeserializeModelWithAbstractModel(JsonEle abstractModelProperty = AbstractModel.DeserializeAbstractModel(property.Value); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelWithAbstractModel(abstractModelProperty.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelWithAbstractModel)} does not support '{options.Format}' format."); } - return new ModelWithAbstractModel(abstractModelProperty.Value); } + + ModelWithAbstractModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelWithAbstractModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelWithAbstractModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithAbstractModel.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithAbstractModel.cs index 3a462fd0302..1bcf2ebcb4f 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithAbstractModel.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithAbstractModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace TypeSchemaMapping.Models { /// The ModelWithAbstractModel. public partial class ModelWithAbstractModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ModelWithAbstractModel() { @@ -20,9 +55,11 @@ internal ModelWithAbstractModel() /// Please note is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes. /// The available derived classes include . /// - internal ModelWithAbstractModel(AbstractModel abstractModelProperty) + /// Keeps track of any properties unknown to the library. + internal ModelWithAbstractModel(AbstractModel abstractModelProperty, IDictionary serializedAdditionalRawData) { AbstractModelProperty = abstractModelProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithArrayOfEnum.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithArrayOfEnum.Serialization.cs index 6d86f0c3e16..d02d108cb28 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithArrayOfEnum.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithArrayOfEnum.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace TypeSchemaMapping.Models { - internal partial class ModelWithArrayOfEnum : IUtf8JsonSerializable + internal partial class ModelWithArrayOfEnum : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithArrayOfEnum)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsCollectionDefined(ArrayOfEnum)) { @@ -41,17 +51,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelWithArrayOfEnum DeserializeModelWithArrayOfEnum(JsonElement element) + ModelWithArrayOfEnum IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithArrayOfEnum)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelWithArrayOfEnum(document.RootElement, options); + } + + internal static ModelWithArrayOfEnum DeserializeModelWithArrayOfEnum(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional> arrayOfEnum = default; Optional> arrayOfEnumCustomizedToNullable = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("ArrayOfEnum"u8)) @@ -89,8 +130,44 @@ internal static ModelWithArrayOfEnum DeserializeModelWithArrayOfEnum(JsonElement arrayOfEnumCustomizedToNullable = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ModelWithArrayOfEnum(Optional.ToList(arrayOfEnum), Optional.ToList(arrayOfEnumCustomizedToNullable)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelWithArrayOfEnum(Optional.ToList(arrayOfEnum), Optional.ToList(arrayOfEnumCustomizedToNullable), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelWithArrayOfEnum)} does not support '{options.Format}' format."); + } + } + + ModelWithArrayOfEnum IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelWithArrayOfEnum(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelWithArrayOfEnum)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithArrayOfEnum.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithArrayOfEnum.cs index 77331178b96..d58005ee7d5 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithArrayOfEnum.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithArrayOfEnum.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace TypeSchemaMapping.Models /// The ModelWithArrayOfEnum. internal partial class ModelWithArrayOfEnum { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ModelWithArrayOfEnum() { @@ -23,10 +56,12 @@ public ModelWithArrayOfEnum() /// Initializes a new instance of . /// /// - internal ModelWithArrayOfEnum(IReadOnlyList arrayOfEnum, IReadOnlyList arrayOfEnumCustomizedToNullable) + /// Keeps track of any properties unknown to the library. + internal ModelWithArrayOfEnum(IReadOnlyList arrayOfEnum, IReadOnlyList arrayOfEnumCustomizedToNullable, IDictionary serializedAdditionalRawData) { ArrayOfEnum = arrayOfEnum; ArrayOfEnumCustomizedToNullable = arrayOfEnumCustomizedToNullable; + _serializedAdditionalRawData = serializedAdditionalRawData; } } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomNamespace.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomNamespace.cs index 5a13fdbf725..f8331a00a52 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomNamespace.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomNamespace.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace Very.Custom.Namespace.From.Swagger { /// The ModelWithCustomNamespace. internal partial class ModelWithCustomNamespace { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ModelWithCustomNamespace() { @@ -17,9 +52,11 @@ internal ModelWithCustomNamespace() /// Initializes a new instance of . /// . - internal ModelWithCustomNamespace(string modelProperty) + /// Keeps track of any properties unknown to the library. + internal ModelWithCustomNamespace(string modelProperty, IDictionary serializedAdditionalRawData) { ModelProperty = modelProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// . diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsage.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsage.Serialization.cs index 865d2c35787..18585a17483 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsage.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsage.Serialization.cs @@ -5,6 +5,10 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.IO; using System.Text.Json; using System.Xml; using System.Xml.Linq; @@ -12,9 +16,9 @@ namespace TypeSchemaMapping.Models { - public partial class ModelWithCustomUsage : IUtf8JsonSerializable, IXmlSerializable + public partial class ModelWithCustomUsage : IUtf8JsonSerializable, IJsonModel, IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "ModelWithCustomUsage"); if (Optional.IsDefined(ModelProperty)) @@ -26,34 +30,77 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static ModelWithCustomUsage DeserializeModelWithCustomUsage(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ModelWithCustomUsage DeserializeModelWithCustomUsage(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string modelProperty = default; if (element.Element("ModelProperty") is XElement modelPropertyElement) { modelProperty = (string)modelPropertyElement; } - return new ModelWithCustomUsage(modelProperty); + return new ModelWithCustomUsage(modelProperty, serializedAdditionalRawData: null); } - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithCustomUsage)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(ModelProperty)) { writer.WritePropertyName("ModelProperty"u8); writer.WriteStringValue(ModelProperty); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelWithCustomUsage DeserializeModelWithCustomUsage(JsonElement element) + ModelWithCustomUsage IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithCustomUsage)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelWithCustomUsage(document.RootElement, options); + } + + internal static ModelWithCustomUsage DeserializeModelWithCustomUsage(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional modelProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("ModelProperty"u8)) @@ -61,8 +108,54 @@ internal static ModelWithCustomUsage DeserializeModelWithCustomUsage(JsonElement modelProperty = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelWithCustomUsage(modelProperty.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ModelWithCustomUsage)} does not support '{options.Format}' format."); + } + } + + ModelWithCustomUsage IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelWithCustomUsage(document.RootElement, options); + } + case "X": + return DeserializeModelWithCustomUsage(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ModelWithCustomUsage)} does not support '{options.Format}' format."); } - return new ModelWithCustomUsage(modelProperty.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsage.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsage.cs index 60a4fa28015..97b2fc728ac 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsage.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsage.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace TypeSchemaMapping.Models { /// The ModelWithCustomUsage. public partial class ModelWithCustomUsage { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ModelWithCustomUsage() { @@ -17,9 +52,11 @@ public ModelWithCustomUsage() /// Initializes a new instance of . /// . - internal ModelWithCustomUsage(string modelProperty) + /// Keeps track of any properties unknown to the library. + internal ModelWithCustomUsage(string modelProperty, IDictionary serializedAdditionalRawData) { ModelProperty = modelProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// . diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsageViaAttribute.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsageViaAttribute.Serialization.cs index a8b3580fb05..9decf5af5c0 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsageViaAttribute.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsageViaAttribute.Serialization.cs @@ -5,6 +5,10 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.IO; using System.Text.Json; using System.Xml; using System.Xml.Linq; @@ -12,9 +16,9 @@ namespace TypeSchemaMapping.Models { - public partial class ModelWithCustomUsageViaAttribute : IUtf8JsonSerializable, IXmlSerializable + public partial class ModelWithCustomUsageViaAttribute : IUtf8JsonSerializable, IJsonModel, IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "ModelWithCustomUsageViaAttribute"); if (Optional.IsDefined(ModelProperty)) @@ -26,34 +30,77 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static ModelWithCustomUsageViaAttribute DeserializeModelWithCustomUsageViaAttribute(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ModelWithCustomUsageViaAttribute DeserializeModelWithCustomUsageViaAttribute(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string modelProperty = default; if (element.Element("ModelProperty") is XElement modelPropertyElement) { modelProperty = (string)modelPropertyElement; } - return new ModelWithCustomUsageViaAttribute(modelProperty); + return new ModelWithCustomUsageViaAttribute(modelProperty, serializedAdditionalRawData: null); } - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithCustomUsageViaAttribute)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(ModelProperty)) { writer.WritePropertyName("ModelProperty"u8); writer.WriteStringValue(ModelProperty); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelWithCustomUsageViaAttribute DeserializeModelWithCustomUsageViaAttribute(JsonElement element) + ModelWithCustomUsageViaAttribute IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithCustomUsageViaAttribute)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelWithCustomUsageViaAttribute(document.RootElement, options); + } + + internal static ModelWithCustomUsageViaAttribute DeserializeModelWithCustomUsageViaAttribute(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional modelProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("ModelProperty"u8)) @@ -61,8 +108,54 @@ internal static ModelWithCustomUsageViaAttribute DeserializeModelWithCustomUsage modelProperty = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelWithCustomUsageViaAttribute(modelProperty.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ModelWithCustomUsageViaAttribute)} does not support '{options.Format}' format."); + } + } + + ModelWithCustomUsageViaAttribute IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelWithCustomUsageViaAttribute(document.RootElement, options); + } + case "X": + return DeserializeModelWithCustomUsageViaAttribute(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ModelWithCustomUsageViaAttribute)} does not support '{options.Format}' format."); } - return new ModelWithCustomUsageViaAttribute(modelProperty.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsageViaAttribute.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsageViaAttribute.cs index e0ba1a76b76..d8702d6cafc 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsageViaAttribute.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithCustomUsageViaAttribute.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace TypeSchemaMapping.Models { /// The ModelWithCustomUsageViaAttribute. public partial class ModelWithCustomUsageViaAttribute { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ModelWithCustomUsageViaAttribute() { @@ -17,9 +52,11 @@ public ModelWithCustomUsageViaAttribute() /// Initializes a new instance of . /// . - internal ModelWithCustomUsageViaAttribute(string modelProperty) + /// Keeps track of any properties unknown to the library. + internal ModelWithCustomUsageViaAttribute(string modelProperty, IDictionary serializedAdditionalRawData) { ModelProperty = modelProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// . diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithGuidProperty.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithGuidProperty.Serialization.cs index ef0d5ef1fb8..ed90ed06bb9 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithGuidProperty.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithGuidProperty.Serialization.cs @@ -6,18 +6,20 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace TypeSchemaMapping.Models { - public partial class ModelWithGuidProperty : IXmlSerializable + public partial class ModelWithGuidProperty : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "ModelWithGuidProperty"); - if (Optional.IsDefined(ModelProperty)) + if (options.Format != "W" && Optional.IsDefined(ModelProperty)) { writer.WriteStartElement("ModelProperty"); writer.WriteValue(ModelProperty.Value); @@ -26,14 +28,52 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static ModelWithGuidProperty DeserializeModelWithGuidProperty(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ModelWithGuidProperty DeserializeModelWithGuidProperty(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + Guid? modelProperty = default; if (element.Element("ModelProperty") is XElement modelPropertyElement) { modelProperty = new Guid(modelPropertyElement.Value); } - return new ModelWithGuidProperty(modelProperty); + return new ModelWithGuidProperty(modelProperty, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ModelWithGuidProperty)} does not support '{options.Format}' format."); + } } + + ModelWithGuidProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeModelWithGuidProperty(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ModelWithGuidProperty)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithGuidProperty.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithGuidProperty.cs index 4ffb591392e..43ffd59e48b 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithGuidProperty.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithGuidProperty.cs @@ -6,12 +6,45 @@ #nullable disable using System; +using System.Collections.Generic; namespace TypeSchemaMapping.Models { /// The ModelWithGuidProperty. public partial class ModelWithGuidProperty { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ModelWithGuidProperty() { @@ -19,9 +52,11 @@ public ModelWithGuidProperty() /// Initializes a new instance of . /// . - internal ModelWithGuidProperty(Guid? modelProperty) + /// Keeps track of any properties unknown to the library. + internal ModelWithGuidProperty(Guid? modelProperty, IDictionary serializedAdditionalRawData) { ModelProperty = modelProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// . diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithInternalModel.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithInternalModel.Serialization.cs index c0990fe8cee..16e603d5597 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithInternalModel.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithInternalModel.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace TypeSchemaMapping.Models { - public partial class ModelWithInternalModel + public partial class ModelWithInternalModel : IUtf8JsonSerializable, IJsonModel { - internal static ModelWithInternalModel DeserializeModelWithInternalModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithInternalModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(InternalProperty)) + { + writer.WritePropertyName("InternalProperty"u8); + writer.WriteObjectValue(InternalProperty); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ModelWithInternalModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithInternalModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelWithInternalModel(document.RootElement, options); + } + + internal static ModelWithInternalModel DeserializeModelWithInternalModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional internalProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("InternalProperty"u8)) @@ -30,8 +83,44 @@ internal static ModelWithInternalModel DeserializeModelWithInternalModel(JsonEle internalProperty = InternalModel.DeserializeInternalModel(property.Value); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelWithInternalModel(internalProperty.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelWithInternalModel)} does not support '{options.Format}' format."); } - return new ModelWithInternalModel(internalProperty.Value); } + + ModelWithInternalModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelWithInternalModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelWithInternalModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithInternalModel.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithInternalModel.cs index e7933f316ac..fb2fe984c8c 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithInternalModel.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithInternalModel.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace TypeSchemaMapping.Models { /// The ModelWithInternalModel. public partial class ModelWithInternalModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ModelWithInternalModel() { @@ -17,9 +52,11 @@ internal ModelWithInternalModel() /// Initializes a new instance of . /// - internal ModelWithInternalModel(InternalModel internalProperty) + /// Keeps track of any properties unknown to the library. + internal ModelWithInternalModel(InternalModel internalProperty, IDictionary serializedAdditionalRawData) { InternalProperty = internalProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithListOfInternalModel.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithListOfInternalModel.Serialization.cs index a089b743fa4..1e6009a6e57 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithListOfInternalModel.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithListOfInternalModel.Serialization.cs @@ -5,22 +5,84 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace TypeSchemaMapping.Models { - public partial class ModelWithListOfInternalModel + public partial class ModelWithListOfInternalModel : IUtf8JsonSerializable, IJsonModel { - internal static ModelWithListOfInternalModel DeserializeModelWithListOfInternalModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithListOfInternalModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (options.Format != "W" && Optional.IsDefined(StringProperty)) + { + writer.WritePropertyName("StringProperty"u8); + writer.WriteStringValue(StringProperty); + } + if (options.Format != "W" && Optional.IsCollectionDefined(InternalListProperty)) + { + writer.WritePropertyName("InternalListProperty"u8); + writer.WriteStartArray(); + foreach (var item in InternalListProperty) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ModelWithListOfInternalModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithListOfInternalModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelWithListOfInternalModel(document.RootElement, options); + } + + internal static ModelWithListOfInternalModel DeserializeModelWithListOfInternalModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional stringProperty = default; Optional> internalListProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("StringProperty"u8)) @@ -42,8 +104,44 @@ internal static ModelWithListOfInternalModel DeserializeModelWithListOfInternalM internalListProperty = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ModelWithListOfInternalModel(stringProperty.Value, Optional.ToList(internalListProperty)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelWithListOfInternalModel(stringProperty.Value, Optional.ToList(internalListProperty), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelWithListOfInternalModel)} does not support '{options.Format}' format."); + } + } + + ModelWithListOfInternalModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelWithListOfInternalModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelWithListOfInternalModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithListOfInternalModel.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithListOfInternalModel.cs index 703fa485b43..330fd8cff63 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithListOfInternalModel.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithListOfInternalModel.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace TypeSchemaMapping.Models /// The ModelWithListOfInternalModel. public partial class ModelWithListOfInternalModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ModelWithListOfInternalModel() { @@ -22,10 +55,12 @@ internal ModelWithListOfInternalModel() /// Initializes a new instance of . /// /// - internal ModelWithListOfInternalModel(string stringProperty, IReadOnlyList internalListProperty) + /// Keeps track of any properties unknown to the library. + internal ModelWithListOfInternalModel(string stringProperty, IReadOnlyList internalListProperty, IDictionary serializedAdditionalRawData) { StringProperty = stringProperty; InternalListProperty = internalListProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the string property. diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithNullableObjectProperty.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithNullableObjectProperty.Serialization.cs index 089e8cf844a..b1c4fa11714 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithNullableObjectProperty.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithNullableObjectProperty.Serialization.cs @@ -5,31 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace TypeSchemaMapping.Models { - internal partial class ModelWithNullableObjectProperty : IUtf8JsonSerializable + internal partial class ModelWithNullableObjectProperty : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithNullableObjectProperty)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(ModelProperty)) { writer.WritePropertyName("ModelProperty"u8); ModelProperty.WriteTo(writer); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelWithNullableObjectProperty DeserializeModelWithNullableObjectProperty(JsonElement element) + ModelWithNullableObjectProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithNullableObjectProperty)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelWithNullableObjectProperty(document.RootElement, options); + } + + internal static ModelWithNullableObjectProperty DeserializeModelWithNullableObjectProperty(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional modelProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("ModelProperty"u8)) @@ -37,8 +79,44 @@ internal static ModelWithNullableObjectProperty DeserializeModelWithNullableObje modelProperty = property.Value.Clone(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelWithNullableObjectProperty(modelProperty, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelWithNullableObjectProperty)} does not support '{options.Format}' format."); } - return new ModelWithNullableObjectProperty(modelProperty); } + + ModelWithNullableObjectProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelWithNullableObjectProperty(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelWithNullableObjectProperty)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithNullableObjectProperty.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithNullableObjectProperty.cs index 1c93b0a3d5c..970d53e8c95 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithNullableObjectProperty.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithNullableObjectProperty.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.Collections.Generic; using System.Text.Json; namespace TypeSchemaMapping.Models @@ -12,6 +14,38 @@ namespace TypeSchemaMapping.Models /// The ModelWithNullableObjectProperty. internal partial class ModelWithNullableObjectProperty { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ModelWithNullableObjectProperty() { @@ -19,9 +53,11 @@ public ModelWithNullableObjectProperty() /// Initializes a new instance of . /// . - internal ModelWithNullableObjectProperty(JsonElement modelProperty) + /// Keeps track of any properties unknown to the library. + internal ModelWithNullableObjectProperty(JsonElement modelProperty, IDictionary serializedAdditionalRawData) { ModelProperty = modelProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithUriProperty.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithUriProperty.Serialization.cs index fbaea29f3e8..4b39faf4245 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithUriProperty.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithUriProperty.Serialization.cs @@ -6,31 +6,72 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace TypeSchemaMapping.Models { - public partial class ModelWithUriProperty : IUtf8JsonSerializable + public partial class ModelWithUriProperty : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithUriProperty)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Uri)) { writer.WritePropertyName("Uri"u8); writer.WriteStringValue(Uri.AbsoluteUri); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ModelWithUriProperty DeserializeModelWithUriProperty(JsonElement element) + ModelWithUriProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ModelWithUriProperty)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeModelWithUriProperty(document.RootElement, options); + } + + internal static ModelWithUriProperty DeserializeModelWithUriProperty(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional uri = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("Uri"u8)) @@ -42,8 +83,44 @@ internal static ModelWithUriProperty DeserializeModelWithUriProperty(JsonElement uri = new Uri(property.Value.GetString()); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ModelWithUriProperty(uri.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ModelWithUriProperty(uri.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ModelWithUriProperty)} does not support '{options.Format}' format."); + } + } + + ModelWithUriProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeModelWithUriProperty(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ModelWithUriProperty)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithUriProperty.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithUriProperty.cs index c9708cd8c7c..c9f782a4e12 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithUriProperty.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/ModelWithUriProperty.cs @@ -6,12 +6,45 @@ #nullable disable using System; +using System.Collections.Generic; namespace TypeSchemaMapping.Models { /// The ModelWithUriProperty. public partial class ModelWithUriProperty { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ModelWithUriProperty() { @@ -19,9 +52,11 @@ public ModelWithUriProperty() /// Initializes a new instance of . /// . - internal ModelWithUriProperty(Uri uri) + /// Keeps track of any properties unknown to the library. + internal ModelWithUriProperty(Uri uri, IDictionary serializedAdditionalRawData) { Uri = uri; + _serializedAdditionalRawData = serializedAdditionalRawData; } } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/PublicModelWithInternalProperty.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/PublicModelWithInternalProperty.Serialization.cs index 771fd7bf445..2eedbc7eef6 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/PublicModelWithInternalProperty.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/PublicModelWithInternalProperty.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace TypeSchemaMapping.Models { - public partial class PublicModelWithInternalProperty + public partial class PublicModelWithInternalProperty : IUtf8JsonSerializable, IJsonModel { - internal static PublicModelWithInternalProperty DeserializePublicModelWithInternalProperty(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PublicModelWithInternalProperty)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(StringPropertyJson)) + { + writer.WritePropertyName("InternalProperty"u8); + StringPropertyJson.WriteTo(writer); + } + if (Optional.IsDefined(PublicProperty)) + { + writer.WritePropertyName("PublicProperty"u8); + writer.WriteStringValue(PublicProperty); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + PublicModelWithInternalProperty IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PublicModelWithInternalProperty)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePublicModelWithInternalProperty(document.RootElement, options); + } + + internal static PublicModelWithInternalProperty DeserializePublicModelWithInternalProperty(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional internalProperty = default; Optional publicProperty = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("InternalProperty"u8)) @@ -32,8 +90,44 @@ internal static PublicModelWithInternalProperty DeserializePublicModelWithIntern publicProperty = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new PublicModelWithInternalProperty(internalProperty, publicProperty.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PublicModelWithInternalProperty)} does not support '{options.Format}' format."); } - return new PublicModelWithInternalProperty(internalProperty, publicProperty.Value); } + + PublicModelWithInternalProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePublicModelWithInternalProperty(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PublicModelWithInternalProperty)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/PublicModelWithInternalProperty.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/PublicModelWithInternalProperty.cs index 4f1e0646aa0..71146fb8933 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/PublicModelWithInternalProperty.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/PublicModelWithInternalProperty.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.Collections.Generic; using System.Text.Json; namespace TypeSchemaMapping.Models @@ -12,6 +14,38 @@ namespace TypeSchemaMapping.Models /// The PublicModelWithInternalProperty. public partial class PublicModelWithInternalProperty { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal PublicModelWithInternalProperty() { @@ -20,10 +54,12 @@ internal PublicModelWithInternalProperty() /// Initializes a new instance of . /// /// - internal PublicModelWithInternalProperty(JsonElement stringPropertyJson, string publicProperty) + /// Keeps track of any properties unknown to the library. + internal PublicModelWithInternalProperty(JsonElement stringPropertyJson, string publicProperty, IDictionary serializedAdditionalRawData) { StringPropertyJson = stringPropertyJson; PublicProperty = publicProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the public property. public string PublicProperty { get; } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedModelStruct.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedModelStruct.Serialization.cs index 048042fc1ee..080c2c0b959 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedModelStruct.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedModelStruct.Serialization.cs @@ -5,16 +5,27 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; using NamespaceForEnums; namespace CustomNamespace { - internal partial struct RenamedModelStruct : IUtf8JsonSerializable + internal partial struct RenamedModelStruct : IUtf8JsonSerializable, IJsonModel, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RenamedModelStruct)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("ModelProperty"u8); writer.WriteStartObject(); @@ -39,15 +50,50 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteStringValue(DaysOfWeek.Value.ToString()); } writer.WriteEndObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RenamedModelStruct DeserializeRenamedModelStruct(JsonElement element) + RenamedModelStruct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RenamedModelStruct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRenamedModelStruct(document.RootElement, options); + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => ((IJsonModel)this).Write(writer, options); + + object IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => ((IJsonModel)this).Create(ref reader, options); + + internal static RenamedModelStruct DeserializeRenamedModelStruct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + Optional modelProperty = default; Optional propertyToField = default; Optional fruit = default; Optional daysOfWeek = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("ModelProperty"u8)) @@ -90,8 +136,50 @@ internal static RenamedModelStruct DeserializeRenamedModelStruct(JsonElement ele } continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RenamedModelStruct(modelProperty.Value, propertyToField.Value, Optional.ToNullable(fruit), Optional.ToNullable(daysOfWeek), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RenamedModelStruct)} does not support '{options.Format}' format."); } - return new RenamedModelStruct(modelProperty.Value, propertyToField.Value, Optional.ToNullable(fruit), Optional.ToNullable(daysOfWeek)); } + + RenamedModelStruct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRenamedModelStruct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RenamedModelStruct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => ((IPersistableModel)this).Write(options); + + object IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => ((IPersistableModel)this).Create(data, options); + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => ((IPersistableModel)this).GetFormatFromOptions(options); } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedModelStruct.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedModelStruct.cs index 73ad69236bb..56e6e7315a7 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedModelStruct.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedModelStruct.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; using NamespaceForEnums; @@ -14,6 +15,38 @@ namespace CustomNamespace /// The ModelStruct. internal readonly partial struct RenamedModelStruct { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private readonly IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// . /// . @@ -30,6 +63,26 @@ public RenamedModelStruct(string customizedFlattenedStringProperty, string prope Fruit = fruit; DaysOfWeek = daysOfWeek; } + + /// Initializes a new instance of . + /// . + /// . + /// Fruit. + /// Day of week. + /// Keeps track of any properties unknown to the library. + internal RenamedModelStruct(string customizedFlattenedStringProperty, string propertyToField, CustomFruitEnum? fruit, CustomDaysOfWeek? daysOfWeek, IDictionary serializedAdditionalRawData) + { + CustomizedFlattenedStringProperty = customizedFlattenedStringProperty; + PropertyToField = propertyToField; + Fruit = fruit; + DaysOfWeek = daysOfWeek; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + public RenamedModelStruct() + { + } /// . public string PropertyToField { get; } /// Fruit. diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedThirdModel.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedThirdModel.Serialization.cs index 0e3ee9b3cfc..5e5cbdc269d 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedThirdModel.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedThirdModel.Serialization.cs @@ -6,16 +6,26 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure; using Azure.Core; namespace CustomNamespace { - internal partial class RenamedThirdModel : IUtf8JsonSerializable + internal partial class RenamedThirdModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RenamedThirdModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(CustomizedETagProperty)) { @@ -27,17 +37,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("CreatedAt"u8); writer.WriteStringValue(CustomizedCreatedAtProperty); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RenamedThirdModel DeserializeRenamedThirdModel(JsonElement element) + RenamedThirdModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RenamedThirdModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRenamedThirdModel(document.RootElement, options); + } + + internal static RenamedThirdModel DeserializeRenamedThirdModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional eTag = default; Optional createdAt = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("ETag"u8)) @@ -58,8 +99,44 @@ internal static RenamedThirdModel DeserializeRenamedThirdModel(JsonElement eleme createdAt = property.Value.GetDateTime(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new RenamedThirdModel(eTag, createdAt); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RenamedThirdModel(eTag, createdAt, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RenamedThirdModel)} does not support '{options.Format}' format."); + } + } + + RenamedThirdModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRenamedThirdModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RenamedThirdModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedThirdModel.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedThirdModel.cs index 38b77dacfe6..5191f10fa56 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedThirdModel.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/RenamedThirdModel.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure; namespace CustomNamespace @@ -13,6 +14,38 @@ namespace CustomNamespace /// The ThirdModel. internal partial class RenamedThirdModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public RenamedThirdModel() { @@ -21,10 +54,12 @@ public RenamedThirdModel() /// Initializes a new instance of . /// ETag property. /// Creation date. - internal RenamedThirdModel(ETag customizedETagProperty, DateTime customizedCreatedAtProperty) + /// Keeps track of any properties unknown to the library. + internal RenamedThirdModel(ETag customizedETagProperty, DateTime customizedCreatedAtProperty, IDictionary serializedAdditionalRawData) { CustomizedETagProperty = customizedETagProperty; CustomizedCreatedAtProperty = customizedCreatedAtProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/SecondModel.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/SecondModel.Serialization.cs index 83060d69fcc..04789b95964 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/SecondModel.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/SecondModel.Serialization.cs @@ -5,6 +5,8 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; @@ -12,10 +14,18 @@ namespace TypeSchemaMapping.Models { - internal partial class SecondModel : IUtf8JsonSerializable + internal partial class SecondModel : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SecondModel)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(IntProperty)) { @@ -38,11 +48,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("DaysOfWeek"u8); writer.WriteStringValue(DaysOfWeek.Value.ToString()); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static SecondModel DeserializeSecondModel(JsonElement element) + SecondModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SecondModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSecondModel(document.RootElement, options); + } + + internal static SecondModel DeserializeSecondModel(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -50,6 +89,8 @@ internal static SecondModel DeserializeSecondModel(JsonElement element) Optional stringProperty = default; Optional> dictionaryProperty = default; Optional daysOfWeek = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("StringProperty"u8)) @@ -84,8 +125,44 @@ internal static SecondModel DeserializeSecondModel(JsonElement element) daysOfWeek = new CustomDaysOfWeek(property.Value.GetString()); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new SecondModel(stringProperty, Optional.ToDictionary(dictionaryProperty), Optional.ToNullable(daysOfWeek)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new SecondModel(stringProperty, Optional.ToDictionary(dictionaryProperty), Optional.ToNullable(daysOfWeek), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(SecondModel)} does not support '{options.Format}' format."); + } + } + + SecondModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSecondModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SecondModel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/SecondModel.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/SecondModel.cs index 26a760071d0..ace5a5ed61c 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/SecondModel.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/SecondModel.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; using NamespaceForEnums; @@ -14,6 +15,38 @@ namespace TypeSchemaMapping.Models /// The SecondModel. internal partial class SecondModel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public SecondModel() { @@ -24,11 +57,13 @@ public SecondModel() /// . /// . /// Day of week. - internal SecondModel(int intProperty, IReadOnlyDictionary dictionaryProperty, CustomDaysOfWeek? daysOfWeek) + /// Keeps track of any properties unknown to the library. + internal SecondModel(int intProperty, IReadOnlyDictionary dictionaryProperty, CustomDaysOfWeek? daysOfWeek, IDictionary serializedAdditionalRawData) { IntProperty = intProperty; DictionaryProperty = dictionaryProperty; DaysOfWeek = daysOfWeek; + _serializedAdditionalRawData = serializedAdditionalRawData; } } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/UnknownAbstractModel.Serialization.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/UnknownAbstractModel.Serialization.cs index ac1d9491f22..ebea4fccd41 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/UnknownAbstractModel.Serialization.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/UnknownAbstractModel.Serialization.cs @@ -5,19 +5,70 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; +using Azure.Core; namespace TypeSchemaMapping.Models { - internal partial class UnknownAbstractModel + internal partial class UnknownAbstractModel : IUtf8JsonSerializable, IJsonModel { - internal static UnknownAbstractModel DeserializeUnknownAbstractModel(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AbstractModel)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("DiscriminatorProperty"u8); + writer.WriteStringValue(DiscriminatorProperty); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + AbstractModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AbstractModel)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownAbstractModel(document.RootElement, options); + } + + internal static UnknownAbstractModel DeserializeUnknownAbstractModel(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } string discriminatorProperty = "Unknown"; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("DiscriminatorProperty"u8)) @@ -25,8 +76,44 @@ internal static UnknownAbstractModel DeserializeUnknownAbstractModel(JsonElement discriminatorProperty = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new UnknownAbstractModel(discriminatorProperty, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(AbstractModel)} does not support '{options.Format}' format."); + } + } + + AbstractModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownAbstractModel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AbstractModel)} does not support '{options.Format}' format."); } - return new UnknownAbstractModel(discriminatorProperty); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/UnknownAbstractModel.cs b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/UnknownAbstractModel.cs index c418d739779..1d614d2ad52 100644 --- a/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/UnknownAbstractModel.cs +++ b/test/TestProjects/TypeSchemaMapping/SomeFolder/Generated/Models/UnknownAbstractModel.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace TypeSchemaMapping.Models { /// The UnknownAbstractModel. @@ -12,7 +15,8 @@ internal partial class UnknownAbstractModel : AbstractModel { /// Initializes a new instance of . /// - internal UnknownAbstractModel(string discriminatorProperty) : base(discriminatorProperty) + /// Keeps track of any properties unknown to the library. + internal UnknownAbstractModel(string discriminatorProperty, IDictionary serializedAdditionalRawData) : base(discriminatorProperty, serializedAdditionalRawData) { DiscriminatorProperty = discriminatorProperty ?? "Unknown"; } diff --git a/test/TestProjects/TypeSchemaMapping/TypeSchemaMapping.csproj b/test/TestProjects/TypeSchemaMapping/TypeSchemaMapping.csproj index c12e132bf90..8f40e0c7f23 100644 --- a/test/TestProjects/TypeSchemaMapping/TypeSchemaMapping.csproj +++ b/test/TestProjects/TypeSchemaMapping/TypeSchemaMapping.csproj @@ -8,6 +8,7 @@ + diff --git a/test/TestProjects/TypeSchemaMapping/readme.md b/test/TestProjects/TypeSchemaMapping/readme.md index cba43181afb..c4a87a9fd77 100644 --- a/test/TestProjects/TypeSchemaMapping/readme.md +++ b/test/TestProjects/TypeSchemaMapping/readme.md @@ -13,4 +13,6 @@ output-folder: $(this-folder)/SomeFolder/Generated skip-csproj: true # relative path to output-folder also works project-folder: ../../ + +use-model-reader-writer: true ``` diff --git a/test/TestServerProjects/additionalProperties/Generated/AdditionalPropertiesModelFactory.cs b/test/TestServerProjects/additionalProperties/Generated/AdditionalPropertiesModelFactory.cs index e26a7edf138..5867b84bfd7 100644 --- a/test/TestServerProjects/additionalProperties/Generated/AdditionalPropertiesModelFactory.cs +++ b/test/TestServerProjects/additionalProperties/Generated/AdditionalPropertiesModelFactory.cs @@ -75,7 +75,7 @@ public static PetAPInProperties PetAPInProperties(int id = default, string name { additionalProperties ??= new Dictionary(); - return new PetAPInProperties(id, name, status, additionalProperties); + return new PetAPInProperties(id, name, status, additionalProperties, serializedAdditionalRawData: null); } } } diff --git a/test/TestServerProjects/additionalProperties/Generated/Configuration.json b/test/TestServerProjects/additionalProperties/Generated/Configuration.json index d4ee8abcdad..016bff335e3 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Configuration.json +++ b/test/TestServerProjects/additionalProperties/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/CatAPTrue.Serialization.cs b/test/TestServerProjects/additionalProperties/Generated/Models/CatAPTrue.Serialization.cs index 908dfbf24fd..737bc87df9c 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/CatAPTrue.Serialization.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/CatAPTrue.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace additionalProperties.Models { - public partial class CatAPTrue : IUtf8JsonSerializable + public partial class CatAPTrue : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(CatAPTrue)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Friendly)) { @@ -28,6 +38,11 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteBooleanValue(Status.Value); + } foreach (var item in AdditionalProperties) { writer.WritePropertyName(item.Key); @@ -36,8 +51,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static CatAPTrue DeserializeCatAPTrue(JsonElement element) + CatAPTrue IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(CatAPTrue)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeCatAPTrue(document.RootElement, options); + } + + internal static CatAPTrue DeserializeCatAPTrue(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -83,5 +112,36 @@ internal static CatAPTrue DeserializeCatAPTrue(JsonElement element) additionalProperties = additionalPropertiesDictionary; return new CatAPTrue(id, name.Value, Optional.ToNullable(status), additionalProperties, Optional.ToNullable(friendly)); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(CatAPTrue)} does not support '{options.Format}' format."); + } + } + + CatAPTrue IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeCatAPTrue(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(CatAPTrue)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/CatAPTrue.cs b/test/TestServerProjects/additionalProperties/Generated/Models/CatAPTrue.cs index 7086ba15de5..c16758168af 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/CatAPTrue.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/CatAPTrue.cs @@ -29,6 +29,11 @@ internal CatAPTrue(int id, string name, bool? status, IDictionary Initializes a new instance of for deserialization. + internal CatAPTrue() + { + } + /// Gets or sets the friendly. public bool? Friendly { get; set; } } diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/additionalProperties/Generated/Models/Error.Serialization.cs index 3db94c67453..1c18740eeed 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace additionalProperties.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/Error.cs b/test/TestServerProjects/additionalProperties/Generated/Models/Error.cs index baae97235d2..203ef8a1c8a 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/Error.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace additionalProperties.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInProperties.Serialization.cs b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInProperties.Serialization.cs index 8552d3421ca..0ce03344b06 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInProperties.Serialization.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInProperties.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace additionalProperties.Models { - public partial class PetAPInProperties : IUtf8JsonSerializable + public partial class PetAPInProperties : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAPInProperties)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id); @@ -23,6 +33,11 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteBooleanValue(Status.Value); + } if (Optional.IsCollectionDefined(AdditionalProperties)) { writer.WritePropertyName("additionalProperties"u8); @@ -34,11 +49,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndObject(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static PetAPInProperties DeserializePetAPInProperties(JsonElement element) + PetAPInProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAPInProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePetAPInProperties(document.RootElement, options); + } + + internal static PetAPInProperties DeserializePetAPInProperties(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -47,6 +91,8 @@ internal static PetAPInProperties DeserializePetAPInProperties(JsonElement eleme Optional name = default; Optional status = default; Optional> additionalProperties = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -82,8 +128,44 @@ internal static PetAPInProperties DeserializePetAPInProperties(JsonElement eleme additionalProperties = dictionary; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new PetAPInProperties(id, name.Value, Optional.ToNullable(status), Optional.ToDictionary(additionalProperties), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PetAPInProperties)} does not support '{options.Format}' format."); } - return new PetAPInProperties(id, name.Value, Optional.ToNullable(status), Optional.ToDictionary(additionalProperties)); } + + PetAPInProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePetAPInProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PetAPInProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInProperties.cs b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInProperties.cs index 11620dc0f20..301deabf667 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInProperties.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInProperties.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace additionalProperties.Models /// The PetAPInProperties. public partial class PetAPInProperties { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// public PetAPInProperties(int id) @@ -26,12 +59,19 @@ public PetAPInProperties(int id) /// /// /// Dictionary of <number>. - internal PetAPInProperties(int id, string name, bool? status, IDictionary additionalProperties) + /// Keeps track of any properties unknown to the library. + internal PetAPInProperties(int id, string name, bool? status, IDictionary additionalProperties, IDictionary serializedAdditionalRawData) { Id = id; Name = name; Status = status; AdditionalProperties = additionalProperties; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal PetAPInProperties() + { } /// Gets or sets the id. diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInPropertiesWithAPString.Serialization.cs b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInPropertiesWithAPString.Serialization.cs index b8ade9f7426..6819d57ab03 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInPropertiesWithAPString.Serialization.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInPropertiesWithAPString.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace additionalProperties.Models { - public partial class PetAPInPropertiesWithAPString : IUtf8JsonSerializable + public partial class PetAPInPropertiesWithAPString : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAPInPropertiesWithAPString)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id); @@ -23,6 +33,11 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteBooleanValue(Status.Value); + } writer.WritePropertyName("@odata.location"u8); writer.WriteStringValue(OdataLocation); if (Optional.IsCollectionDefined(AdditionalProperties)) @@ -44,8 +59,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static PetAPInPropertiesWithAPString DeserializePetAPInPropertiesWithAPString(JsonElement element) + PetAPInPropertiesWithAPString IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAPInPropertiesWithAPString)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePetAPInPropertiesWithAPString(document.RootElement, options); + } + + internal static PetAPInPropertiesWithAPString DeserializePetAPInPropertiesWithAPString(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -102,5 +131,36 @@ internal static PetAPInPropertiesWithAPString DeserializePetAPInPropertiesWithAP moreAdditionalProperties = additionalPropertiesDictionary; return new PetAPInPropertiesWithAPString(id, name.Value, Optional.ToNullable(status), odataLocation, Optional.ToDictionary(additionalProperties), moreAdditionalProperties); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PetAPInPropertiesWithAPString)} does not support '{options.Format}' format."); + } + } + + PetAPInPropertiesWithAPString IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePetAPInPropertiesWithAPString(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PetAPInPropertiesWithAPString)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInPropertiesWithAPString.cs b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInPropertiesWithAPString.cs index 1d760be349d..83f9c421fea 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInPropertiesWithAPString.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPInPropertiesWithAPString.cs @@ -45,6 +45,11 @@ internal PetAPInPropertiesWithAPString(int id, string name, bool? status, string MoreAdditionalProperties = moreAdditionalProperties; } + /// Initializes a new instance of for deserialization. + internal PetAPInPropertiesWithAPString() + { + } + /// Gets or sets the id. public int Id { get; set; } /// Gets or sets the name. diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPObject.Serialization.cs b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPObject.Serialization.cs index e0985862194..69e9908c3ea 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPObject.Serialization.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPObject.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace additionalProperties.Models { - public partial class PetAPObject : IUtf8JsonSerializable + public partial class PetAPObject : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAPObject)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id); @@ -23,6 +33,11 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteBooleanValue(Status.Value); + } foreach (var item in AdditionalProperties) { writer.WritePropertyName(item.Key); @@ -31,8 +46,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static PetAPObject DeserializePetAPObject(JsonElement element) + PetAPObject IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAPObject)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePetAPObject(document.RootElement, options); + } + + internal static PetAPObject DeserializePetAPObject(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -68,5 +97,36 @@ internal static PetAPObject DeserializePetAPObject(JsonElement element) additionalProperties = additionalPropertiesDictionary; return new PetAPObject(id, name.Value, Optional.ToNullable(status), additionalProperties); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PetAPObject)} does not support '{options.Format}' format."); + } + } + + PetAPObject IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePetAPObject(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PetAPObject)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPObject.cs b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPObject.cs index f841ae8ec19..c10c95093d1 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPObject.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPObject.cs @@ -34,6 +34,11 @@ internal PetAPObject(int id, string name, bool? status, IDictionary Initializes a new instance of for deserialization. + internal PetAPObject() + { + } + /// Gets or sets the id. public int Id { get; set; } /// Gets or sets the name. diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPString.Serialization.cs b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPString.Serialization.cs index 1fcf3c52581..a8807e8e2b7 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPString.Serialization.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPString.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace additionalProperties.Models { - public partial class PetAPString : IUtf8JsonSerializable + public partial class PetAPString : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAPString)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id); @@ -23,6 +33,11 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteBooleanValue(Status.Value); + } foreach (var item in AdditionalProperties) { writer.WritePropertyName(item.Key); @@ -31,8 +46,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static PetAPString DeserializePetAPString(JsonElement element) + PetAPString IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAPString)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePetAPString(document.RootElement, options); + } + + internal static PetAPString DeserializePetAPString(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -68,5 +97,36 @@ internal static PetAPString DeserializePetAPString(JsonElement element) additionalProperties = additionalPropertiesDictionary; return new PetAPString(id, name.Value, Optional.ToNullable(status), additionalProperties); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PetAPString)} does not support '{options.Format}' format."); + } + } + + PetAPString IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePetAPString(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PetAPString)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPString.cs b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPString.cs index 688fecea5a1..790df2dec26 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPString.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPString.cs @@ -34,6 +34,11 @@ internal PetAPString(int id, string name, bool? status, IDictionary Initializes a new instance of for deserialization. + internal PetAPString() + { + } + /// Gets or sets the id. public int Id { get; set; } /// Gets or sets the name. diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPTrue.Serialization.cs b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPTrue.Serialization.cs index 4bad4933692..7c325da7d61 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPTrue.Serialization.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPTrue.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace additionalProperties.Models { - public partial class PetAPTrue : IUtf8JsonSerializable + public partial class PetAPTrue : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAPTrue)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id); @@ -23,6 +33,11 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteBooleanValue(Status.Value); + } foreach (var item in AdditionalProperties) { writer.WritePropertyName(item.Key); @@ -31,8 +46,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static PetAPTrue DeserializePetAPTrue(JsonElement element) + PetAPTrue IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAPTrue)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePetAPTrue(document.RootElement, options); + } + + internal static PetAPTrue DeserializePetAPTrue(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -68,5 +97,36 @@ internal static PetAPTrue DeserializePetAPTrue(JsonElement element) additionalProperties = additionalPropertiesDictionary; return new PetAPTrue(id, name.Value, Optional.ToNullable(status), additionalProperties); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PetAPTrue)} does not support '{options.Format}' format."); + } + } + + PetAPTrue IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePetAPTrue(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PetAPTrue)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPTrue.cs b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPTrue.cs index 5d6415fad4b..eacd15b8941 100644 --- a/test/TestServerProjects/additionalProperties/Generated/Models/PetAPTrue.cs +++ b/test/TestServerProjects/additionalProperties/Generated/Models/PetAPTrue.cs @@ -34,6 +34,11 @@ internal PetAPTrue(int id, string name, bool? status, IDictionary Initializes a new instance of for deserialization. + internal PetAPTrue() + { + } + /// Gets or sets the id. public int Id { get; set; } /// Gets or sets the name. diff --git a/test/TestServerProjects/additionalProperties/additionalProperties.csproj b/test/TestServerProjects/additionalProperties/additionalProperties.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/additionalProperties/additionalProperties.csproj +++ b/test/TestServerProjects/additionalProperties/additionalProperties.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/azure-parameter-grouping/Generated/AzureParameterGroupingModelFactory.cs b/test/TestServerProjects/azure-parameter-grouping/Generated/AzureParameterGroupingModelFactory.cs new file mode 100644 index 00000000000..d3e3644bd67 --- /dev/null +++ b/test/TestServerProjects/azure-parameter-grouping/Generated/AzureParameterGroupingModelFactory.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace azure_parameter_grouping.Models +{ + /// Model factory for models. + public static partial class AzureParameterGroupingModelFactory + { + /// Initializes a new instance of . + /// + /// Query parameter with default. + /// Path parameter. + /// + /// A new instance for mocking. + public static ParameterGroupingPostRequiredParameters ParameterGroupingPostRequiredParameters(string customHeader = null, int? query = null, string path = null, int body = default) + { + return new ParameterGroupingPostRequiredParameters(customHeader, query, path, body, serializedAdditionalRawData: null); + } + } +} diff --git a/test/TestServerProjects/azure-parameter-grouping/Generated/Configuration.json b/test/TestServerProjects/azure-parameter-grouping/Generated/Configuration.json index 26553b75ff8..ceee25fb1d0 100644 --- a/test/TestServerProjects/azure-parameter-grouping/Generated/Configuration.json +++ b/test/TestServerProjects/azure-parameter-grouping/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Error.Serialization.cs index 0716d12cc84..f9dfc9c74fb 100644 --- a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace azure_parameter_grouping.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Error.cs b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Error.cs index 8f92fcc73c5..f1bb8d9a848 100644 --- a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Error.cs +++ b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace azure_parameter_grouping.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/FirstParameterGroup.cs b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/FirstParameterGroup.cs index 0575f9ff7e1..334bef37cf9 100644 --- a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/FirstParameterGroup.cs +++ b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/FirstParameterGroup.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace azure_parameter_grouping.Models { /// Parameter group. public partial class FirstParameterGroup { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public FirstParameterGroup() { @@ -18,10 +53,12 @@ public FirstParameterGroup() /// Initializes a new instance of . /// /// Query parameter with default. - internal FirstParameterGroup(string headerOne, int? queryOne) + /// Keeps track of any properties unknown to the library. + internal FirstParameterGroup(string headerOne, int? queryOne, IDictionary serializedAdditionalRawData) { HeaderOne = headerOne; QueryOne = queryOne; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the header one. diff --git a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Grouper.cs b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Grouper.cs index 09d9faf83a6..df905ac4de4 100644 --- a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Grouper.cs +++ b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/Grouper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace azure_parameter_grouping.Models { /// Parameter group. public partial class Grouper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Grouper() { @@ -18,10 +53,12 @@ public Grouper() /// Initializes a new instance of . /// A grouped parameter that is a constant. /// Optional parameter part of a parameter grouping. - internal Grouper(EncryptionAlgorithmType? groupedConstant, string groupedParameter) + /// Keeps track of any properties unknown to the library. + internal Grouper(EncryptionAlgorithmType? groupedConstant, string groupedParameter, IDictionary serializedAdditionalRawData) { GroupedConstant = groupedConstant; GroupedParameter = groupedParameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// A grouped parameter that is a constant. diff --git a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostMultiParamGroupsSecondParamGroup.cs b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostMultiParamGroupsSecondParamGroup.cs index 17aac1af798..bc7b2711d69 100644 --- a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostMultiParamGroupsSecondParamGroup.cs +++ b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostMultiParamGroupsSecondParamGroup.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace azure_parameter_grouping.Models { /// Parameter group. public partial class ParameterGroupingPostMultiParamGroupsSecondParamGroup { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ParameterGroupingPostMultiParamGroupsSecondParamGroup() { @@ -18,10 +53,12 @@ public ParameterGroupingPostMultiParamGroupsSecondParamGroup() /// Initializes a new instance of . /// /// Query parameter with default. - internal ParameterGroupingPostMultiParamGroupsSecondParamGroup(string headerTwo, int? queryTwo) + /// Keeps track of any properties unknown to the library. + internal ParameterGroupingPostMultiParamGroupsSecondParamGroup(string headerTwo, int? queryTwo, IDictionary serializedAdditionalRawData) { HeaderTwo = headerTwo; QueryTwo = queryTwo; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the header two. diff --git a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostOptionalParameters.cs b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostOptionalParameters.cs index 5b1c6fde344..f81eb5f3aa3 100644 --- a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostOptionalParameters.cs +++ b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostOptionalParameters.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace azure_parameter_grouping.Models { /// Parameter group. public partial class ParameterGroupingPostOptionalParameters { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ParameterGroupingPostOptionalParameters() { @@ -18,10 +53,12 @@ public ParameterGroupingPostOptionalParameters() /// Initializes a new instance of . /// /// Query parameter with default. - internal ParameterGroupingPostOptionalParameters(string customHeader, int? query) + /// Keeps track of any properties unknown to the library. + internal ParameterGroupingPostOptionalParameters(string customHeader, int? query, IDictionary serializedAdditionalRawData) { CustomHeader = customHeader; Query = query; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the custom header. diff --git a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostRequiredParameters.cs b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostRequiredParameters.cs index bfb5bbcb2a2..9a69cb1fbdf 100644 --- a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostRequiredParameters.cs +++ b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostRequiredParameters.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace azure_parameter_grouping.Models @@ -13,6 +14,38 @@ namespace azure_parameter_grouping.Models /// Parameter group. public partial class ParameterGroupingPostRequiredParameters { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Path parameter. /// @@ -30,12 +63,19 @@ public ParameterGroupingPostRequiredParameters(string path, int body) /// Query parameter with default. /// Path parameter. /// - internal ParameterGroupingPostRequiredParameters(string customHeader, int? query, string path, int body) + /// Keeps track of any properties unknown to the library. + internal ParameterGroupingPostRequiredParameters(string customHeader, int? query, string path, int body, IDictionary serializedAdditionalRawData) { CustomHeader = customHeader; Query = query; Path = path; Body = body; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ParameterGroupingPostRequiredParameters() + { } /// Gets or sets the custom header. diff --git a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostReservedWordsParameters.cs b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostReservedWordsParameters.cs index 220d8a73630..185c7c12941 100644 --- a/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostReservedWordsParameters.cs +++ b/test/TestServerProjects/azure-parameter-grouping/Generated/Models/ParameterGroupingPostReservedWordsParameters.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace azure_parameter_grouping.Models { /// Parameter group. public partial class ParameterGroupingPostReservedWordsParameters { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ParameterGroupingPostReservedWordsParameters() { @@ -18,10 +53,12 @@ public ParameterGroupingPostReservedWordsParameters() /// Initializes a new instance of . /// 'from' is a reserved word. Pass in 'bob' to pass. /// 'accept' is a reserved word. Pass in 'yes' to pass. - internal ParameterGroupingPostReservedWordsParameters(string @from, string accept) + /// Keeps track of any properties unknown to the library. + internal ParameterGroupingPostReservedWordsParameters(string @from, string accept, IDictionary serializedAdditionalRawData) { From = @from; Accept = accept; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// 'from' is a reserved word. Pass in 'bob' to pass. diff --git a/test/TestServerProjects/azure-parameter-grouping/azure_parameter_grouping.csproj b/test/TestServerProjects/azure-parameter-grouping/azure_parameter_grouping.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/azure-parameter-grouping/azure_parameter_grouping.csproj +++ b/test/TestServerProjects/azure-parameter-grouping/azure_parameter_grouping.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/azure-special-properties/Generated/Configuration.json b/test/TestServerProjects/azure-special-properties/Generated/Configuration.json index 58ee1f10ec9..77071cddf6c 100644 --- a/test/TestServerProjects/azure-special-properties/Generated/Configuration.json +++ b/test/TestServerProjects/azure-special-properties/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/azure-special-properties/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/azure-special-properties/Generated/Models/Error.Serialization.cs index e539eb0cbec..12d10062c38 100644 --- a/test/TestServerProjects/azure-special-properties/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/azure-special-properties/Generated/Models/Error.Serialization.cs @@ -5,15 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace azure_special_properties.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + writer.WritePropertyName("constantId"u8); + writer.WriteNumberValue(ConstantId.ToSerialInt32()); + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -21,6 +79,8 @@ internal static Error DeserializeError(JsonElement element) Optional status = default; ErrorConstantId constantId = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -42,8 +102,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), constantId, message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), constantId, message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/azure-special-properties/Generated/Models/Error.cs b/test/TestServerProjects/azure-special-properties/Generated/Models/Error.cs index 3da78b4d6ac..6f8bb0dd397 100644 --- a/test/TestServerProjects/azure-special-properties/Generated/Models/Error.cs +++ b/test/TestServerProjects/azure-special-properties/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace azure_special_properties.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -20,11 +55,13 @@ internal Error() /// /// /// - internal Error(int? status, ErrorConstantId constantId, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, ErrorConstantId constantId, string message, IDictionary serializedAdditionalRawData) { Status = status; ConstantId = constantId; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/azure-special-properties/Generated/Models/HeaderCustomNamedRequestIdParamGroupingParameters.cs b/test/TestServerProjects/azure-special-properties/Generated/Models/HeaderCustomNamedRequestIdParamGroupingParameters.cs index 0aa0133d5ac..451b7bd46a1 100644 --- a/test/TestServerProjects/azure-special-properties/Generated/Models/HeaderCustomNamedRequestIdParamGroupingParameters.cs +++ b/test/TestServerProjects/azure-special-properties/Generated/Models/HeaderCustomNamedRequestIdParamGroupingParameters.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace azure_special_properties.Models @@ -13,6 +14,38 @@ namespace azure_special_properties.Models /// Parameter group. public partial class HeaderCustomNamedRequestIdParamGroupingParameters { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// The fooRequestId. /// is null. @@ -23,6 +56,20 @@ public HeaderCustomNamedRequestIdParamGroupingParameters(string fooClientRequest FooClientRequestId = fooClientRequestId; } + /// Initializes a new instance of . + /// The fooRequestId. + /// Keeps track of any properties unknown to the library. + internal HeaderCustomNamedRequestIdParamGroupingParameters(string fooClientRequestId, IDictionary serializedAdditionalRawData) + { + FooClientRequestId = fooClientRequestId; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal HeaderCustomNamedRequestIdParamGroupingParameters() + { + } + /// The fooRequestId. public string FooClientRequestId { get; } } diff --git a/test/TestServerProjects/azure-special-properties/Generated/Models/OdataFilter.cs b/test/TestServerProjects/azure-special-properties/Generated/Models/OdataFilter.cs index 9473e6d3c50..902366b9629 100644 --- a/test/TestServerProjects/azure-special-properties/Generated/Models/OdataFilter.cs +++ b/test/TestServerProjects/azure-special-properties/Generated/Models/OdataFilter.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace azure_special_properties.Models { /// The OdataFilter. internal partial class OdataFilter { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal OdataFilter() { @@ -18,10 +53,12 @@ internal OdataFilter() /// Initializes a new instance of . /// /// - internal OdataFilter(int? id, string name) + /// Keeps track of any properties unknown to the library. + internal OdataFilter(int? id, string name, IDictionary serializedAdditionalRawData) { Id = id; Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the id. diff --git a/test/TestServerProjects/azure-special-properties/azure_special_properties.csproj b/test/TestServerProjects/azure-special-properties/azure_special_properties.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/azure-special-properties/azure_special_properties.csproj +++ b/test/TestServerProjects/azure-special-properties/azure_special_properties.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-array/Generated/Configuration.json b/test/TestServerProjects/body-array/Generated/Configuration.json index 9c5cfa42945..e7945b40b46 100644 --- a/test/TestServerProjects/body-array/Generated/Configuration.json +++ b/test/TestServerProjects/body-array/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-array/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-array/Generated/Models/Error.Serialization.cs index 4105600cc8f..93551c58d00 100644 --- a/test/TestServerProjects/body-array/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-array/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_array.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-array/Generated/Models/Error.cs b/test/TestServerProjects/body-array/Generated/Models/Error.cs index ab3eb59885c..bd44c762e79 100644 --- a/test/TestServerProjects/body-array/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-array/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_array.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-array/Generated/Models/Product.Serialization.cs b/test/TestServerProjects/body-array/Generated/Models/Product.Serialization.cs index 944ee23e470..19f5641a263 100644 --- a/test/TestServerProjects/body-array/Generated/Models/Product.Serialization.cs +++ b/test/TestServerProjects/body-array/Generated/Models/Product.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_array.Models { - public partial class Product : IUtf8JsonSerializable + public partial class Product : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Integer)) { @@ -25,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("string"u8); writer.WriteStringValue(String); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Product DeserializeProduct(JsonElement element) + Product IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProduct(document.RootElement, options); + } + + internal static Product DeserializeProduct(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional integer = default; Optional @string = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("integer"u8)) @@ -52,8 +94,44 @@ internal static Product DeserializeProduct(JsonElement element) @string = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Product(Optional.ToNullable(integer), @string.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Product(Optional.ToNullable(integer), @string.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + Product IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-array/Generated/Models/Product.cs b/test/TestServerProjects/body-array/Generated/Models/Product.cs index c2ab624c224..7663b6cf9b0 100644 --- a/test/TestServerProjects/body-array/Generated/Models/Product.cs +++ b/test/TestServerProjects/body-array/Generated/Models/Product.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_array.Models { /// The Product. public partial class Product { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Product() { @@ -18,10 +53,12 @@ public Product() /// Initializes a new instance of . /// /// - internal Product(int? integer, string @string) + /// Keeps track of any properties unknown to the library. + internal Product(int? integer, string @string, IDictionary serializedAdditionalRawData) { Integer = integer; String = @string; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the integer. diff --git a/test/TestServerProjects/body-array/body_array.csproj b/test/TestServerProjects/body-array/body_array.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-array/body_array.csproj +++ b/test/TestServerProjects/body-array/body_array.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-boolean/Generated/Configuration.json b/test/TestServerProjects/body-boolean/Generated/Configuration.json index 2539712fb7a..3d035401c3d 100644 --- a/test/TestServerProjects/body-boolean/Generated/Configuration.json +++ b/test/TestServerProjects/body-boolean/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-boolean/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-boolean/Generated/Models/Error.Serialization.cs index c9ab1698018..6c9a0280b38 100644 --- a/test/TestServerProjects/body-boolean/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-boolean/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_boolean.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-boolean/Generated/Models/Error.cs b/test/TestServerProjects/body-boolean/Generated/Models/Error.cs index 21ada941433..e49fb310a8f 100644 --- a/test/TestServerProjects/body-boolean/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-boolean/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_boolean.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-boolean/body_boolean.csproj b/test/TestServerProjects/body-boolean/body_boolean.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-boolean/body_boolean.csproj +++ b/test/TestServerProjects/body-boolean/body_boolean.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-byte/Generated/Configuration.json b/test/TestServerProjects/body-byte/Generated/Configuration.json index 394a40ced03..4a587951700 100644 --- a/test/TestServerProjects/body-byte/Generated/Configuration.json +++ b/test/TestServerProjects/body-byte/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-byte/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-byte/Generated/Models/Error.Serialization.cs index 8223702abae..bfe9fea7093 100644 --- a/test/TestServerProjects/body-byte/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-byte/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_byte.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-byte/Generated/Models/Error.cs b/test/TestServerProjects/body-byte/Generated/Models/Error.cs index 6ee1800dac5..9bdb0c37a37 100644 --- a/test/TestServerProjects/body-byte/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-byte/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_byte.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-byte/body_byte.csproj b/test/TestServerProjects/body-byte/body_byte.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-byte/body_byte.csproj +++ b/test/TestServerProjects/body-byte/body_byte.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-complex/Generated/BodyComplexModelFactory.cs b/test/TestServerProjects/body-complex/Generated/BodyComplexModelFactory.cs index 967c7b6ce6d..b81a5464c2a 100644 --- a/test/TestServerProjects/body-complex/Generated/BodyComplexModelFactory.cs +++ b/test/TestServerProjects/body-complex/Generated/BodyComplexModelFactory.cs @@ -19,7 +19,7 @@ public static partial class BodyComplexModelFactory /// A new instance for mocking. public static DotFish DotFish(string fishType = null, string species = null) { - return new UnknownDotFish(fishType, species); + return new UnknownDotFish(fishType, species, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -39,7 +39,7 @@ public static DotFishMarket DotFishMarket(DotSalmon sampleSalmon = null, IEnumer salmons ??= new List(); fishes ??= new List(); - return new DotFishMarket(sampleSalmon, salmons?.ToList(), sampleFish, fishes?.ToList()); + return new DotFishMarket(sampleSalmon, salmons?.ToList(), sampleFish, fishes?.ToList(), serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -49,7 +49,7 @@ public static DotFishMarket DotFishMarket(DotSalmon sampleSalmon = null, IEnumer /// A new instance for mocking. public static DotSalmon DotSalmon(string species = null, string location = null, bool? iswild = null) { - return new DotSalmon("DotSalmon", species, location, iswild); + return new DotSalmon("DotSalmon", species, serializedAdditionalRawData: null, location, iswild); } /// Initializes a new instance of . @@ -58,7 +58,7 @@ public static DotSalmon DotSalmon(string species = null, string location = null, /// A new instance for mocking. public static ReadonlyObj ReadonlyObj(string id = null, int? size = null) { - return new ReadonlyObj(id, size); + return new ReadonlyObj(id, size, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -68,7 +68,7 @@ public static ReadonlyObj ReadonlyObj(string id = null, int? size = null) /// A new instance for mocking. public static MyBaseType MyBaseType(string kind = "Unknown", string propB1 = null, string propBH1 = null) { - return new UnknownMyBaseType(kind, propB1, propBH1); + return new UnknownMyBaseType(kind, propB1, propBH1, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -78,7 +78,7 @@ public static MyBaseType MyBaseType(string kind = "Unknown", string propB1 = nul /// A new instance for mocking. public static MyDerivedType MyDerivedType(string propB1 = null, string propBH1 = null, string propD1 = null) { - return new MyDerivedType(MyKind.Kind1, propB1, propBH1, propD1); + return new MyDerivedType(MyKind.Kind1, propB1, propBH1, serializedAdditionalRawData: null, propD1); } } } diff --git a/test/TestServerProjects/body-complex/Generated/Configuration.json b/test/TestServerProjects/body-complex/Generated/Configuration.json index 659fe26d91d..faededc1d6c 100644 --- a/test/TestServerProjects/body-complex/Generated/Configuration.json +++ b/test/TestServerProjects/body-complex/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-complex/Generated/Models/ArrayWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/ArrayWrapper.Serialization.cs index 1cfc09124ca..859a16d9775 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/ArrayWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/ArrayWrapper.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class ArrayWrapper : IUtf8JsonSerializable + public partial class ArrayWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ArrayWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsCollectionDefined(Array)) { @@ -26,16 +36,47 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ArrayWrapper DeserializeArrayWrapper(JsonElement element) + ArrayWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ArrayWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeArrayWrapper(document.RootElement, options); + } + + internal static ArrayWrapper DeserializeArrayWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional> array = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("array"u8)) @@ -52,8 +93,44 @@ internal static ArrayWrapper DeserializeArrayWrapper(JsonElement element) array = array0; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ArrayWrapper(Optional.ToList(array)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ArrayWrapper(Optional.ToList(array), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ArrayWrapper)} does not support '{options.Format}' format."); + } + } + + ArrayWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeArrayWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ArrayWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/ArrayWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/ArrayWrapper.cs index c2425a87edb..56e50b6178f 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/ArrayWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/ArrayWrapper.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace body_complex.Models /// The ArrayWrapper. public partial class ArrayWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ArrayWrapper() { @@ -21,9 +54,11 @@ public ArrayWrapper() /// Initializes a new instance of . /// - internal ArrayWrapper(IList array) + /// Keeps track of any properties unknown to the library. + internal ArrayWrapper(IList array, IDictionary serializedAdditionalRawData) { Array = array; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the array. diff --git a/test/TestServerProjects/body-complex/Generated/Models/Basic.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Basic.Serialization.cs index e9f86dc64e7..0076a1cd0f6 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Basic.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Basic.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Basic : IUtf8JsonSerializable + public partial class Basic : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Basic)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Id)) { @@ -37,11 +48,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("color"u8); writer.WriteStringValue(Color.Value.ToString()); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Basic DeserializeBasic(JsonElement element) + Basic IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Basic)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeBasic(document.RootElement, options); + } + + internal static Basic DeserializeBasic(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -49,6 +89,8 @@ internal static Basic DeserializeBasic(JsonElement element) Optional id = default; Optional name = default; Optional color = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -75,8 +117,44 @@ internal static Basic DeserializeBasic(JsonElement element) color = new CMYKColors(property.Value.GetString()); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Basic(Optional.ToNullable(id), name.Value, Optional.ToNullable(color)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Basic(Optional.ToNullable(id), name.Value, Optional.ToNullable(color), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Basic)} does not support '{options.Format}' format."); + } + } + + Basic IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeBasic(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Basic)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Basic.cs b/test/TestServerProjects/body-complex/Generated/Models/Basic.cs index 4494334104b..4eeeb747314 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Basic.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Basic.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The Basic. public partial class Basic { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Basic() { @@ -19,11 +54,13 @@ public Basic() /// Basic Id. /// Name property with a very long description that does not fit on a single line and a line break. /// - internal Basic(int? id, string name, CMYKColors? color) + /// Keeps track of any properties unknown to the library. + internal Basic(int? id, string name, CMYKColors? color, IDictionary serializedAdditionalRawData) { Id = id; Name = name; Color = color; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Basic Id. diff --git a/test/TestServerProjects/body-complex/Generated/Models/BooleanWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/BooleanWrapper.Serialization.cs index 23c3e009d0a..1909ebd6b81 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/BooleanWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/BooleanWrapper.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class BooleanWrapper : IUtf8JsonSerializable + public partial class BooleanWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BooleanWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(FieldTrue)) { @@ -25,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("field_false"u8); writer.WriteBooleanValue(FieldFalse.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static BooleanWrapper DeserializeBooleanWrapper(JsonElement element) + BooleanWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BooleanWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeBooleanWrapper(document.RootElement, options); + } + + internal static BooleanWrapper DeserializeBooleanWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional fieldTrue = default; Optional fieldFalse = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field_true"u8)) @@ -56,8 +98,44 @@ internal static BooleanWrapper DeserializeBooleanWrapper(JsonElement element) fieldFalse = property.Value.GetBoolean(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new BooleanWrapper(Optional.ToNullable(fieldTrue), Optional.ToNullable(fieldFalse)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new BooleanWrapper(Optional.ToNullable(fieldTrue), Optional.ToNullable(fieldFalse), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(BooleanWrapper)} does not support '{options.Format}' format."); + } + } + + BooleanWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeBooleanWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(BooleanWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/BooleanWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/BooleanWrapper.cs index c9b1f276de4..f561c662fae 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/BooleanWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/BooleanWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The BooleanWrapper. public partial class BooleanWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public BooleanWrapper() { @@ -18,10 +53,12 @@ public BooleanWrapper() /// Initializes a new instance of . /// /// - internal BooleanWrapper(bool? fieldTrue, bool? fieldFalse) + /// Keeps track of any properties unknown to the library. + internal BooleanWrapper(bool? fieldTrue, bool? fieldFalse, IDictionary serializedAdditionalRawData) { FieldTrue = fieldTrue; FieldFalse = fieldFalse; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field true. diff --git a/test/TestServerProjects/body-complex/Generated/Models/ByteWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/ByteWrapper.Serialization.cs index d4a28ee5d63..6ca7b6c1357 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/ByteWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/ByteWrapper.Serialization.cs @@ -6,31 +6,72 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class ByteWrapper : IUtf8JsonSerializable + public partial class ByteWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ByteWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Field)) { writer.WritePropertyName("field"u8); writer.WriteBase64StringValue(Field, "D"); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ByteWrapper DeserializeByteWrapper(JsonElement element) + ByteWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ByteWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeByteWrapper(document.RootElement, options); + } + + internal static ByteWrapper DeserializeByteWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional field = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field"u8)) @@ -42,8 +83,44 @@ internal static ByteWrapper DeserializeByteWrapper(JsonElement element) field = property.Value.GetBytesFromBase64("D"); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ByteWrapper(field.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ByteWrapper(field.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ByteWrapper)} does not support '{options.Format}' format."); + } + } + + ByteWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeByteWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ByteWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/ByteWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/ByteWrapper.cs index b5be6443dc0..55f142a20de 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/ByteWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/ByteWrapper.cs @@ -6,12 +6,45 @@ #nullable disable using System; +using System.Collections.Generic; namespace body_complex.Models { /// The ByteWrapper. public partial class ByteWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ByteWrapper() { @@ -19,9 +52,11 @@ public ByteWrapper() /// Initializes a new instance of . /// - internal ByteWrapper(byte[] field) + /// Keeps track of any properties unknown to the library. + internal ByteWrapper(byte[] field, IDictionary serializedAdditionalRawData) { Field = field; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field. diff --git a/test/TestServerProjects/body-complex/Generated/Models/Cat.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Cat.Serialization.cs index 109c2af3f5b..497d04c4fcc 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Cat.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Cat.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Cat : IUtf8JsonSerializable + public partial class Cat : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Cat)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Color)) { @@ -41,11 +51,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Cat DeserializeCat(JsonElement element) + Cat IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Cat)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeCat(document.RootElement, options); + } + + internal static Cat DeserializeCat(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -54,6 +93,8 @@ internal static Cat DeserializeCat(JsonElement element) Optional> hates = default; Optional id = default; Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("color"u8)) @@ -89,8 +130,44 @@ internal static Cat DeserializeCat(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Cat(Optional.ToNullable(id), name.Value, color.Value, Optional.ToList(hates)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Cat(Optional.ToNullable(id), name.Value, serializedAdditionalRawData, color.Value, Optional.ToList(hates)); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Cat)} does not support '{options.Format}' format."); + } + } + + Cat IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeCat(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Cat)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Cat.cs b/test/TestServerProjects/body-complex/Generated/Models/Cat.cs index dd46ef73673..34976091a01 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Cat.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Cat.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -22,9 +23,10 @@ public Cat() /// Initializes a new instance of . /// /// + /// Keeps track of any properties unknown to the library. /// /// - internal Cat(int? id, string name, string color, IList hates) : base(id, name) + internal Cat(int? id, string name, IDictionary serializedAdditionalRawData, string color, IList hates) : base(id, name, serializedAdditionalRawData) { Color = color; Hates = hates; diff --git a/test/TestServerProjects/body-complex/Generated/Models/Cookiecuttershark.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Cookiecuttershark.Serialization.cs index 6e54b6b3f95..0a3a08f9153 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Cookiecuttershark.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Cookiecuttershark.Serialization.cs @@ -6,16 +6,25 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Cookiecuttershark : IUtf8JsonSerializable + public partial class Cookiecuttershark : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Cookiecuttershark)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Age)) { @@ -43,11 +52,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Cookiecuttershark DeserializeCookiecuttershark(JsonElement element) + Cookiecuttershark IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Cookiecuttershark)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeCookiecuttershark(document.RootElement, options); + } + + internal static Cookiecuttershark DeserializeCookiecuttershark(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -58,6 +96,8 @@ internal static Cookiecuttershark DeserializeCookiecuttershark(JsonElement eleme Optional species = default; float length = default; Optional> siblings = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("age"u8)) @@ -103,8 +143,44 @@ internal static Cookiecuttershark DeserializeCookiecuttershark(JsonElement eleme siblings = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Cookiecuttershark(fishtype, species.Value, length, Optional.ToList(siblings), Optional.ToNullable(age), birthday); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Cookiecuttershark(fishtype, species.Value, length, Optional.ToList(siblings), serializedAdditionalRawData, Optional.ToNullable(age), birthday); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Cookiecuttershark)} does not support '{options.Format}' format."); + } + } + + Cookiecuttershark IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeCookiecuttershark(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Cookiecuttershark)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Cookiecuttershark.cs b/test/TestServerProjects/body-complex/Generated/Models/Cookiecuttershark.cs index 878023da690..f9aafb70901 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Cookiecuttershark.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Cookiecuttershark.cs @@ -29,11 +29,17 @@ public Cookiecuttershark(float length, DateTimeOffset birthday) : base(length, b /// Please note is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes. /// The available derived classes include , , , , and . /// + /// Keeps track of any properties unknown to the library. /// /// - internal Cookiecuttershark(string fishtype, string species, float length, IList siblings, int? age, DateTimeOffset birthday) : base(fishtype, species, length, siblings, age, birthday) + internal Cookiecuttershark(string fishtype, string species, float length, IList siblings, IDictionary serializedAdditionalRawData, int? age, DateTimeOffset birthday) : base(fishtype, species, length, siblings, serializedAdditionalRawData, age, birthday) { Fishtype = fishtype ?? "cookiecuttershark"; } + + /// Initializes a new instance of for deserialization. + internal Cookiecuttershark() + { + } } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/DateWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/DateWrapper.Serialization.cs index aef23045539..547b88d413f 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DateWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DateWrapper.Serialization.cs @@ -6,15 +6,25 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class DateWrapper : IUtf8JsonSerializable + public partial class DateWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DateWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Field)) { @@ -26,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("leap"u8); writer.WriteStringValue(Leap.Value, "D"); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static DateWrapper DeserializeDateWrapper(JsonElement element) + DateWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DateWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDateWrapper(document.RootElement, options); + } + + internal static DateWrapper DeserializeDateWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional field = default; Optional leap = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field"u8)) @@ -57,8 +98,44 @@ internal static DateWrapper DeserializeDateWrapper(JsonElement element) leap = property.Value.GetDateTimeOffset("D"); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new DateWrapper(Optional.ToNullable(field), Optional.ToNullable(leap)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DateWrapper(Optional.ToNullable(field), Optional.ToNullable(leap), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DateWrapper)} does not support '{options.Format}' format."); + } + } + + DateWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDateWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DateWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/DateWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/DateWrapper.cs index 5e1e5a619fc..3df503091f4 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DateWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DateWrapper.cs @@ -6,12 +6,45 @@ #nullable disable using System; +using System.Collections.Generic; namespace body_complex.Models { /// The DateWrapper. public partial class DateWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public DateWrapper() { @@ -20,10 +53,12 @@ public DateWrapper() /// Initializes a new instance of . /// /// - internal DateWrapper(DateTimeOffset? field, DateTimeOffset? leap) + /// Keeps track of any properties unknown to the library. + internal DateWrapper(DateTimeOffset? field, DateTimeOffset? leap, IDictionary serializedAdditionalRawData) { Field = field; Leap = leap; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field. diff --git a/test/TestServerProjects/body-complex/Generated/Models/DatetimeWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/DatetimeWrapper.Serialization.cs index 0e243e48d80..d3569df3690 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DatetimeWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DatetimeWrapper.Serialization.cs @@ -6,15 +6,25 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class DatetimeWrapper : IUtf8JsonSerializable + public partial class DatetimeWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DatetimeWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Field)) { @@ -26,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("now"u8); writer.WriteStringValue(Now.Value, "O"); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static DatetimeWrapper DeserializeDatetimeWrapper(JsonElement element) + DatetimeWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DatetimeWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDatetimeWrapper(document.RootElement, options); + } + + internal static DatetimeWrapper DeserializeDatetimeWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional field = default; Optional now = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field"u8)) @@ -57,8 +98,44 @@ internal static DatetimeWrapper DeserializeDatetimeWrapper(JsonElement element) now = property.Value.GetDateTimeOffset("O"); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new DatetimeWrapper(Optional.ToNullable(field), Optional.ToNullable(now)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DatetimeWrapper(Optional.ToNullable(field), Optional.ToNullable(now), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DatetimeWrapper)} does not support '{options.Format}' format."); + } + } + + DatetimeWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDatetimeWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DatetimeWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/DatetimeWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/DatetimeWrapper.cs index 8de94d6aec1..ff6eb87cc2f 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DatetimeWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DatetimeWrapper.cs @@ -6,12 +6,45 @@ #nullable disable using System; +using System.Collections.Generic; namespace body_complex.Models { /// The DatetimeWrapper. public partial class DatetimeWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public DatetimeWrapper() { @@ -20,10 +53,12 @@ public DatetimeWrapper() /// Initializes a new instance of . /// /// - internal DatetimeWrapper(DateTimeOffset? field, DateTimeOffset? now) + /// Keeps track of any properties unknown to the library. + internal DatetimeWrapper(DateTimeOffset? field, DateTimeOffset? now, IDictionary serializedAdditionalRawData) { Field = field; Now = now; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field. diff --git a/test/TestServerProjects/body-complex/Generated/Models/Datetimerfc1123Wrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Datetimerfc1123Wrapper.Serialization.cs index 4672e133894..5ee78b1d69e 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Datetimerfc1123Wrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Datetimerfc1123Wrapper.Serialization.cs @@ -6,15 +6,25 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Datetimerfc1123Wrapper : IUtf8JsonSerializable + public partial class Datetimerfc1123Wrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Datetimerfc1123Wrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Field)) { @@ -26,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("now"u8); writer.WriteStringValue(Now.Value, "R"); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Datetimerfc1123Wrapper DeserializeDatetimerfc1123Wrapper(JsonElement element) + Datetimerfc1123Wrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Datetimerfc1123Wrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDatetimerfc1123Wrapper(document.RootElement, options); + } + + internal static Datetimerfc1123Wrapper DeserializeDatetimerfc1123Wrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional field = default; Optional now = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field"u8)) @@ -57,8 +98,44 @@ internal static Datetimerfc1123Wrapper DeserializeDatetimerfc1123Wrapper(JsonEle now = property.Value.GetDateTimeOffset("R"); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Datetimerfc1123Wrapper(Optional.ToNullable(field), Optional.ToNullable(now)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Datetimerfc1123Wrapper(Optional.ToNullable(field), Optional.ToNullable(now), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Datetimerfc1123Wrapper)} does not support '{options.Format}' format."); + } + } + + Datetimerfc1123Wrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDatetimerfc1123Wrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Datetimerfc1123Wrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Datetimerfc1123Wrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/Datetimerfc1123Wrapper.cs index a32ced44db2..33b3bbf045d 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Datetimerfc1123Wrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Datetimerfc1123Wrapper.cs @@ -6,12 +6,45 @@ #nullable disable using System; +using System.Collections.Generic; namespace body_complex.Models { /// The Datetimerfc1123Wrapper. public partial class Datetimerfc1123Wrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Datetimerfc1123Wrapper() { @@ -20,10 +53,12 @@ public Datetimerfc1123Wrapper() /// Initializes a new instance of . /// /// - internal Datetimerfc1123Wrapper(DateTimeOffset? field, DateTimeOffset? now) + /// Keeps track of any properties unknown to the library. + internal Datetimerfc1123Wrapper(DateTimeOffset? field, DateTimeOffset? now, IDictionary serializedAdditionalRawData) { Field = field; Now = now; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field. diff --git a/test/TestServerProjects/body-complex/Generated/Models/DictionaryWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/DictionaryWrapper.Serialization.cs index 88d0d9681c9..6b5f6dea058 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DictionaryWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DictionaryWrapper.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class DictionaryWrapper : IUtf8JsonSerializable + public partial class DictionaryWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DictionaryWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsCollectionDefined(DefaultProgram)) { @@ -34,16 +44,47 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteNull("defaultProgram"); } } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static DictionaryWrapper DeserializeDictionaryWrapper(JsonElement element) + DictionaryWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DictionaryWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDictionaryWrapper(document.RootElement, options); + } + + internal static DictionaryWrapper DeserializeDictionaryWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional> defaultProgram = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("defaultProgram"u8)) @@ -60,8 +101,44 @@ internal static DictionaryWrapper DeserializeDictionaryWrapper(JsonElement eleme defaultProgram = dictionary; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new DictionaryWrapper(Optional.ToDictionary(defaultProgram)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DictionaryWrapper(Optional.ToDictionary(defaultProgram), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DictionaryWrapper)} does not support '{options.Format}' format."); + } + } + + DictionaryWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDictionaryWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DictionaryWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/DictionaryWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/DictionaryWrapper.cs index c03264cacdc..24c15ecdf9c 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DictionaryWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DictionaryWrapper.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace body_complex.Models /// The DictionaryWrapper. public partial class DictionaryWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public DictionaryWrapper() { @@ -21,9 +54,11 @@ public DictionaryWrapper() /// Initializes a new instance of . /// Dictionary of <string>. - internal DictionaryWrapper(IDictionary defaultProgram) + /// Keeps track of any properties unknown to the library. + internal DictionaryWrapper(IDictionary defaultProgram, IDictionary serializedAdditionalRawData) { DefaultProgram = defaultProgram; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Dictionary of <string>. diff --git a/test/TestServerProjects/body-complex/Generated/Models/Dog.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Dog.Serialization.cs index 012cb08a41a..b09ccb9fb22 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Dog.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Dog.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Dog : IUtf8JsonSerializable + public partial class Dog : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Dog)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Food)) { @@ -30,11 +41,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Dog DeserializeDog(JsonElement element) + Dog IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Dog)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDog(document.RootElement, options); + } + + internal static Dog DeserializeDog(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -42,6 +82,8 @@ internal static Dog DeserializeDog(JsonElement element) Optional food = default; Optional id = default; Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("food"u8)) @@ -63,8 +105,44 @@ internal static Dog DeserializeDog(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Dog(Optional.ToNullable(id), name.Value, food.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Dog(Optional.ToNullable(id), name.Value, serializedAdditionalRawData, food.Value); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Dog)} does not support '{options.Format}' format."); + } + } + + Dog IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDog(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Dog)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Dog.cs b/test/TestServerProjects/body-complex/Generated/Models/Dog.cs index b7ce83845c9..aafdf06f857 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Dog.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Dog.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The Dog. @@ -18,8 +21,9 @@ public Dog() /// Initializes a new instance of . /// /// + /// Keeps track of any properties unknown to the library. /// - internal Dog(int? id, string name, string food) : base(id, name) + internal Dog(int? id, string name, IDictionary serializedAdditionalRawData, string food) : base(id, name, serializedAdditionalRawData) { Food = food; } diff --git a/test/TestServerProjects/body-complex/Generated/Models/DotFish.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/DotFish.Serialization.cs index 0d6b0f36c1e..e13fe729817 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DotFish.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DotFish.Serialization.cs @@ -5,14 +5,68 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; +using Azure.Core; namespace body_complex.Models { - public partial class DotFish + [PersistableModelProxy(typeof(UnknownDotFish))] + public partial class DotFish : IUtf8JsonSerializable, IJsonModel { - internal static DotFish DeserializeDotFish(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DotFish)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("fish.type"u8); + writer.WriteStringValue(FishType); + if (Optional.IsDefined(Species)) + { + writer.WritePropertyName("species"u8); + writer.WriteStringValue(Species); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + DotFish IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DotFish)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDotFish(document.RootElement, options); + } + + internal static DotFish DeserializeDotFish(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -26,5 +80,36 @@ internal static DotFish DeserializeDotFish(JsonElement element) } return UnknownDotFish.DeserializeUnknownDotFish(element); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DotFish)} does not support '{options.Format}' format."); + } + } + + DotFish IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDotFish(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DotFish)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/DotFish.cs b/test/TestServerProjects/body-complex/Generated/Models/DotFish.cs index 165fdc44d00..84b74a44c12 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DotFish.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DotFish.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// @@ -14,6 +17,38 @@ namespace body_complex.Models /// public abstract partial class DotFish { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . protected DotFish() { @@ -22,10 +57,12 @@ protected DotFish() /// Initializes a new instance of . /// /// - internal DotFish(string fishType, string species) + /// Keeps track of any properties unknown to the library. + internal DotFish(string fishType, string species, IDictionary serializedAdditionalRawData) { FishType = fishType; Species = species; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the fish type. diff --git a/test/TestServerProjects/body-complex/Generated/Models/DotFishMarket.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/DotFishMarket.Serialization.cs index 092f3dad2de..57f3545b3c4 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DotFishMarket.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DotFishMarket.Serialization.cs @@ -5,16 +5,91 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class DotFishMarket + public partial class DotFishMarket : IUtf8JsonSerializable, IJsonModel { - internal static DotFishMarket DeserializeDotFishMarket(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DotFishMarket)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(SampleSalmon)) + { + writer.WritePropertyName("sampleSalmon"u8); + writer.WriteObjectValue(SampleSalmon); + } + if (Optional.IsCollectionDefined(Salmons)) + { + writer.WritePropertyName("salmons"u8); + writer.WriteStartArray(); + foreach (var item in Salmons) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(SampleFish)) + { + writer.WritePropertyName("sampleFish"u8); + writer.WriteObjectValue(SampleFish); + } + if (Optional.IsCollectionDefined(Fishes)) + { + writer.WritePropertyName("fishes"u8); + writer.WriteStartArray(); + foreach (var item in Fishes) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + DotFishMarket IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DotFishMarket)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDotFishMarket(document.RootElement, options); + } + + internal static DotFishMarket DeserializeDotFishMarket(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -23,6 +98,8 @@ internal static DotFishMarket DeserializeDotFishMarket(JsonElement element) Optional> salmons = default; Optional sampleFish = default; Optional> fishes = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("sampleSalmon"u8)) @@ -71,8 +148,44 @@ internal static DotFishMarket DeserializeDotFishMarket(JsonElement element) fishes = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DotFishMarket(sampleSalmon.Value, Optional.ToList(salmons), sampleFish.Value, Optional.ToList(fishes), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DotFishMarket)} does not support '{options.Format}' format."); + } + } + + DotFishMarket IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDotFishMarket(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DotFishMarket)} does not support '{options.Format}' format."); } - return new DotFishMarket(sampleSalmon.Value, Optional.ToList(salmons), sampleFish.Value, Optional.ToList(fishes)); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/DotFishMarket.cs b/test/TestServerProjects/body-complex/Generated/Models/DotFishMarket.cs index a3cd162ee9c..e3420f18bd4 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DotFishMarket.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DotFishMarket.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace body_complex.Models /// The DotFishMarket. public partial class DotFishMarket { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal DotFishMarket() { @@ -31,12 +64,14 @@ internal DotFishMarket() /// Please note is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes. /// The available derived classes include . /// - internal DotFishMarket(DotSalmon sampleSalmon, IReadOnlyList salmons, DotFish sampleFish, IReadOnlyList fishes) + /// Keeps track of any properties unknown to the library. + internal DotFishMarket(DotSalmon sampleSalmon, IReadOnlyList salmons, DotFish sampleFish, IReadOnlyList fishes, IDictionary serializedAdditionalRawData) { SampleSalmon = sampleSalmon; Salmons = salmons; SampleFish = sampleFish; Fishes = fishes; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the sample salmon. diff --git a/test/TestServerProjects/body-complex/Generated/Models/DotSalmon.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/DotSalmon.Serialization.cs index b122e122b02..b91a772b1f1 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DotSalmon.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DotSalmon.Serialization.cs @@ -5,15 +5,78 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class DotSalmon + public partial class DotSalmon : IUtf8JsonSerializable, IJsonModel { - internal static DotSalmon DeserializeDotSalmon(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DotSalmon)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Location)) + { + writer.WritePropertyName("location"u8); + writer.WriteStringValue(Location); + } + if (Optional.IsDefined(Iswild)) + { + writer.WritePropertyName("iswild"u8); + writer.WriteBooleanValue(Iswild.Value); + } + writer.WritePropertyName("fish.type"u8); + writer.WriteStringValue(FishType); + if (Optional.IsDefined(Species)) + { + writer.WritePropertyName("species"u8); + writer.WriteStringValue(Species); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + DotSalmon IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DotSalmon)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDotSalmon(document.RootElement, options); + } + + internal static DotSalmon DeserializeDotSalmon(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -22,6 +85,8 @@ internal static DotSalmon DeserializeDotSalmon(JsonElement element) Optional iswild = default; string fishType = default; Optional species = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("location"u8)) @@ -48,8 +113,44 @@ internal static DotSalmon DeserializeDotSalmon(JsonElement element) species = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new DotSalmon(fishType, species.Value, location.Value, Optional.ToNullable(iswild)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DotSalmon(fishType, species.Value, serializedAdditionalRawData, location.Value, Optional.ToNullable(iswild)); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DotSalmon)} does not support '{options.Format}' format."); + } + } + + DotSalmon IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDotSalmon(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DotSalmon)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/DotSalmon.cs b/test/TestServerProjects/body-complex/Generated/Models/DotSalmon.cs index 89e3ee83385..b86ab143250 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DotSalmon.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DotSalmon.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The DotSalmon. @@ -19,9 +22,10 @@ internal DotSalmon() /// Initializes a new instance of . /// /// + /// Keeps track of any properties unknown to the library. /// /// - internal DotSalmon(string fishType, string species, string location, bool? iswild) : base(fishType, species) + internal DotSalmon(string fishType, string species, IDictionary serializedAdditionalRawData, string location, bool? iswild) : base(fishType, species, serializedAdditionalRawData) { Location = location; Iswild = iswild; diff --git a/test/TestServerProjects/body-complex/Generated/Models/DoubleWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/DoubleWrapper.Serialization.cs index 5705c579df4..7ca2f10bda2 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DoubleWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DoubleWrapper.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class DoubleWrapper : IUtf8JsonSerializable + public partial class DoubleWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DoubleWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Field1)) { @@ -25,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("field_56_zeros_after_the_dot_and_negative_zero_before_dot_and_this_is_a_long_field_name_on_purpose"u8); writer.WriteNumberValue(Field56ZerosAfterTheDotAndNegativeZeroBeforeDotAndThisIsALongFieldNameOnPurpose.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static DoubleWrapper DeserializeDoubleWrapper(JsonElement element) + DoubleWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DoubleWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDoubleWrapper(document.RootElement, options); + } + + internal static DoubleWrapper DeserializeDoubleWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional field1 = default; Optional field56ZerosAfterTheDotAndNegativeZeroBeforeDotAndThisIsALongFieldNameOnPurpose = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field1"u8)) @@ -56,8 +98,44 @@ internal static DoubleWrapper DeserializeDoubleWrapper(JsonElement element) field56ZerosAfterTheDotAndNegativeZeroBeforeDotAndThisIsALongFieldNameOnPurpose = property.Value.GetDouble(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new DoubleWrapper(Optional.ToNullable(field1), Optional.ToNullable(field56ZerosAfterTheDotAndNegativeZeroBeforeDotAndThisIsALongFieldNameOnPurpose)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DoubleWrapper(Optional.ToNullable(field1), Optional.ToNullable(field56ZerosAfterTheDotAndNegativeZeroBeforeDotAndThisIsALongFieldNameOnPurpose), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DoubleWrapper)} does not support '{options.Format}' format."); + } + } + + DoubleWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDoubleWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DoubleWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/DoubleWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/DoubleWrapper.cs index 7425073f33f..cd41e71accb 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DoubleWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DoubleWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The DoubleWrapper. public partial class DoubleWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public DoubleWrapper() { @@ -18,10 +53,12 @@ public DoubleWrapper() /// Initializes a new instance of . /// /// - internal DoubleWrapper(double? field1, double? field56ZerosAfterTheDotAndNegativeZeroBeforeDotAndThisIsALongFieldNameOnPurpose) + /// Keeps track of any properties unknown to the library. + internal DoubleWrapper(double? field1, double? field56ZerosAfterTheDotAndNegativeZeroBeforeDotAndThisIsALongFieldNameOnPurpose, IDictionary serializedAdditionalRawData) { Field1 = field1; Field56ZerosAfterTheDotAndNegativeZeroBeforeDotAndThisIsALongFieldNameOnPurpose = field56ZerosAfterTheDotAndNegativeZeroBeforeDotAndThisIsALongFieldNameOnPurpose; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field 1. diff --git a/test/TestServerProjects/body-complex/Generated/Models/DurationWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/DurationWrapper.Serialization.cs index 1d8d2b3ec1c..3bd5b190049 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DurationWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DurationWrapper.Serialization.cs @@ -6,31 +6,72 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class DurationWrapper : IUtf8JsonSerializable + public partial class DurationWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DurationWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Field)) { writer.WritePropertyName("field"u8); writer.WriteStringValue(Field.Value, "P"); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static DurationWrapper DeserializeDurationWrapper(JsonElement element) + DurationWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DurationWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDurationWrapper(document.RootElement, options); + } + + internal static DurationWrapper DeserializeDurationWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional field = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field"u8)) @@ -42,8 +83,44 @@ internal static DurationWrapper DeserializeDurationWrapper(JsonElement element) field = property.Value.GetTimeSpan("P"); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new DurationWrapper(Optional.ToNullable(field)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new DurationWrapper(Optional.ToNullable(field), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DurationWrapper)} does not support '{options.Format}' format."); + } + } + + DurationWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeDurationWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DurationWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/DurationWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/DurationWrapper.cs index 7d2a78a4bfe..da089cd6841 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/DurationWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/DurationWrapper.cs @@ -6,12 +6,45 @@ #nullable disable using System; +using System.Collections.Generic; namespace body_complex.Models { /// The DurationWrapper. public partial class DurationWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public DurationWrapper() { @@ -19,9 +52,11 @@ public DurationWrapper() /// Initializes a new instance of . /// - internal DurationWrapper(TimeSpan? field) + /// Keeps track of any properties unknown to the library. + internal DurationWrapper(TimeSpan? field, IDictionary serializedAdditionalRawData) { Field = field; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field. diff --git a/test/TestServerProjects/body-complex/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Error.Serialization.cs index 1983a54de46..0057ddfc86b 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Error.cs b/test/TestServerProjects/body-complex/Generated/Models/Error.cs index 78cb3717d56..bef3c65b3f6 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-complex/Generated/Models/Fish.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Fish.Serialization.cs index 14004a55985..e4e37f20dcd 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Fish.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Fish.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Fish : IUtf8JsonSerializable + [PersistableModelProxy(typeof(UnknownFish))] + public partial class Fish : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Fish)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("fishtype"u8); writer.WriteStringValue(Fishtype); @@ -34,11 +45,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Fish DeserializeFish(JsonElement element) + Fish IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Fish)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeFish(document.RootElement, options); + } + + internal static Fish DeserializeFish(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -57,5 +97,36 @@ internal static Fish DeserializeFish(JsonElement element) } return UnknownFish.DeserializeUnknownFish(element); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Fish)} does not support '{options.Format}' format."); + } + } + + Fish IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeFish(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Fish)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Fish.cs b/test/TestServerProjects/body-complex/Generated/Models/Fish.cs index d65a5c34cd3..ecbffc90523 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Fish.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Fish.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -17,6 +18,38 @@ namespace body_complex.Models /// public abstract partial class Fish { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// protected Fish(float length) @@ -33,12 +66,19 @@ protected Fish(float length) /// Please note is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes. /// The available derived classes include , , , , and . /// - internal Fish(string fishtype, string species, float length, IList siblings) + /// Keeps track of any properties unknown to the library. + internal Fish(string fishtype, string species, float length, IList siblings, IDictionary serializedAdditionalRawData) { Fishtype = fishtype; Species = species; Length = length; Siblings = siblings; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Fish() + { } /// Gets or sets the fishtype. diff --git a/test/TestServerProjects/body-complex/Generated/Models/FloatWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/FloatWrapper.Serialization.cs index 016470a72b5..7bc0c35731b 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/FloatWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/FloatWrapper.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class FloatWrapper : IUtf8JsonSerializable + public partial class FloatWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(FloatWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Field1)) { @@ -25,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("field2"u8); writer.WriteNumberValue(Field2.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static FloatWrapper DeserializeFloatWrapper(JsonElement element) + FloatWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(FloatWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeFloatWrapper(document.RootElement, options); + } + + internal static FloatWrapper DeserializeFloatWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional field1 = default; Optional field2 = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field1"u8)) @@ -56,8 +98,44 @@ internal static FloatWrapper DeserializeFloatWrapper(JsonElement element) field2 = property.Value.GetSingle(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new FloatWrapper(Optional.ToNullable(field1), Optional.ToNullable(field2)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new FloatWrapper(Optional.ToNullable(field1), Optional.ToNullable(field2), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(FloatWrapper)} does not support '{options.Format}' format."); + } + } + + FloatWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeFloatWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(FloatWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/FloatWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/FloatWrapper.cs index ab05258e343..aa5c9fd5c68 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/FloatWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/FloatWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The FloatWrapper. public partial class FloatWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public FloatWrapper() { @@ -18,10 +53,12 @@ public FloatWrapper() /// Initializes a new instance of . /// /// - internal FloatWrapper(float? field1, float? field2) + /// Keeps track of any properties unknown to the library. + internal FloatWrapper(float? field1, float? field2, IDictionary serializedAdditionalRawData) { Field1 = field1; Field2 = field2; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field 1. diff --git a/test/TestServerProjects/body-complex/Generated/Models/Goblinshark.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Goblinshark.Serialization.cs index f18b1354400..73992298793 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Goblinshark.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Goblinshark.Serialization.cs @@ -6,16 +6,25 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Goblinshark : IUtf8JsonSerializable + public partial class Goblinshark : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Goblinshark)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Jawsize)) { @@ -53,11 +62,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Goblinshark DeserializeGoblinshark(JsonElement element) + Goblinshark IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Goblinshark)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeGoblinshark(document.RootElement, options); + } + + internal static Goblinshark DeserializeGoblinshark(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -70,6 +108,8 @@ internal static Goblinshark DeserializeGoblinshark(JsonElement element) Optional species = default; float length = default; Optional> siblings = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("jawsize"u8)) @@ -133,8 +173,44 @@ internal static Goblinshark DeserializeGoblinshark(JsonElement element) siblings = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Goblinshark(fishtype, species.Value, length, Optional.ToList(siblings), Optional.ToNullable(age), birthday, Optional.ToNullable(jawsize), Optional.ToNullable(color)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Goblinshark(fishtype, species.Value, length, Optional.ToList(siblings), serializedAdditionalRawData, Optional.ToNullable(age), birthday, Optional.ToNullable(jawsize), Optional.ToNullable(color)); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Goblinshark)} does not support '{options.Format}' format."); + } + } + + Goblinshark IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeGoblinshark(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Goblinshark)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Goblinshark.cs b/test/TestServerProjects/body-complex/Generated/Models/Goblinshark.cs index 7391a89fc8f..f3382a44fc1 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Goblinshark.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Goblinshark.cs @@ -29,17 +29,23 @@ public Goblinshark(float length, DateTimeOffset birthday) : base(length, birthda /// Please note is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes. /// The available derived classes include , , , , and . /// + /// Keeps track of any properties unknown to the library. /// /// /// /// Colors possible. - internal Goblinshark(string fishtype, string species, float length, IList siblings, int? age, DateTimeOffset birthday, int? jawsize, GoblinSharkColor? color) : base(fishtype, species, length, siblings, age, birthday) + internal Goblinshark(string fishtype, string species, float length, IList siblings, IDictionary serializedAdditionalRawData, int? age, DateTimeOffset birthday, int? jawsize, GoblinSharkColor? color) : base(fishtype, species, length, siblings, serializedAdditionalRawData, age, birthday) { Jawsize = jawsize; Color = color; Fishtype = fishtype ?? "goblin"; } + /// Initializes a new instance of for deserialization. + internal Goblinshark() + { + } + /// Gets or sets the jawsize. public int? Jawsize { get; set; } /// Colors possible. diff --git a/test/TestServerProjects/body-complex/Generated/Models/IntWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/IntWrapper.Serialization.cs index ff5d2489a96..e449b9d673f 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/IntWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/IntWrapper.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class IntWrapper : IUtf8JsonSerializable + public partial class IntWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IntWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Field1)) { @@ -25,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("field2"u8); writer.WriteNumberValue(Field2.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static IntWrapper DeserializeIntWrapper(JsonElement element) + IntWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IntWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIntWrapper(document.RootElement, options); + } + + internal static IntWrapper DeserializeIntWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional field1 = default; Optional field2 = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field1"u8)) @@ -56,8 +98,44 @@ internal static IntWrapper DeserializeIntWrapper(JsonElement element) field2 = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new IntWrapper(Optional.ToNullable(field1), Optional.ToNullable(field2)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new IntWrapper(Optional.ToNullable(field1), Optional.ToNullable(field2), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IntWrapper)} does not support '{options.Format}' format."); + } + } + + IntWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIntWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IntWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/IntWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/IntWrapper.cs index 566a63d0d64..7c03a621cf9 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/IntWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/IntWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The IntWrapper. public partial class IntWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public IntWrapper() { @@ -18,10 +53,12 @@ public IntWrapper() /// Initializes a new instance of . /// /// - internal IntWrapper(int? field1, int? field2) + /// Keeps track of any properties unknown to the library. + internal IntWrapper(int? field1, int? field2, IDictionary serializedAdditionalRawData) { Field1 = field1; Field2 = field2; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field 1. diff --git a/test/TestServerProjects/body-complex/Generated/Models/LongWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/LongWrapper.Serialization.cs index 4bd9bcb7bff..8939c2c929b 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/LongWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/LongWrapper.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class LongWrapper : IUtf8JsonSerializable + public partial class LongWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(LongWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Field1)) { @@ -25,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("field2"u8); writer.WriteNumberValue(Field2.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static LongWrapper DeserializeLongWrapper(JsonElement element) + LongWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(LongWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeLongWrapper(document.RootElement, options); + } + + internal static LongWrapper DeserializeLongWrapper(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional field1 = default; Optional field2 = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field1"u8)) @@ -56,8 +98,44 @@ internal static LongWrapper DeserializeLongWrapper(JsonElement element) field2 = property.Value.GetInt64(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new LongWrapper(Optional.ToNullable(field1), Optional.ToNullable(field2)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new LongWrapper(Optional.ToNullable(field1), Optional.ToNullable(field2), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(LongWrapper)} does not support '{options.Format}' format."); + } + } + + LongWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeLongWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(LongWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/LongWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/LongWrapper.cs index 779f55d48a5..77526032e9b 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/LongWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/LongWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The LongWrapper. public partial class LongWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public LongWrapper() { @@ -18,10 +53,12 @@ public LongWrapper() /// Initializes a new instance of . /// /// - internal LongWrapper(long? field1, long? field2) + /// Keeps track of any properties unknown to the library. + internal LongWrapper(long? field1, long? field2, IDictionary serializedAdditionalRawData) { Field1 = field1; Field2 = field2; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field 1. diff --git a/test/TestServerProjects/body-complex/Generated/Models/MyBaseType.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/MyBaseType.Serialization.cs index 91d255535e6..5ae2a9fc0c1 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/MyBaseType.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/MyBaseType.Serialization.cs @@ -5,14 +5,76 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; +using Azure.Core; namespace body_complex.Models { - public partial class MyBaseType + [PersistableModelProxy(typeof(UnknownMyBaseType))] + public partial class MyBaseType : IUtf8JsonSerializable, IJsonModel { - internal static MyBaseType DeserializeMyBaseType(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MyBaseType)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind.ToString()); + if (Optional.IsDefined(PropB1)) + { + writer.WritePropertyName("propB1"u8); + writer.WriteStringValue(PropB1); + } + writer.WritePropertyName("helper"u8); + writer.WriteStartObject(); + if (Optional.IsDefined(PropBH1)) + { + writer.WritePropertyName("propBH1"u8); + writer.WriteStringValue(PropBH1); + } + writer.WriteEndObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + MyBaseType IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MyBaseType)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeMyBaseType(document.RootElement, options); + } + + internal static MyBaseType DeserializeMyBaseType(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -26,5 +88,36 @@ internal static MyBaseType DeserializeMyBaseType(JsonElement element) } return UnknownMyBaseType.DeserializeUnknownMyBaseType(element); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(MyBaseType)} does not support '{options.Format}' format."); + } + } + + MyBaseType IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeMyBaseType(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(MyBaseType)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/MyBaseType.cs b/test/TestServerProjects/body-complex/Generated/Models/MyBaseType.cs index d7932f6d4bc..17ef8ee2657 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/MyBaseType.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/MyBaseType.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// @@ -14,6 +17,38 @@ namespace body_complex.Models /// public abstract partial class MyBaseType { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . protected MyBaseType() { @@ -23,11 +58,13 @@ protected MyBaseType() /// /// /// - internal MyBaseType(MyKind kind, string propB1, string propBH1) + /// Keeps track of any properties unknown to the library. + internal MyBaseType(MyKind kind, string propB1, string propBH1, IDictionary serializedAdditionalRawData) { Kind = kind; PropB1 = propB1; PropBH1 = propBH1; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the kind. diff --git a/test/TestServerProjects/body-complex/Generated/Models/MyDerivedType.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/MyDerivedType.Serialization.cs index e8971cbff0e..74dad026fa7 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/MyDerivedType.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/MyDerivedType.Serialization.cs @@ -5,15 +5,81 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class MyDerivedType + public partial class MyDerivedType : IUtf8JsonSerializable, IJsonModel { - internal static MyDerivedType DeserializeMyDerivedType(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MyDerivedType)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(PropD1)) + { + writer.WritePropertyName("propD1"u8); + writer.WriteStringValue(PropD1); + } + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind.ToString()); + if (Optional.IsDefined(PropB1)) + { + writer.WritePropertyName("propB1"u8); + writer.WriteStringValue(PropB1); + } + writer.WritePropertyName("helper"u8); + writer.WriteStartObject(); + if (Optional.IsDefined(PropBH1)) + { + writer.WritePropertyName("propBH1"u8); + writer.WriteStringValue(PropBH1); + } + writer.WriteEndObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + MyDerivedType IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MyDerivedType)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeMyDerivedType(document.RootElement, options); + } + + internal static MyDerivedType DeserializeMyDerivedType(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -22,6 +88,8 @@ internal static MyDerivedType DeserializeMyDerivedType(JsonElement element) MyKind kind = default; Optional propB1 = default; Optional propBH1 = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("propD1"u8)) @@ -56,8 +124,44 @@ internal static MyDerivedType DeserializeMyDerivedType(JsonElement element) } continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new MyDerivedType(kind, propB1.Value, propBH1.Value, propD1.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new MyDerivedType(kind, propB1.Value, propBH1.Value, serializedAdditionalRawData, propD1.Value); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(MyDerivedType)} does not support '{options.Format}' format."); + } + } + + MyDerivedType IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeMyDerivedType(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(MyDerivedType)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/MyDerivedType.cs b/test/TestServerProjects/body-complex/Generated/Models/MyDerivedType.cs index 664cbe65651..adeaaa8f9fa 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/MyDerivedType.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/MyDerivedType.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The MyDerivedType. @@ -20,8 +23,9 @@ internal MyDerivedType() /// /// /// + /// Keeps track of any properties unknown to the library. /// - internal MyDerivedType(MyKind kind, string propB1, string propBH1, string propD1) : base(kind, propB1, propBH1) + internal MyDerivedType(MyKind kind, string propB1, string propBH1, IDictionary serializedAdditionalRawData, string propD1) : base(kind, propB1, propBH1, serializedAdditionalRawData) { PropD1 = propD1; Kind = kind; diff --git a/test/TestServerProjects/body-complex/Generated/Models/Pet.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Pet.Serialization.cs index e7004f43cd3..7cb191b68d9 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Pet.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Pet.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Pet : IUtf8JsonSerializable + public partial class Pet : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Id)) { @@ -25,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Pet DeserializePet(JsonElement element) + Pet IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePet(document.RootElement, options); + } + + internal static Pet DeserializePet(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional id = default; Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -52,8 +94,44 @@ internal static Pet DeserializePet(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Pet(Optional.ToNullable(id), name.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Pet(Optional.ToNullable(id), name.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Pet)} does not support '{options.Format}' format."); + } + } + + Pet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePet(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Pet)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Pet.cs b/test/TestServerProjects/body-complex/Generated/Models/Pet.cs index c91cbe99932..579b5c6be73 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Pet.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Pet.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The Pet. public partial class Pet { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Pet() { @@ -18,10 +53,12 @@ public Pet() /// Initializes a new instance of . /// /// - internal Pet(int? id, string name) + /// Keeps track of any properties unknown to the library. + internal Pet(int? id, string name, IDictionary serializedAdditionalRawData) { Id = id; Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the id. diff --git a/test/TestServerProjects/body-complex/Generated/Models/ReadonlyObj.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/ReadonlyObj.Serialization.cs index 2d7c0063367..dda5098ceef 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/ReadonlyObj.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/ReadonlyObj.Serialization.cs @@ -5,32 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class ReadonlyObj : IUtf8JsonSerializable + public partial class ReadonlyObj : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ReadonlyObj)} does not support '{format}' format."); + } + writer.WriteStartObject(); + if (options.Format != "W" && Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } if (Optional.IsDefined(Size)) { writer.WritePropertyName("size"u8); writer.WriteNumberValue(Size.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ReadonlyObj DeserializeReadonlyObj(JsonElement element) + ReadonlyObj IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ReadonlyObj)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeReadonlyObj(document.RootElement, options); + } + + internal static ReadonlyObj DeserializeReadonlyObj(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional id = default; Optional size = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -47,8 +94,44 @@ internal static ReadonlyObj DeserializeReadonlyObj(JsonElement element) size = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ReadonlyObj(id.Value, Optional.ToNullable(size), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ReadonlyObj)} does not support '{options.Format}' format."); } - return new ReadonlyObj(id.Value, Optional.ToNullable(size)); } + + ReadonlyObj IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeReadonlyObj(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ReadonlyObj)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/ReadonlyObj.cs b/test/TestServerProjects/body-complex/Generated/Models/ReadonlyObj.cs index c0a34b1f4f9..30cfbc512f1 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/ReadonlyObj.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/ReadonlyObj.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The ReadonlyObj. public partial class ReadonlyObj { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ReadonlyObj() { @@ -18,10 +53,12 @@ public ReadonlyObj() /// Initializes a new instance of . /// /// - internal ReadonlyObj(string id, int? size) + /// Keeps track of any properties unknown to the library. + internal ReadonlyObj(string id, int? size, IDictionary serializedAdditionalRawData) { Id = id; Size = size; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the id. diff --git a/test/TestServerProjects/body-complex/Generated/Models/Salmon.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Salmon.Serialization.cs index 524ffc59657..43f19d144f6 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Salmon.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Salmon.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Salmon : IUtf8JsonSerializable + public partial class Salmon : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Salmon)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Location)) { @@ -45,11 +55,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Salmon DeserializeSalmon(JsonElement element) + Salmon IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Salmon)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSalmon(document.RootElement, options); + } + + internal static Salmon DeserializeSalmon(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -67,6 +106,8 @@ internal static Salmon DeserializeSalmon(JsonElement element) Optional species = default; float length = default; Optional> siblings = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("location"u8)) @@ -112,8 +153,44 @@ internal static Salmon DeserializeSalmon(JsonElement element) siblings = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Salmon(fishtype, species.Value, length, Optional.ToList(siblings), location.Value, Optional.ToNullable(iswild)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Salmon(fishtype, species.Value, length, Optional.ToList(siblings), serializedAdditionalRawData, location.Value, Optional.ToNullable(iswild)); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Salmon)} does not support '{options.Format}' format."); + } + } + + Salmon IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSalmon(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Salmon)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Salmon.cs b/test/TestServerProjects/body-complex/Generated/Models/Salmon.cs index 25f3542a8be..ab97864ab4f 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Salmon.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Salmon.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; namespace body_complex.Models @@ -31,15 +32,21 @@ public Salmon(float length) : base(length) /// Please note is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes. /// The available derived classes include , , , , and . /// + /// Keeps track of any properties unknown to the library. /// /// - internal Salmon(string fishtype, string species, float length, IList siblings, string location, bool? iswild) : base(fishtype, species, length, siblings) + internal Salmon(string fishtype, string species, float length, IList siblings, IDictionary serializedAdditionalRawData, string location, bool? iswild) : base(fishtype, species, length, siblings, serializedAdditionalRawData) { Location = location; Iswild = iswild; Fishtype = fishtype ?? "salmon"; } + /// Initializes a new instance of for deserialization. + internal Salmon() + { + } + /// Gets or sets the location. public string Location { get; set; } /// Gets or sets the iswild. diff --git a/test/TestServerProjects/body-complex/Generated/Models/Sawshark.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Sawshark.Serialization.cs index a62ea52c43f..3ad62cf0405 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Sawshark.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Sawshark.Serialization.cs @@ -6,16 +6,25 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Sawshark : IUtf8JsonSerializable + public partial class Sawshark : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Sawshark)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Picture)) { @@ -48,11 +57,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Sawshark DeserializeSawshark(JsonElement element) + Sawshark IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Sawshark)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSawshark(document.RootElement, options); + } + + internal static Sawshark DeserializeSawshark(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -64,6 +102,8 @@ internal static Sawshark DeserializeSawshark(JsonElement element) Optional species = default; float length = default; Optional> siblings = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("picture"u8)) @@ -118,8 +158,44 @@ internal static Sawshark DeserializeSawshark(JsonElement element) siblings = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Sawshark(fishtype, species.Value, length, Optional.ToList(siblings), Optional.ToNullable(age), birthday, picture.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Sawshark(fishtype, species.Value, length, Optional.ToList(siblings), serializedAdditionalRawData, Optional.ToNullable(age), birthday, picture.Value); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Sawshark)} does not support '{options.Format}' format."); + } + } + + Sawshark IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSawshark(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Sawshark)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Sawshark.cs b/test/TestServerProjects/body-complex/Generated/Models/Sawshark.cs index b1a6f7f4478..bb2b0f3cdf0 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Sawshark.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Sawshark.cs @@ -29,15 +29,21 @@ public Sawshark(float length, DateTimeOffset birthday) : base(length, birthday) /// Please note is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes. /// The available derived classes include , , , , and . /// + /// Keeps track of any properties unknown to the library. /// /// /// - internal Sawshark(string fishtype, string species, float length, IList siblings, int? age, DateTimeOffset birthday, byte[] picture) : base(fishtype, species, length, siblings, age, birthday) + internal Sawshark(string fishtype, string species, float length, IList siblings, IDictionary serializedAdditionalRawData, int? age, DateTimeOffset birthday, byte[] picture) : base(fishtype, species, length, siblings, serializedAdditionalRawData, age, birthday) { Picture = picture; Fishtype = fishtype ?? "sawshark"; } + /// Initializes a new instance of for deserialization. + internal Sawshark() + { + } + /// Gets or sets the picture. public byte[] Picture { get; set; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Shark.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Shark.Serialization.cs index 07900710d3a..89cdcdeada7 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Shark.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Shark.Serialization.cs @@ -6,16 +6,25 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Shark : IUtf8JsonSerializable + public partial class Shark : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Shark)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Age)) { @@ -43,11 +52,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Shark DeserializeShark(JsonElement element) + Shark IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Shark)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeShark(document.RootElement, options); + } + + internal static Shark DeserializeShark(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -67,6 +105,8 @@ internal static Shark DeserializeShark(JsonElement element) Optional species = default; float length = default; Optional> siblings = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("age"u8)) @@ -112,8 +152,44 @@ internal static Shark DeserializeShark(JsonElement element) siblings = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Shark(fishtype, species.Value, length, Optional.ToList(siblings), Optional.ToNullable(age), birthday); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Shark(fishtype, species.Value, length, Optional.ToList(siblings), serializedAdditionalRawData, Optional.ToNullable(age), birthday); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Shark)} does not support '{options.Format}' format."); + } + } + + Shark IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeShark(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Shark)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Shark.cs b/test/TestServerProjects/body-complex/Generated/Models/Shark.cs index adcd7022593..39d47cc6206 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Shark.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Shark.cs @@ -34,15 +34,21 @@ public Shark(float length, DateTimeOffset birthday) : base(length) /// Please note is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes. /// The available derived classes include , , , , and . /// + /// Keeps track of any properties unknown to the library. /// /// - internal Shark(string fishtype, string species, float length, IList siblings, int? age, DateTimeOffset birthday) : base(fishtype, species, length, siblings) + internal Shark(string fishtype, string species, float length, IList siblings, IDictionary serializedAdditionalRawData, int? age, DateTimeOffset birthday) : base(fishtype, species, length, siblings, serializedAdditionalRawData) { Age = age; Birthday = birthday; Fishtype = fishtype ?? "shark"; } + /// Initializes a new instance of for deserialization. + internal Shark() + { + } + /// Gets or sets the age. public int? Age { get; set; } /// Gets or sets the birthday. diff --git a/test/TestServerProjects/body-complex/Generated/Models/Siamese.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/Siamese.Serialization.cs index 613bc12bc5c..1f824121273 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Siamese.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Siamese.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class Siamese : IUtf8JsonSerializable + public partial class Siamese : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Siamese)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Breed)) { @@ -46,11 +56,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Siamese DeserializeSiamese(JsonElement element) + Siamese IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Siamese)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSiamese(document.RootElement, options); + } + + internal static Siamese DeserializeSiamese(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -60,6 +99,8 @@ internal static Siamese DeserializeSiamese(JsonElement element) Optional> hates = default; Optional id = default; Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("breed"u8)) @@ -100,8 +141,44 @@ internal static Siamese DeserializeSiamese(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Siamese(Optional.ToNullable(id), name.Value, color.Value, Optional.ToList(hates), breed.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Siamese(Optional.ToNullable(id), name.Value, serializedAdditionalRawData, color.Value, Optional.ToList(hates), breed.Value); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Siamese)} does not support '{options.Format}' format."); + } + } + + Siamese IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSiamese(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Siamese)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/Siamese.cs b/test/TestServerProjects/body-complex/Generated/Models/Siamese.cs index aa80b00b60d..f38a91c20de 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/Siamese.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/Siamese.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; namespace body_complex.Models @@ -20,10 +21,11 @@ public Siamese() /// Initializes a new instance of . /// /// + /// Keeps track of any properties unknown to the library. /// /// /// - internal Siamese(int? id, string name, string color, IList hates, string breed) : base(id, name, color, hates) + internal Siamese(int? id, string name, IDictionary serializedAdditionalRawData, string color, IList hates, string breed) : base(id, name, serializedAdditionalRawData, color, hates) { Breed = breed; } diff --git a/test/TestServerProjects/body-complex/Generated/Models/SmartSalmon.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/SmartSalmon.Serialization.cs index 66c709a72b2..e4c63cda4f0 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/SmartSalmon.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/SmartSalmon.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class SmartSalmon : IUtf8JsonSerializable + public partial class SmartSalmon : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SmartSalmon)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(CollegeDegree)) { @@ -58,8 +68,22 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteEndObject(); } - internal static SmartSalmon DeserializeSmartSalmon(JsonElement element) + SmartSalmon IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SmartSalmon)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSmartSalmon(document.RootElement, options); + } + + internal static SmartSalmon DeserializeSmartSalmon(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -128,5 +152,36 @@ internal static SmartSalmon DeserializeSmartSalmon(JsonElement element) additionalProperties = additionalPropertiesDictionary; return new SmartSalmon(fishtype, species.Value, length, Optional.ToList(siblings), location.Value, Optional.ToNullable(iswild), collegeDegree.Value, additionalProperties); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(SmartSalmon)} does not support '{options.Format}' format."); + } + } + + SmartSalmon IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSmartSalmon(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SmartSalmon)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/SmartSalmon.cs b/test/TestServerProjects/body-complex/Generated/Models/SmartSalmon.cs index c4110f7305d..3427feea351 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/SmartSalmon.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/SmartSalmon.cs @@ -33,13 +33,18 @@ public SmartSalmon(float length) : base(length) /// /// /// Additional Properties. - internal SmartSalmon(string fishtype, string species, float length, IList siblings, string location, bool? iswild, string collegeDegree, IDictionary additionalProperties) : base(fishtype, species, length, siblings, location, iswild) + internal SmartSalmon(string fishtype, string species, float length, IList siblings, string location, bool? iswild, string collegeDegree, IDictionary additionalProperties) : base(fishtype, species, length, siblings, null, location, iswild) { CollegeDegree = collegeDegree; AdditionalProperties = additionalProperties; Fishtype = fishtype ?? "smart_salmon"; } + /// Initializes a new instance of for deserialization. + internal SmartSalmon() + { + } + /// Gets or sets the college degree. public string CollegeDegree { get; set; } /// Additional Properties. diff --git a/test/TestServerProjects/body-complex/Generated/Models/StringWrapper.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/StringWrapper.Serialization.cs index 239022c5790..ff7af9e17b4 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/StringWrapper.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/StringWrapper.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - public partial class StringWrapper : IUtf8JsonSerializable + public partial class StringWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(StringWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Field)) { @@ -30,11 +41,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("null"u8); writer.WriteStringValue(NullProperty); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static StringWrapper DeserializeStringWrapper(JsonElement element) + StringWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(StringWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeStringWrapper(document.RootElement, options); + } + + internal static StringWrapper DeserializeStringWrapper(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -42,6 +82,8 @@ internal static StringWrapper DeserializeStringWrapper(JsonElement element) Optional field = default; Optional empty = default; Optional @null = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("field"u8)) @@ -59,8 +101,44 @@ internal static StringWrapper DeserializeStringWrapper(JsonElement element) @null = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new StringWrapper(field.Value, empty.Value, @null.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(StringWrapper)} does not support '{options.Format}' format."); } - return new StringWrapper(field.Value, empty.Value, @null.Value); } + + StringWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeStringWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(StringWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/StringWrapper.cs b/test/TestServerProjects/body-complex/Generated/Models/StringWrapper.cs index 8c9b1d48a52..d8395d93f42 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/StringWrapper.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/StringWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The StringWrapper. public partial class StringWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public StringWrapper() { @@ -19,11 +54,13 @@ public StringWrapper() /// /// /// - internal StringWrapper(string field, string empty, string nullProperty) + /// Keeps track of any properties unknown to the library. + internal StringWrapper(string field, string empty, string nullProperty, IDictionary serializedAdditionalRawData) { Field = field; Empty = empty; NullProperty = nullProperty; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the field. diff --git a/test/TestServerProjects/body-complex/Generated/Models/UnknownDotFish.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/UnknownDotFish.Serialization.cs index ff427085172..4e8328b0322 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/UnknownDotFish.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/UnknownDotFish.Serialization.cs @@ -5,21 +5,76 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - internal partial class UnknownDotFish + internal partial class UnknownDotFish : IUtf8JsonSerializable, IJsonModel { - internal static UnknownDotFish DeserializeUnknownDotFish(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DotFish)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("fish.type"u8); + writer.WriteStringValue(FishType); + if (Optional.IsDefined(Species)) + { + writer.WritePropertyName("species"u8); + writer.WriteStringValue(Species); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + DotFish IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(DotFish)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownDotFish(document.RootElement, options); + } + + internal static UnknownDotFish DeserializeUnknownDotFish(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } string fishType = "Unknown"; Optional species = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("fish.type"u8)) @@ -32,8 +87,44 @@ internal static UnknownDotFish DeserializeUnknownDotFish(JsonElement element) species = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new UnknownDotFish(fishType, species.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new UnknownDotFish(fishType, species.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(DotFish)} does not support '{options.Format}' format."); + } + } + + DotFish IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownDotFish(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(DotFish)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/UnknownDotFish.cs b/test/TestServerProjects/body-complex/Generated/Models/UnknownDotFish.cs index e5b72862966..dbe88d682b9 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/UnknownDotFish.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/UnknownDotFish.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The UnknownDotFish. @@ -13,7 +16,8 @@ internal partial class UnknownDotFish : DotFish /// Initializes a new instance of . /// /// - internal UnknownDotFish(string fishType, string species) : base(fishType, species) + /// Keeps track of any properties unknown to the library. + internal UnknownDotFish(string fishType, string species, IDictionary serializedAdditionalRawData) : base(fishType, species, serializedAdditionalRawData) { FishType = fishType ?? "Unknown"; } diff --git a/test/TestServerProjects/body-complex/Generated/Models/UnknownFish.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/UnknownFish.Serialization.cs index 0e7a5cdbeff..e8410b0b423 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/UnknownFish.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/UnknownFish.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - internal partial class UnknownFish : IUtf8JsonSerializable + internal partial class UnknownFish : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Fish)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("fishtype"u8); writer.WriteStringValue(Fishtype); @@ -35,11 +45,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static UnknownFish DeserializeUnknownFish(JsonElement element) + Fish IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Fish)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownFish(document.RootElement, options); + } + + internal static UnknownFish DeserializeUnknownFish(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -48,6 +87,8 @@ internal static UnknownFish DeserializeUnknownFish(JsonElement element) Optional species = default; float length = default; Optional> siblings = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("fishtype"u8)) @@ -79,8 +120,44 @@ internal static UnknownFish DeserializeUnknownFish(JsonElement element) siblings = array; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new UnknownFish(fishtype, species.Value, length, Optional.ToList(siblings)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new UnknownFish(fishtype, species.Value, length, Optional.ToList(siblings), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Fish)} does not support '{options.Format}' format."); + } + } + + Fish IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownFish(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Fish)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/UnknownFish.cs b/test/TestServerProjects/body-complex/Generated/Models/UnknownFish.cs index 137e8d918b4..cc386e66e87 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/UnknownFish.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/UnknownFish.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; namespace body_complex.Models @@ -20,9 +21,15 @@ internal partial class UnknownFish : Fish /// Please note is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes. /// The available derived classes include , , , , and . /// - internal UnknownFish(string fishtype, string species, float length, IList siblings) : base(fishtype, species, length, siblings) + /// Keeps track of any properties unknown to the library. + internal UnknownFish(string fishtype, string species, float length, IList siblings, IDictionary serializedAdditionalRawData) : base(fishtype, species, length, siblings, serializedAdditionalRawData) { Fishtype = fishtype ?? "Unknown"; } + + /// Initializes a new instance of for deserialization. + internal UnknownFish() + { + } } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/UnknownMyBaseType.Serialization.cs b/test/TestServerProjects/body-complex/Generated/Models/UnknownMyBaseType.Serialization.cs index b61aa1ac0f7..6742e5142d7 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/UnknownMyBaseType.Serialization.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/UnknownMyBaseType.Serialization.cs @@ -5,15 +5,76 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_complex.Models { - internal partial class UnknownMyBaseType + internal partial class UnknownMyBaseType : IUtf8JsonSerializable, IJsonModel { - internal static UnknownMyBaseType DeserializeUnknownMyBaseType(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MyBaseType)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind.ToString()); + if (Optional.IsDefined(PropB1)) + { + writer.WritePropertyName("propB1"u8); + writer.WriteStringValue(PropB1); + } + writer.WritePropertyName("helper"u8); + writer.WriteStartObject(); + if (Optional.IsDefined(PropBH1)) + { + writer.WritePropertyName("propBH1"u8); + writer.WriteStringValue(PropBH1); + } + writer.WriteEndObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + MyBaseType IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MyBaseType)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownMyBaseType(document.RootElement, options); + } + + internal static UnknownMyBaseType DeserializeUnknownMyBaseType(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -21,6 +82,8 @@ internal static UnknownMyBaseType DeserializeUnknownMyBaseType(JsonElement eleme MyKind kind = "Unknown"; Optional propB1 = default; Optional propBH1 = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("kind"u8)) @@ -50,8 +113,44 @@ internal static UnknownMyBaseType DeserializeUnknownMyBaseType(JsonElement eleme } continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new UnknownMyBaseType(kind, propB1.Value, propBH1.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(MyBaseType)} does not support '{options.Format}' format."); + } + } + + MyBaseType IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownMyBaseType(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(MyBaseType)} does not support '{options.Format}' format."); } - return new UnknownMyBaseType(kind, propB1.Value, propBH1.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-complex/Generated/Models/UnknownMyBaseType.cs b/test/TestServerProjects/body-complex/Generated/Models/UnknownMyBaseType.cs index 76756d72f25..b31b41f7705 100644 --- a/test/TestServerProjects/body-complex/Generated/Models/UnknownMyBaseType.cs +++ b/test/TestServerProjects/body-complex/Generated/Models/UnknownMyBaseType.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_complex.Models { /// The UnknownMyBaseType. @@ -14,7 +17,8 @@ internal partial class UnknownMyBaseType : MyBaseType /// /// /// - internal UnknownMyBaseType(MyKind kind, string propB1, string propBH1) : base(kind, propB1, propBH1) + /// Keeps track of any properties unknown to the library. + internal UnknownMyBaseType(MyKind kind, string propB1, string propBH1, IDictionary serializedAdditionalRawData) : base(kind, propB1, propBH1, serializedAdditionalRawData) { Kind = kind; } diff --git a/test/TestServerProjects/body-complex/body_complex.csproj b/test/TestServerProjects/body-complex/body_complex.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-complex/body_complex.csproj +++ b/test/TestServerProjects/body-complex/body_complex.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-date/Generated/Configuration.json b/test/TestServerProjects/body-date/Generated/Configuration.json index 48a8664adb2..a6784900248 100644 --- a/test/TestServerProjects/body-date/Generated/Configuration.json +++ b/test/TestServerProjects/body-date/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-date/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-date/Generated/Models/Error.Serialization.cs index 0753c8984cd..cb39a59ec73 100644 --- a/test/TestServerProjects/body-date/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-date/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_date.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-date/Generated/Models/Error.cs b/test/TestServerProjects/body-date/Generated/Models/Error.cs index 436da9affb2..702b0ac3288 100644 --- a/test/TestServerProjects/body-date/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-date/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_date.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-date/body_date.csproj b/test/TestServerProjects/body-date/body_date.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-date/body_date.csproj +++ b/test/TestServerProjects/body-date/body_date.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-datetime-rfc1123/Generated/Configuration.json b/test/TestServerProjects/body-datetime-rfc1123/Generated/Configuration.json index b47673abefd..4b72ed988c1 100644 --- a/test/TestServerProjects/body-datetime-rfc1123/Generated/Configuration.json +++ b/test/TestServerProjects/body-datetime-rfc1123/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-datetime-rfc1123/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-datetime-rfc1123/Generated/Models/Error.Serialization.cs index d5bdcbd1500..62d6af5f690 100644 --- a/test/TestServerProjects/body-datetime-rfc1123/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-datetime-rfc1123/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_datetime_rfc1123.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-datetime-rfc1123/Generated/Models/Error.cs b/test/TestServerProjects/body-datetime-rfc1123/Generated/Models/Error.cs index ac151586cdf..1490fe0232b 100644 --- a/test/TestServerProjects/body-datetime-rfc1123/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-datetime-rfc1123/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_datetime_rfc1123.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-datetime-rfc1123/body_datetime_rfc1123.csproj b/test/TestServerProjects/body-datetime-rfc1123/body_datetime_rfc1123.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-datetime-rfc1123/body_datetime_rfc1123.csproj +++ b/test/TestServerProjects/body-datetime-rfc1123/body_datetime_rfc1123.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-datetime/Generated/Configuration.json b/test/TestServerProjects/body-datetime/Generated/Configuration.json index 9e7f1bf8d11..3b13f3a28e1 100644 --- a/test/TestServerProjects/body-datetime/Generated/Configuration.json +++ b/test/TestServerProjects/body-datetime/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-datetime/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-datetime/Generated/Models/Error.Serialization.cs index 4fd0b924ace..f7b7df2f2ad 100644 --- a/test/TestServerProjects/body-datetime/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-datetime/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_datetime.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-datetime/Generated/Models/Error.cs b/test/TestServerProjects/body-datetime/Generated/Models/Error.cs index 3ff47f53ec4..02abda43a05 100644 --- a/test/TestServerProjects/body-datetime/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-datetime/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_datetime.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-datetime/body_datetime.csproj b/test/TestServerProjects/body-datetime/body_datetime.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-datetime/body_datetime.csproj +++ b/test/TestServerProjects/body-datetime/body_datetime.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-dictionary/Generated/Configuration.json b/test/TestServerProjects/body-dictionary/Generated/Configuration.json index 5538b646d1d..1732e8a3ef9 100644 --- a/test/TestServerProjects/body-dictionary/Generated/Configuration.json +++ b/test/TestServerProjects/body-dictionary/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-dictionary/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-dictionary/Generated/Models/Error.Serialization.cs index 337d2127715..955564a4f2f 100644 --- a/test/TestServerProjects/body-dictionary/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-dictionary/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_dictionary.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-dictionary/Generated/Models/Error.cs b/test/TestServerProjects/body-dictionary/Generated/Models/Error.cs index 8b35011572f..f4e76bd66a2 100644 --- a/test/TestServerProjects/body-dictionary/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-dictionary/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_dictionary.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-dictionary/Generated/Models/Widget.Serialization.cs b/test/TestServerProjects/body-dictionary/Generated/Models/Widget.Serialization.cs index c5301ee1ba3..cedc236d4b8 100644 --- a/test/TestServerProjects/body-dictionary/Generated/Models/Widget.Serialization.cs +++ b/test/TestServerProjects/body-dictionary/Generated/Models/Widget.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_dictionary.Models { - public partial class Widget : IUtf8JsonSerializable + public partial class Widget : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Widget)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Integer)) { @@ -25,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("string"u8); writer.WriteStringValue(String); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Widget DeserializeWidget(JsonElement element) + Widget IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Widget)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeWidget(document.RootElement, options); + } + + internal static Widget DeserializeWidget(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional integer = default; Optional @string = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("integer"u8)) @@ -52,8 +94,44 @@ internal static Widget DeserializeWidget(JsonElement element) @string = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Widget(Optional.ToNullable(integer), @string.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Widget(Optional.ToNullable(integer), @string.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Widget)} does not support '{options.Format}' format."); + } + } + + Widget IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeWidget(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Widget)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-dictionary/Generated/Models/Widget.cs b/test/TestServerProjects/body-dictionary/Generated/Models/Widget.cs index b44e1d4883f..50dd1ef7578 100644 --- a/test/TestServerProjects/body-dictionary/Generated/Models/Widget.cs +++ b/test/TestServerProjects/body-dictionary/Generated/Models/Widget.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_dictionary.Models { /// The Widget. public partial class Widget { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Widget() { @@ -18,10 +53,12 @@ public Widget() /// Initializes a new instance of . /// /// - internal Widget(int? integer, string @string) + /// Keeps track of any properties unknown to the library. + internal Widget(int? integer, string @string, IDictionary serializedAdditionalRawData) { Integer = integer; String = @string; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the integer. diff --git a/test/TestServerProjects/body-dictionary/body_dictionary.csproj b/test/TestServerProjects/body-dictionary/body_dictionary.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-dictionary/body_dictionary.csproj +++ b/test/TestServerProjects/body-dictionary/body_dictionary.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-duration/Generated/Configuration.json b/test/TestServerProjects/body-duration/Generated/Configuration.json index c01525c0cb0..1f4ac7d07f8 100644 --- a/test/TestServerProjects/body-duration/Generated/Configuration.json +++ b/test/TestServerProjects/body-duration/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-duration/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-duration/Generated/Models/Error.Serialization.cs index dd12ed393b5..0d287f73417 100644 --- a/test/TestServerProjects/body-duration/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-duration/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_duration.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-duration/Generated/Models/Error.cs b/test/TestServerProjects/body-duration/Generated/Models/Error.cs index 5f13782a00b..9d72b2e7cfd 100644 --- a/test/TestServerProjects/body-duration/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-duration/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_duration.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-duration/body_duration.csproj b/test/TestServerProjects/body-duration/body_duration.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-duration/body_duration.csproj +++ b/test/TestServerProjects/body-duration/body_duration.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-file/Generated/Configuration.json b/test/TestServerProjects/body-file/Generated/Configuration.json index f4def0de86b..c1911f0a4ae 100644 --- a/test/TestServerProjects/body-file/Generated/Configuration.json +++ b/test/TestServerProjects/body-file/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-file/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-file/Generated/Models/Error.Serialization.cs index c348e992483..088ca8d8290 100644 --- a/test/TestServerProjects/body-file/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-file/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_file.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-file/Generated/Models/Error.cs b/test/TestServerProjects/body-file/Generated/Models/Error.cs index d72bd78b522..f6d287508c6 100644 --- a/test/TestServerProjects/body-file/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-file/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_file.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-file/body_file.csproj b/test/TestServerProjects/body-file/body_file.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-file/body_file.csproj +++ b/test/TestServerProjects/body-file/body_file.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-formdata-urlencoded/Generated/Configuration.json b/test/TestServerProjects/body-formdata-urlencoded/Generated/Configuration.json index 9505101b381..9a413c8c6c7 100644 --- a/test/TestServerProjects/body-formdata-urlencoded/Generated/Configuration.json +++ b/test/TestServerProjects/body-formdata-urlencoded/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-formdata-urlencoded/Generated/Models/Paths14Hl8BdFormsdataurlencodedPetAddPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema.cs b/test/TestServerProjects/body-formdata-urlencoded/Generated/Models/Paths14Hl8BdFormsdataurlencodedPetAddPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema.cs index cf46de4a147..5c37216dcab 100644 --- a/test/TestServerProjects/body-formdata-urlencoded/Generated/Models/Paths14Hl8BdFormsdataurlencodedPetAddPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema.cs +++ b/test/TestServerProjects/body-formdata-urlencoded/Generated/Models/Paths14Hl8BdFormsdataurlencodedPetAddPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_formdata_urlencoded.Models { /// The Paths14Hl8BdFormsdataurlencodedPetAddPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema. internal partial class Paths14Hl8BdFormsdataurlencodedPetAddPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Can take a value of dog, or cat, or fish. /// Can take a value of meat, or fish, or plant. @@ -27,13 +62,20 @@ internal Paths14Hl8BdFormsdataurlencodedPetAddPetidPostRequestbodyContentApplica /// How many years is it old?. /// Updated name of the pet. /// Updated status of the pet. - internal Paths14Hl8BdFormsdataurlencodedPetAddPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema(PetType petType, PetFood petFood, int petAge, string name, string status) + /// Keeps track of any properties unknown to the library. + internal Paths14Hl8BdFormsdataurlencodedPetAddPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema(PetType petType, PetFood petFood, int petAge, string name, string status, IDictionary serializedAdditionalRawData) { PetType = petType; PetFood = petFood; PetAge = petAge; Name = name; Status = status; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Paths14Hl8BdFormsdataurlencodedPetAddPetidPostRequestbodyContentApplicationXWwwFormUrlencodedSchema() + { } /// Can take a value of dog, or cat, or fish. diff --git a/test/TestServerProjects/body-formdata-urlencoded/Generated/Models/PathsPvivzlFormsdataurlencodedPartialconstantbodyPostRequestbodyContentApplicationXWwwFormUrlencodedSchema.cs b/test/TestServerProjects/body-formdata-urlencoded/Generated/Models/PathsPvivzlFormsdataurlencodedPartialconstantbodyPostRequestbodyContentApplicationXWwwFormUrlencodedSchema.cs index 18e236d10b8..eb506ac402d 100644 --- a/test/TestServerProjects/body-formdata-urlencoded/Generated/Models/PathsPvivzlFormsdataurlencodedPartialconstantbodyPostRequestbodyContentApplicationXWwwFormUrlencodedSchema.cs +++ b/test/TestServerProjects/body-formdata-urlencoded/Generated/Models/PathsPvivzlFormsdataurlencodedPartialconstantbodyPostRequestbodyContentApplicationXWwwFormUrlencodedSchema.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace body_formdata_urlencoded.Models @@ -13,6 +14,38 @@ namespace body_formdata_urlencoded.Models /// The PathsPvivzlFormsdataurlencodedPartialconstantbodyPostRequestbodyContentApplicationXWwwFormUrlencodedSchema. internal partial class PathsPvivzlFormsdataurlencodedPartialconstantbodyPostRequestbodyContentApplicationXWwwFormUrlencodedSchema { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Indicates the name of your Azure container registry. /// AAD access token, mandatory when grant_type is access_token_refresh_token or access_token. @@ -31,11 +64,18 @@ internal PathsPvivzlFormsdataurlencodedPartialconstantbodyPostRequestbodyContent /// Constant part of a formdata body. /// Indicates the name of your Azure container registry. /// AAD access token, mandatory when grant_type is access_token_refresh_token or access_token. - internal PathsPvivzlFormsdataurlencodedPartialconstantbodyPostRequestbodyContentApplicationXWwwFormUrlencodedSchema(PostContentSchemaGrantType grantType, string service, string aadAccessToken) + /// Keeps track of any properties unknown to the library. + internal PathsPvivzlFormsdataurlencodedPartialconstantbodyPostRequestbodyContentApplicationXWwwFormUrlencodedSchema(PostContentSchemaGrantType grantType, string service, string aadAccessToken, IDictionary serializedAdditionalRawData) { GrantType = grantType; Service = service; AadAccessToken = aadAccessToken; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal PathsPvivzlFormsdataurlencodedPartialconstantbodyPostRequestbodyContentApplicationXWwwFormUrlencodedSchema() + { } /// Constant part of a formdata body. diff --git a/test/TestServerProjects/body-formdata-urlencoded/body_formdata_urlencoded.csproj b/test/TestServerProjects/body-formdata-urlencoded/body_formdata_urlencoded.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-formdata-urlencoded/body_formdata_urlencoded.csproj +++ b/test/TestServerProjects/body-formdata-urlencoded/body_formdata_urlencoded.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-formdata/Generated/Configuration.json b/test/TestServerProjects/body-formdata/Generated/Configuration.json index 396af113a84..a180ee71839 100644 --- a/test/TestServerProjects/body-formdata/Generated/Configuration.json +++ b/test/TestServerProjects/body-formdata/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-formdata/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-formdata/Generated/Models/Error.Serialization.cs index af53fa1fb27..b198328e1d8 100644 --- a/test/TestServerProjects/body-formdata/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-formdata/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_formdata.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-formdata/Generated/Models/Error.cs b/test/TestServerProjects/body-formdata/Generated/Models/Error.cs index 440d50e6017..19b952cb7ee 100644 --- a/test/TestServerProjects/body-formdata/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-formdata/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_formdata.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-formdata/Generated/Models/Paths1MqqetpFormdataStreamUploadfilePostRequestbodyContentMultipartFormDataSchema.cs b/test/TestServerProjects/body-formdata/Generated/Models/Paths1MqqetpFormdataStreamUploadfilePostRequestbodyContentMultipartFormDataSchema.cs index 5efd24cb749..531f70cf9ce 100644 --- a/test/TestServerProjects/body-formdata/Generated/Models/Paths1MqqetpFormdataStreamUploadfilePostRequestbodyContentMultipartFormDataSchema.cs +++ b/test/TestServerProjects/body-formdata/Generated/Models/Paths1MqqetpFormdataStreamUploadfilePostRequestbodyContentMultipartFormDataSchema.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using System.IO; using Azure.Core; @@ -14,6 +15,38 @@ namespace body_formdata.Models /// The Paths1MqqetpFormdataStreamUploadfilePostRequestbodyContentMultipartFormDataSchema. internal partial class Paths1MqqetpFormdataStreamUploadfilePostRequestbodyContentMultipartFormDataSchema { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// File to upload. /// File name to upload. Name has to be spelled exactly as written here. @@ -27,6 +60,22 @@ internal Paths1MqqetpFormdataStreamUploadfilePostRequestbodyContentMultipartForm FileName = fileName; } + /// Initializes a new instance of . + /// File to upload. + /// File name to upload. Name has to be spelled exactly as written here. + /// Keeps track of any properties unknown to the library. + internal Paths1MqqetpFormdataStreamUploadfilePostRequestbodyContentMultipartFormDataSchema(Stream fileContent, string fileName, IDictionary serializedAdditionalRawData) + { + FileContent = fileContent; + FileName = fileName; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Paths1MqqetpFormdataStreamUploadfilePostRequestbodyContentMultipartFormDataSchema() + { + } + /// File to upload. public Stream FileContent { get; } /// File name to upload. Name has to be spelled exactly as written here. diff --git a/test/TestServerProjects/body-formdata/Generated/Models/Paths1P3Stk3FormdataStreamUploadfilesPostRequestbodyContentMultipartFormDataSchema.cs b/test/TestServerProjects/body-formdata/Generated/Models/Paths1P3Stk3FormdataStreamUploadfilesPostRequestbodyContentMultipartFormDataSchema.cs index a3e5d8649a5..19ba2124e40 100644 --- a/test/TestServerProjects/body-formdata/Generated/Models/Paths1P3Stk3FormdataStreamUploadfilesPostRequestbodyContentMultipartFormDataSchema.cs +++ b/test/TestServerProjects/body-formdata/Generated/Models/Paths1P3Stk3FormdataStreamUploadfilesPostRequestbodyContentMultipartFormDataSchema.cs @@ -16,6 +16,38 @@ namespace body_formdata.Models /// The Paths1P3Stk3FormdataStreamUploadfilesPostRequestbodyContentMultipartFormDataSchema. internal partial class Paths1P3Stk3FormdataStreamUploadfilesPostRequestbodyContentMultipartFormDataSchema { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Files to upload. /// is null. @@ -28,9 +60,16 @@ internal Paths1P3Stk3FormdataStreamUploadfilesPostRequestbodyContentMultipartFor /// Initializes a new instance of . /// Files to upload. - internal Paths1P3Stk3FormdataStreamUploadfilesPostRequestbodyContentMultipartFormDataSchema(IReadOnlyList fileContent) + /// Keeps track of any properties unknown to the library. + internal Paths1P3Stk3FormdataStreamUploadfilesPostRequestbodyContentMultipartFormDataSchema(IReadOnlyList fileContent, IDictionary serializedAdditionalRawData) { FileContent = fileContent; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Paths1P3Stk3FormdataStreamUploadfilesPostRequestbodyContentMultipartFormDataSchema() + { } /// Files to upload. diff --git a/test/TestServerProjects/body-formdata/body_formdata.csproj b/test/TestServerProjects/body-formdata/body_formdata.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-formdata/body_formdata.csproj +++ b/test/TestServerProjects/body-formdata/body_formdata.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-integer/Generated/Configuration.json b/test/TestServerProjects/body-integer/Generated/Configuration.json index b803acd8809..3baa4555406 100644 --- a/test/TestServerProjects/body-integer/Generated/Configuration.json +++ b/test/TestServerProjects/body-integer/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-integer/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-integer/Generated/Models/Error.Serialization.cs index 297969243fd..fe07ecdba4e 100644 --- a/test/TestServerProjects/body-integer/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-integer/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_integer.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-integer/Generated/Models/Error.cs b/test/TestServerProjects/body-integer/Generated/Models/Error.cs index af77fba928f..7b6428271db 100644 --- a/test/TestServerProjects/body-integer/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-integer/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_integer.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-integer/body_integer.csproj b/test/TestServerProjects/body-integer/body_integer.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-integer/body_integer.csproj +++ b/test/TestServerProjects/body-integer/body_integer.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-number/Generated/Configuration.json b/test/TestServerProjects/body-number/Generated/Configuration.json index 30b2abaadbb..10ec9f39be8 100644 --- a/test/TestServerProjects/body-number/Generated/Configuration.json +++ b/test/TestServerProjects/body-number/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-number/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-number/Generated/Models/Error.Serialization.cs index a30059e1ded..e2bb70d51d1 100644 --- a/test/TestServerProjects/body-number/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-number/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_number.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-number/Generated/Models/Error.cs b/test/TestServerProjects/body-number/Generated/Models/Error.cs index a328299607a..86332ed4848 100644 --- a/test/TestServerProjects/body-number/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-number/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_number.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-number/body_number.csproj b/test/TestServerProjects/body-number/body_number.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-number/body_number.csproj +++ b/test/TestServerProjects/body-number/body_number.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-string/Generated/BodyStringModelFactory.cs b/test/TestServerProjects/body-string/Generated/BodyStringModelFactory.cs index 3de1dee3ffe..35dafa5bd6c 100644 --- a/test/TestServerProjects/body-string/Generated/BodyStringModelFactory.cs +++ b/test/TestServerProjects/body-string/Generated/BodyStringModelFactory.cs @@ -16,7 +16,7 @@ public static partial class BodyStringModelFactory /// A new instance for mocking. public static RefColorConstant RefColorConstant(ColorConstant colorConstant = default, string field1 = null) { - return new RefColorConstant(colorConstant, field1); + return new RefColorConstant(colorConstant, field1, serializedAdditionalRawData: null); } } } diff --git a/test/TestServerProjects/body-string/Generated/Configuration.json b/test/TestServerProjects/body-string/Generated/Configuration.json index 8b17d12d0b3..d92c36dad9c 100644 --- a/test/TestServerProjects/body-string/Generated/Configuration.json +++ b/test/TestServerProjects/body-string/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-string/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-string/Generated/Models/Error.Serialization.cs index 125098a292e..71087c53246 100644 --- a/test/TestServerProjects/body-string/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-string/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_string.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-string/Generated/Models/Error.cs b/test/TestServerProjects/body-string/Generated/Models/Error.cs index 75157e69ef5..e7085a02051 100644 --- a/test/TestServerProjects/body-string/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-string/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_string.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-string/Generated/Models/RefColorConstant.Serialization.cs b/test/TestServerProjects/body-string/Generated/Models/RefColorConstant.Serialization.cs index 48351501ddb..ac51fdf8218 100644 --- a/test/TestServerProjects/body-string/Generated/Models/RefColorConstant.Serialization.cs +++ b/test/TestServerProjects/body-string/Generated/Models/RefColorConstant.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_string.Models { - public partial class RefColorConstant : IUtf8JsonSerializable + public partial class RefColorConstant : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RefColorConstant)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("ColorConstant"u8); writer.WriteStringValue(ColorConstant.ToString()); @@ -22,17 +33,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("field1"u8); writer.WriteStringValue(Field1); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static RefColorConstant DeserializeRefColorConstant(JsonElement element) + RefColorConstant IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RefColorConstant)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRefColorConstant(document.RootElement, options); + } + + internal static RefColorConstant DeserializeRefColorConstant(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } ColorConstant colorConstant = default; Optional field1 = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("ColorConstant"u8)) @@ -45,8 +87,44 @@ internal static RefColorConstant DeserializeRefColorConstant(JsonElement element field1 = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new RefColorConstant(colorConstant, field1.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(RefColorConstant)} does not support '{options.Format}' format."); } - return new RefColorConstant(colorConstant, field1.Value); } + + RefColorConstant IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeRefColorConstant(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RefColorConstant)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-string/Generated/Models/RefColorConstant.cs b/test/TestServerProjects/body-string/Generated/Models/RefColorConstant.cs index fe74560f29b..46fb36e6020 100644 --- a/test/TestServerProjects/body-string/Generated/Models/RefColorConstant.cs +++ b/test/TestServerProjects/body-string/Generated/Models/RefColorConstant.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_string.Models { /// The RefColorConstant. public partial class RefColorConstant { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public RefColorConstant() { @@ -19,10 +54,12 @@ public RefColorConstant() /// Initializes a new instance of . /// Referenced Color Constant Description. /// Sample string. - internal RefColorConstant(ColorConstant colorConstant, string field1) + /// Keeps track of any properties unknown to the library. + internal RefColorConstant(ColorConstant colorConstant, string field1, IDictionary serializedAdditionalRawData) { ColorConstant = colorConstant; Field1 = field1; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Referenced Color Constant Description. diff --git a/test/TestServerProjects/body-string/body_string.csproj b/test/TestServerProjects/body-string/body_string.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-string/body_string.csproj +++ b/test/TestServerProjects/body-string/body_string.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/body-time/Generated/Configuration.json b/test/TestServerProjects/body-time/Generated/Configuration.json index 892993aeb01..8a484d25a5c 100644 --- a/test/TestServerProjects/body-time/Generated/Configuration.json +++ b/test/TestServerProjects/body-time/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/body-time/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/body-time/Generated/Models/Error.Serialization.cs index 5de175237e3..c0fd05be869 100644 --- a/test/TestServerProjects/body-time/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/body-time/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace body_time.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/body-time/Generated/Models/Error.cs b/test/TestServerProjects/body-time/Generated/Models/Error.cs index b9471487f00..6a76a201924 100644 --- a/test/TestServerProjects/body-time/Generated/Models/Error.cs +++ b/test/TestServerProjects/body-time/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace body_time.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/body-time/body_time.csproj b/test/TestServerProjects/body-time/body_time.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/body-time/body_time.csproj +++ b/test/TestServerProjects/body-time/body_time.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/constants/Generated/Configuration.json b/test/TestServerProjects/constants/Generated/Configuration.json index 88522045046..875f7c5e1e3 100644 --- a/test/TestServerProjects/constants/Generated/Configuration.json +++ b/test/TestServerProjects/constants/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredOneValueDefault.cs b/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredOneValueDefault.cs index c905bac1a5e..5029f1f8e77 100644 --- a/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredOneValueDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredOneValueDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The ModelAsStringNoRequiredOneValueDefault. internal partial class ModelAsStringNoRequiredOneValueDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ModelAsStringNoRequiredOneValueDefault() { @@ -17,9 +52,11 @@ internal ModelAsStringNoRequiredOneValueDefault() /// Initializes a new instance of . /// - internal ModelAsStringNoRequiredOneValueDefault(ModelAsStringNoRequiredOneValueDefaultEnum? parameter) + /// Keeps track of any properties unknown to the library. + internal ModelAsStringNoRequiredOneValueDefault(ModelAsStringNoRequiredOneValueDefaultEnum? parameter, IDictionary serializedAdditionalRawData) { Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the parameter. diff --git a/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredOneValueNoDefault.cs b/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredOneValueNoDefault.cs index d01ad62524c..9bd0838f601 100644 --- a/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredOneValueNoDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredOneValueNoDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The ModelAsStringNoRequiredOneValueNoDefault. internal partial class ModelAsStringNoRequiredOneValueNoDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ModelAsStringNoRequiredOneValueNoDefault() { @@ -17,9 +52,11 @@ internal ModelAsStringNoRequiredOneValueNoDefault() /// Initializes a new instance of . /// - internal ModelAsStringNoRequiredOneValueNoDefault(ModelAsStringNoRequiredOneValueNoDefaultEnum? parameter) + /// Keeps track of any properties unknown to the library. + internal ModelAsStringNoRequiredOneValueNoDefault(ModelAsStringNoRequiredOneValueNoDefaultEnum? parameter, IDictionary serializedAdditionalRawData) { Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the parameter. diff --git a/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredTwoValueDefault.cs b/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredTwoValueDefault.cs index f2d5fad7d35..2c0a580ce86 100644 --- a/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredTwoValueDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredTwoValueDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The ModelAsStringNoRequiredTwoValueDefault. internal partial class ModelAsStringNoRequiredTwoValueDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ModelAsStringNoRequiredTwoValueDefault() { @@ -17,9 +52,11 @@ internal ModelAsStringNoRequiredTwoValueDefault() /// Initializes a new instance of . /// - internal ModelAsStringNoRequiredTwoValueDefault(ModelAsStringNoRequiredTwoValueDefaultEnum? parameter) + /// Keeps track of any properties unknown to the library. + internal ModelAsStringNoRequiredTwoValueDefault(ModelAsStringNoRequiredTwoValueDefaultEnum? parameter, IDictionary serializedAdditionalRawData) { Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the parameter. diff --git a/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredTwoValueNoDefault.cs b/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredTwoValueNoDefault.cs index a6a9393a1af..effa3d8c7d8 100644 --- a/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredTwoValueNoDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/ModelAsStringNoRequiredTwoValueNoDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The ModelAsStringNoRequiredTwoValueNoDefault. internal partial class ModelAsStringNoRequiredTwoValueNoDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ModelAsStringNoRequiredTwoValueNoDefault() { @@ -17,9 +52,11 @@ internal ModelAsStringNoRequiredTwoValueNoDefault() /// Initializes a new instance of . /// - internal ModelAsStringNoRequiredTwoValueNoDefault(ModelAsStringNoRequiredTwoValueNoDefaultEnum? parameter) + /// Keeps track of any properties unknown to the library. + internal ModelAsStringNoRequiredTwoValueNoDefault(ModelAsStringNoRequiredTwoValueNoDefaultEnum? parameter, IDictionary serializedAdditionalRawData) { Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the parameter. diff --git a/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredOneValueDefault.cs b/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredOneValueDefault.cs index e6597c2c59f..e0f930c02af 100644 --- a/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredOneValueDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredOneValueDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The ModelAsStringRequiredOneValueDefault. internal partial class ModelAsStringRequiredOneValueDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// internal ModelAsStringRequiredOneValueDefault(ModelAsStringRequiredOneValueDefaultEnum parameter) @@ -17,6 +52,20 @@ internal ModelAsStringRequiredOneValueDefault(ModelAsStringRequiredOneValueDefau Parameter = parameter; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal ModelAsStringRequiredOneValueDefault(ModelAsStringRequiredOneValueDefaultEnum parameter, IDictionary serializedAdditionalRawData) + { + Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ModelAsStringRequiredOneValueDefault() + { + } + /// Gets the parameter. public ModelAsStringRequiredOneValueDefaultEnum Parameter { get; } } diff --git a/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredOneValueNoDefault.cs b/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredOneValueNoDefault.cs index 07472811926..f972fff91c1 100644 --- a/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredOneValueNoDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredOneValueNoDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The ModelAsStringRequiredOneValueNoDefault. internal partial class ModelAsStringRequiredOneValueNoDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// internal ModelAsStringRequiredOneValueNoDefault(ModelAsStringRequiredOneValueNoDefaultEnum parameter) @@ -17,6 +52,20 @@ internal ModelAsStringRequiredOneValueNoDefault(ModelAsStringRequiredOneValueNoD Parameter = parameter; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal ModelAsStringRequiredOneValueNoDefault(ModelAsStringRequiredOneValueNoDefaultEnum parameter, IDictionary serializedAdditionalRawData) + { + Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ModelAsStringRequiredOneValueNoDefault() + { + } + /// Gets the parameter. public ModelAsStringRequiredOneValueNoDefaultEnum Parameter { get; } } diff --git a/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredTwoValueDefault.cs b/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredTwoValueDefault.cs index fa3fae48151..602aef08d21 100644 --- a/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredTwoValueDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredTwoValueDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The ModelAsStringRequiredTwoValueDefault. internal partial class ModelAsStringRequiredTwoValueDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// internal ModelAsStringRequiredTwoValueDefault(ModelAsStringRequiredTwoValueDefaultEnum parameter) @@ -17,6 +52,20 @@ internal ModelAsStringRequiredTwoValueDefault(ModelAsStringRequiredTwoValueDefau Parameter = parameter; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal ModelAsStringRequiredTwoValueDefault(ModelAsStringRequiredTwoValueDefaultEnum parameter, IDictionary serializedAdditionalRawData) + { + Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ModelAsStringRequiredTwoValueDefault() + { + } + /// Gets the parameter. public ModelAsStringRequiredTwoValueDefaultEnum Parameter { get; } } diff --git a/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredTwoValueNoDefault.cs b/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredTwoValueNoDefault.cs index d0c4fd0369e..c954c3e5e18 100644 --- a/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredTwoValueNoDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/ModelAsStringRequiredTwoValueNoDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The ModelAsStringRequiredTwoValueNoDefault. internal partial class ModelAsStringRequiredTwoValueNoDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// internal ModelAsStringRequiredTwoValueNoDefault(ModelAsStringRequiredTwoValueNoDefaultEnum parameter) @@ -17,6 +52,20 @@ internal ModelAsStringRequiredTwoValueNoDefault(ModelAsStringRequiredTwoValueNoD Parameter = parameter; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal ModelAsStringRequiredTwoValueNoDefault(ModelAsStringRequiredTwoValueNoDefaultEnum parameter, IDictionary serializedAdditionalRawData) + { + Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ModelAsStringRequiredTwoValueNoDefault() + { + } + /// Gets the parameter. public ModelAsStringRequiredTwoValueNoDefaultEnum Parameter { get; } } diff --git a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredOneValueDefault.cs b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredOneValueDefault.cs index 33c7c18e5a9..4ce34f460e2 100644 --- a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredOneValueDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredOneValueDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The NoModelAsStringNoRequiredOneValueDefault. internal partial class NoModelAsStringNoRequiredOneValueDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal NoModelAsStringNoRequiredOneValueDefault() { @@ -17,9 +52,11 @@ internal NoModelAsStringNoRequiredOneValueDefault() /// Initializes a new instance of . /// - internal NoModelAsStringNoRequiredOneValueDefault(NoModelAsStringNoRequiredOneValueDefaultEnum? parameter) + /// Keeps track of any properties unknown to the library. + internal NoModelAsStringNoRequiredOneValueDefault(NoModelAsStringNoRequiredOneValueDefaultEnum? parameter, IDictionary serializedAdditionalRawData) { Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the parameter. diff --git a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredOneValueNoDefault.cs b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredOneValueNoDefault.cs index be82753f5bb..889464277d7 100644 --- a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredOneValueNoDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredOneValueNoDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The NoModelAsStringNoRequiredOneValueNoDefault. internal partial class NoModelAsStringNoRequiredOneValueNoDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal NoModelAsStringNoRequiredOneValueNoDefault() { @@ -17,9 +52,11 @@ internal NoModelAsStringNoRequiredOneValueNoDefault() /// Initializes a new instance of . /// - internal NoModelAsStringNoRequiredOneValueNoDefault(NoModelAsStringNoRequiredOneValueNoDefaultEnum? parameter) + /// Keeps track of any properties unknown to the library. + internal NoModelAsStringNoRequiredOneValueNoDefault(NoModelAsStringNoRequiredOneValueNoDefaultEnum? parameter, IDictionary serializedAdditionalRawData) { Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the parameter. diff --git a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredTwoValueDefault.cs b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredTwoValueDefault.cs index 5eb56b5ab79..26ba7e0a37c 100644 --- a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredTwoValueDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredTwoValueDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The NoModelAsStringNoRequiredTwoValueDefault. internal partial class NoModelAsStringNoRequiredTwoValueDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal NoModelAsStringNoRequiredTwoValueDefault() { @@ -17,9 +52,11 @@ internal NoModelAsStringNoRequiredTwoValueDefault() /// Initializes a new instance of . /// - internal NoModelAsStringNoRequiredTwoValueDefault(NoModelAsStringNoRequiredTwoValueDefaultEnum? parameter) + /// Keeps track of any properties unknown to the library. + internal NoModelAsStringNoRequiredTwoValueDefault(NoModelAsStringNoRequiredTwoValueDefaultEnum? parameter, IDictionary serializedAdditionalRawData) { Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the parameter. diff --git a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredTwoValueNoDefault.cs b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredTwoValueNoDefault.cs index f5a3149f69c..94c20770f22 100644 --- a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredTwoValueNoDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringNoRequiredTwoValueNoDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The NoModelAsStringNoRequiredTwoValueNoDefault. internal partial class NoModelAsStringNoRequiredTwoValueNoDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal NoModelAsStringNoRequiredTwoValueNoDefault() { @@ -17,9 +52,11 @@ internal NoModelAsStringNoRequiredTwoValueNoDefault() /// Initializes a new instance of . /// - internal NoModelAsStringNoRequiredTwoValueNoDefault(NoModelAsStringNoRequiredTwoValueNoDefaultEnum? parameter) + /// Keeps track of any properties unknown to the library. + internal NoModelAsStringNoRequiredTwoValueNoDefault(NoModelAsStringNoRequiredTwoValueNoDefaultEnum? parameter, IDictionary serializedAdditionalRawData) { Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the parameter. diff --git a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredOneValueDefault.cs b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredOneValueDefault.cs index c9317df35d1..1603baa8383 100644 --- a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredOneValueDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredOneValueDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The NoModelAsStringRequiredOneValueDefault. internal partial class NoModelAsStringRequiredOneValueDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal NoModelAsStringRequiredOneValueDefault() { @@ -18,9 +53,11 @@ internal NoModelAsStringRequiredOneValueDefault() /// Initializes a new instance of . /// - internal NoModelAsStringRequiredOneValueDefault(NoModelAsStringRequiredOneValueDefaultEnum parameter) + /// Keeps track of any properties unknown to the library. + internal NoModelAsStringRequiredOneValueDefault(NoModelAsStringRequiredOneValueDefaultEnum parameter, IDictionary serializedAdditionalRawData) { Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the parameter. diff --git a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredOneValueNoDefault.cs b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredOneValueNoDefault.cs index 45afe3ce467..ddaa2b36b43 100644 --- a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredOneValueNoDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredOneValueNoDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The NoModelAsStringRequiredOneValueNoDefault. internal partial class NoModelAsStringRequiredOneValueNoDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal NoModelAsStringRequiredOneValueNoDefault() { @@ -18,9 +53,11 @@ internal NoModelAsStringRequiredOneValueNoDefault() /// Initializes a new instance of . /// - internal NoModelAsStringRequiredOneValueNoDefault(NoModelAsStringRequiredOneValueNoDefaultEnum parameter) + /// Keeps track of any properties unknown to the library. + internal NoModelAsStringRequiredOneValueNoDefault(NoModelAsStringRequiredOneValueNoDefaultEnum parameter, IDictionary serializedAdditionalRawData) { Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the parameter. diff --git a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredTwoValueDefault.cs b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredTwoValueDefault.cs index a3f22e63b51..c83fb53a81f 100644 --- a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredTwoValueDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredTwoValueDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The NoModelAsStringRequiredTwoValueDefault. internal partial class NoModelAsStringRequiredTwoValueDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// internal NoModelAsStringRequiredTwoValueDefault(NoModelAsStringRequiredTwoValueDefaultEnum parameter) @@ -17,6 +52,20 @@ internal NoModelAsStringRequiredTwoValueDefault(NoModelAsStringRequiredTwoValueD Parameter = parameter; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal NoModelAsStringRequiredTwoValueDefault(NoModelAsStringRequiredTwoValueDefaultEnum parameter, IDictionary serializedAdditionalRawData) + { + Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal NoModelAsStringRequiredTwoValueDefault() + { + } + /// Gets the parameter. public NoModelAsStringRequiredTwoValueDefaultEnum Parameter { get; } } diff --git a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredTwoValueNoDefault.cs b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredTwoValueNoDefault.cs index e7cfc5b4db1..ec66f56d0bb 100644 --- a/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredTwoValueNoDefault.cs +++ b/test/TestServerProjects/constants/Generated/Models/NoModelAsStringRequiredTwoValueNoDefault.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace constants.Models { /// The NoModelAsStringRequiredTwoValueNoDefault. internal partial class NoModelAsStringRequiredTwoValueNoDefault { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// internal NoModelAsStringRequiredTwoValueNoDefault(NoModelAsStringRequiredTwoValueNoDefaultEnum parameter) @@ -17,6 +52,20 @@ internal NoModelAsStringRequiredTwoValueNoDefault(NoModelAsStringRequiredTwoValu Parameter = parameter; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal NoModelAsStringRequiredTwoValueNoDefault(NoModelAsStringRequiredTwoValueNoDefaultEnum parameter, IDictionary serializedAdditionalRawData) + { + Parameter = parameter; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal NoModelAsStringRequiredTwoValueNoDefault() + { + } + /// Gets the parameter. public NoModelAsStringRequiredTwoValueNoDefaultEnum Parameter { get; } } diff --git a/test/TestServerProjects/constants/constants.csproj b/test/TestServerProjects/constants/constants.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/constants/constants.csproj +++ b/test/TestServerProjects/constants/constants.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/custom-baseUrl-more-options/Generated/Configuration.json b/test/TestServerProjects/custom-baseUrl-more-options/Generated/Configuration.json index 47de3413f49..556e3a93d50 100644 --- a/test/TestServerProjects/custom-baseUrl-more-options/Generated/Configuration.json +++ b/test/TestServerProjects/custom-baseUrl-more-options/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/custom-baseUrl-more-options/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/custom-baseUrl-more-options/Generated/Models/Error.Serialization.cs index da22290ded5..db84c848e4b 100644 --- a/test/TestServerProjects/custom-baseUrl-more-options/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/custom-baseUrl-more-options/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace custom_baseUrl_more_options.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/custom-baseUrl-more-options/Generated/Models/Error.cs b/test/TestServerProjects/custom-baseUrl-more-options/Generated/Models/Error.cs index 155b885bf72..d2682278c29 100644 --- a/test/TestServerProjects/custom-baseUrl-more-options/Generated/Models/Error.cs +++ b/test/TestServerProjects/custom-baseUrl-more-options/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace custom_baseUrl_more_options.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/custom-baseUrl-more-options/custom_baseUrl_more_options.csproj b/test/TestServerProjects/custom-baseUrl-more-options/custom_baseUrl_more_options.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/custom-baseUrl-more-options/custom_baseUrl_more_options.csproj +++ b/test/TestServerProjects/custom-baseUrl-more-options/custom_baseUrl_more_options.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/custom-baseUrl-paging/Generated/Configuration.json b/test/TestServerProjects/custom-baseUrl-paging/Generated/Configuration.json index a85cb2cf6c8..fa58b40e7c5 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/Generated/Configuration.json +++ b/test/TestServerProjects/custom-baseUrl-paging/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/custom-baseUrl-paging/Generated/CustomBaseUrlPagingModelFactory.cs b/test/TestServerProjects/custom-baseUrl-paging/Generated/CustomBaseUrlPagingModelFactory.cs index c78dbd493ed..4d783d18acc 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/Generated/CustomBaseUrlPagingModelFactory.cs +++ b/test/TestServerProjects/custom-baseUrl-paging/Generated/CustomBaseUrlPagingModelFactory.cs @@ -15,7 +15,7 @@ public static partial class CustomBaseUrlPagingModelFactory /// A new instance for mocking. public static Product Product(ProductProperties properties = null) { - return new Product(properties); + return new Product(properties, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -24,7 +24,7 @@ public static Product Product(ProductProperties properties = null) /// A new instance for mocking. public static ProductProperties ProductProperties(int? id = null, string name = null) { - return new ProductProperties(id, name); + return new ProductProperties(id, name, serializedAdditionalRawData: null); } } } diff --git a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Error.cs b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Error.cs index 55e26e1b328..8413670b847 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Error.cs +++ b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace custom_baseUrl_paging.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Product.Serialization.cs b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Product.Serialization.cs index 701e81c5cb9..23fb77632c4 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Product.Serialization.cs +++ b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Product.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace custom_baseUrl_paging.Models { - public partial class Product + public partial class Product : IUtf8JsonSerializable, IJsonModel { - internal static Product DeserializeProduct(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Properties)) + { + writer.WritePropertyName("properties"u8); + writer.WriteObjectValue(Properties); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Product IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProduct(document.RootElement, options); + } + + internal static Product DeserializeProduct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional properties = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("properties"u8)) @@ -30,8 +83,44 @@ internal static Product DeserializeProduct(JsonElement element) properties = ProductProperties.DeserializeProductProperties(property.Value); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Product(properties.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); } - return new Product(properties.Value); } + + Product IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Product.cs b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Product.cs index 55a37fa5d6b..7049b4fc2f5 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Product.cs +++ b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/Product.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace custom_baseUrl_paging.Models { /// The Product. public partial class Product { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Product() { @@ -17,9 +52,11 @@ internal Product() /// Initializes a new instance of . /// - internal Product(ProductProperties properties) + /// Keeps track of any properties unknown to the library. + internal Product(ProductProperties properties, IDictionary serializedAdditionalRawData) { Properties = properties; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the properties. diff --git a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductProperties.Serialization.cs b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductProperties.Serialization.cs index 9e29075242c..181031a3254 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductProperties.Serialization.cs +++ b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductProperties.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace custom_baseUrl_paging.Models { - public partial class ProductProperties + public partial class ProductProperties : IUtf8JsonSerializable, IJsonModel { - internal static ProductProperties DeserializeProductProperties(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductProperties)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteNumberValue(Id.Value); + } + if (Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ProductProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProductProperties(document.RootElement, options); + } + + internal static ProductProperties DeserializeProductProperties(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional id = default; Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -36,8 +94,44 @@ internal static ProductProperties DeserializeProductProperties(JsonElement eleme name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ProductProperties(Optional.ToNullable(id), name.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ProductProperties)} does not support '{options.Format}' format."); + } + } + + ProductProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProductProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ProductProperties)} does not support '{options.Format}' format."); } - return new ProductProperties(Optional.ToNullable(id), name.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductProperties.cs b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductProperties.cs index fd8f9ede304..27a8f099bc7 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductProperties.cs +++ b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductProperties.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace custom_baseUrl_paging.Models { /// The ProductProperties. public partial class ProductProperties { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ProductProperties() { @@ -18,10 +53,12 @@ internal ProductProperties() /// Initializes a new instance of . /// /// - internal ProductProperties(int? id, string name) + /// Keeps track of any properties unknown to the library. + internal ProductProperties(int? id, string name, IDictionary serializedAdditionalRawData) { Id = id; Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the id. diff --git a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductResult.Serialization.cs b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductResult.Serialization.cs index 9df8f57775f..57f911988d9 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductResult.Serialization.cs +++ b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductResult.Serialization.cs @@ -5,22 +5,84 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace custom_baseUrl_paging.Models { - internal partial class ProductResult + internal partial class ProductResult : IUtf8JsonSerializable, IJsonModel { - internal static ProductResult DeserializeProductResult(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductResult)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsCollectionDefined(Values)) + { + writer.WritePropertyName("values"u8); + writer.WriteStartArray(); + foreach (var item in Values) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(NextLink)) + { + writer.WritePropertyName("nextLink"u8); + writer.WriteStringValue(NextLink); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ProductResult IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductResult)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProductResult(document.RootElement, options); + } + + internal static ProductResult DeserializeProductResult(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional> values = default; Optional nextLink = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("values"u8)) @@ -42,8 +104,44 @@ internal static ProductResult DeserializeProductResult(JsonElement element) nextLink = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ProductResult(Optional.ToList(values), nextLink.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ProductResult(Optional.ToList(values), nextLink.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ProductResult)} does not support '{options.Format}' format."); + } + } + + ProductResult IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProductResult(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ProductResult)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductResult.cs b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductResult.cs index 6324c2e7349..f3a0d94c55e 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductResult.cs +++ b/test/TestServerProjects/custom-baseUrl-paging/Generated/Models/ProductResult.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace custom_baseUrl_paging.Models /// The ProductResult. internal partial class ProductResult { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ProductResult() { @@ -22,10 +55,12 @@ internal ProductResult() /// Initializes a new instance of . /// /// - internal ProductResult(IReadOnlyList values, string nextLink) + /// Keeps track of any properties unknown to the library. + internal ProductResult(IReadOnlyList values, string nextLink, IDictionary serializedAdditionalRawData) { Values = values; NextLink = nextLink; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the values. diff --git a/test/TestServerProjects/custom-baseUrl-paging/Generated/PagingClient.cs b/test/TestServerProjects/custom-baseUrl-paging/Generated/PagingClient.cs index 207e942aafa..ccdde972240 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/Generated/PagingClient.cs +++ b/test/TestServerProjects/custom-baseUrl-paging/Generated/PagingClient.cs @@ -49,7 +49,7 @@ public virtual AsyncPageable GetPagesPartialUrlAsync(string accountName HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetPagesPartialUrlRequest(accountName); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetPagesPartialUrlNextPageRequest(nextLink, accountName); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrl", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrl", "values", "nextLink", cancellationToken); } /// A paging operation that combines custom url, paging and partial URL and expect to concat after host. @@ -62,7 +62,7 @@ public virtual Pageable GetPagesPartialUrl(string accountName, Cancella HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetPagesPartialUrlRequest(accountName); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetPagesPartialUrlNextPageRequest(nextLink, accountName); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrl", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrl", "values", "nextLink", cancellationToken); } /// A paging operation that combines custom url, paging and partial URL with next operation. @@ -75,7 +75,7 @@ public virtual AsyncPageable GetPagesPartialUrlOperationAsync(string ac HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetPagesPartialUrlOperationRequest(accountName); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetPagesPartialUrlOperationNextRequest(accountName, nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrlOperation", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrlOperation", "values", "nextLink", cancellationToken); } /// A paging operation that combines custom url, paging and partial URL with next operation. @@ -88,7 +88,7 @@ public virtual Pageable GetPagesPartialUrlOperation(string accountName, HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetPagesPartialUrlOperationRequest(accountName); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetPagesPartialUrlOperationNextRequest(accountName, nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrlOperation", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrlOperation", "values", "nextLink", cancellationToken); } /// A paging operation that combines custom url, paging and partial URL. @@ -103,7 +103,7 @@ public virtual AsyncPageable GetPagesPartialUrlOperationNextAsync(strin HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetPagesPartialUrlOperationNextRequest(accountName, nextLink); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetPagesPartialUrlOperationNextRequest(accountName, nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrlOperationNext", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrlOperationNext", "values", "nextLink", cancellationToken); } /// A paging operation that combines custom url, paging and partial URL. @@ -118,7 +118,7 @@ public virtual Pageable GetPagesPartialUrlOperationNext(string accountN HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetPagesPartialUrlOperationNextRequest(accountName, nextLink); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetPagesPartialUrlOperationNextRequest(accountName, nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrlOperationNext", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetPagesPartialUrlOperationNext", "values", "nextLink", cancellationToken); } } } diff --git a/test/TestServerProjects/custom-baseUrl-paging/custom_baseUrl_paging.csproj b/test/TestServerProjects/custom-baseUrl-paging/custom_baseUrl_paging.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/custom-baseUrl-paging/custom_baseUrl_paging.csproj +++ b/test/TestServerProjects/custom-baseUrl-paging/custom_baseUrl_paging.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/custom-baseUrl/Generated/Configuration.json b/test/TestServerProjects/custom-baseUrl/Generated/Configuration.json index 7e7c0923978..6a3cb7beaa4 100644 --- a/test/TestServerProjects/custom-baseUrl/Generated/Configuration.json +++ b/test/TestServerProjects/custom-baseUrl/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/custom-baseUrl/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/custom-baseUrl/Generated/Models/Error.Serialization.cs index 494f1a9ae72..015fdeac459 100644 --- a/test/TestServerProjects/custom-baseUrl/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/custom-baseUrl/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace custom_baseUrl.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/custom-baseUrl/Generated/Models/Error.cs b/test/TestServerProjects/custom-baseUrl/Generated/Models/Error.cs index 7d5193cf138..8ec70a9b370 100644 --- a/test/TestServerProjects/custom-baseUrl/Generated/Models/Error.cs +++ b/test/TestServerProjects/custom-baseUrl/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace custom_baseUrl.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/custom-baseUrl/custom_baseUrl.csproj b/test/TestServerProjects/custom-baseUrl/custom_baseUrl.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/custom-baseUrl/custom_baseUrl.csproj +++ b/test/TestServerProjects/custom-baseUrl/custom_baseUrl.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/extensible-enums-swagger/Generated/Configuration.json b/test/TestServerProjects/extensible-enums-swagger/Generated/Configuration.json index 970f62b60ba..2098cc3d2ee 100644 --- a/test/TestServerProjects/extensible-enums-swagger/Generated/Configuration.json +++ b/test/TestServerProjects/extensible-enums-swagger/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/extensible-enums-swagger/Generated/Models/Pet.Serialization.cs b/test/TestServerProjects/extensible-enums-swagger/Generated/Models/Pet.Serialization.cs index c0e0c30a46e..e949609a7cf 100644 --- a/test/TestServerProjects/extensible-enums-swagger/Generated/Models/Pet.Serialization.cs +++ b/test/TestServerProjects/extensible-enums-swagger/Generated/Models/Pet.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace extensible_enums_swagger.Models { - public partial class Pet : IUtf8JsonSerializable + public partial class Pet : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Name)) { @@ -27,11 +38,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WritePropertyName("IntEnum"u8); writer.WriteStringValue(IntEnum.ToString()); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Pet DeserializePet(JsonElement element) + Pet IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePet(document.RootElement, options); + } + + internal static Pet DeserializePet(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -39,6 +79,8 @@ internal static Pet DeserializePet(JsonElement element) Optional name = default; Optional daysOfWeek = default; IntEnum intEnum = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("name"u8)) @@ -60,8 +102,44 @@ internal static Pet DeserializePet(JsonElement element) intEnum = new IntEnum(property.Value.GetString()); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Pet(name.Value, Optional.ToNullable(daysOfWeek), intEnum); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Pet(name.Value, Optional.ToNullable(daysOfWeek), intEnum, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Pet)} does not support '{options.Format}' format."); + } + } + + Pet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePet(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Pet)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/extensible-enums-swagger/Generated/Models/Pet.cs b/test/TestServerProjects/extensible-enums-swagger/Generated/Models/Pet.cs index 65f41ef1382..d32d2b20d91 100644 --- a/test/TestServerProjects/extensible-enums-swagger/Generated/Models/Pet.cs +++ b/test/TestServerProjects/extensible-enums-swagger/Generated/Models/Pet.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace extensible_enums_swagger.Models { /// The Pet. public partial class Pet { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// public Pet(IntEnum intEnum) @@ -21,11 +56,18 @@ public Pet(IntEnum intEnum) /// name. /// Type of Pet. /// - internal Pet(string name, DaysOfWeekExtensibleEnum? daysOfWeek, IntEnum intEnum) + /// Keeps track of any properties unknown to the library. + internal Pet(string name, DaysOfWeekExtensibleEnum? daysOfWeek, IntEnum intEnum, IDictionary serializedAdditionalRawData) { Name = name; DaysOfWeek = daysOfWeek; IntEnum = intEnum; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Pet() + { } /// name. diff --git a/test/TestServerProjects/extensible-enums-swagger/extensible_enums_swagger.csproj b/test/TestServerProjects/extensible-enums-swagger/extensible_enums_swagger.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/extensible-enums-swagger/extensible_enums_swagger.csproj +++ b/test/TestServerProjects/extensible-enums-swagger/extensible_enums_swagger.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/head/Generated/Configuration.json b/test/TestServerProjects/head/Generated/Configuration.json index 5c32727da4c..16104dd0da4 100644 --- a/test/TestServerProjects/head/Generated/Configuration.json +++ b/test/TestServerProjects/head/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/head/head.csproj b/test/TestServerProjects/head/head.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/head/head.csproj +++ b/test/TestServerProjects/head/head.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/header/Generated/Configuration.json b/test/TestServerProjects/header/Generated/Configuration.json index 476e3bd80ef..c49e73afa77 100644 --- a/test/TestServerProjects/header/Generated/Configuration.json +++ b/test/TestServerProjects/header/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/header/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/header/Generated/Models/Error.Serialization.cs index 43458a83307..3f88d2e2bba 100644 --- a/test/TestServerProjects/header/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/header/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace header.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/header/Generated/Models/Error.cs b/test/TestServerProjects/header/Generated/Models/Error.cs index f8c39c079ee..197724a71af 100644 --- a/test/TestServerProjects/header/Generated/Models/Error.cs +++ b/test/TestServerProjects/header/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace header.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/header/header.csproj b/test/TestServerProjects/header/header.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/header/header.csproj +++ b/test/TestServerProjects/header/header.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Configuration.json b/test/TestServerProjects/httpInfrastructure/Generated/Configuration.json index a38b73c265c..3f96e8d527b 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Configuration.json +++ b/test/TestServerProjects/httpInfrastructure/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/httpInfrastructure/Generated/HttpInfrastructureModelFactory.cs b/test/TestServerProjects/httpInfrastructure/Generated/HttpInfrastructureModelFactory.cs index 86431202c57..ad6c325b185 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/HttpInfrastructureModelFactory.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/HttpInfrastructureModelFactory.cs @@ -15,7 +15,7 @@ public static partial class HttpInfrastructureModelFactory /// A new instance for mocking. public static MyException MyException(string statusCode = null) { - return new MyException(statusCode); + return new MyException(statusCode, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -24,7 +24,7 @@ public static MyException MyException(string statusCode = null) /// A new instance for mocking. public static B B(string statusCode = null, string textStatusCode = null) { - return new B(statusCode, textStatusCode); + return new B(statusCode, serializedAdditionalRawData: null, textStatusCode); } /// Initializes a new instance of . @@ -32,7 +32,7 @@ public static B B(string statusCode = null, string textStatusCode = null) /// A new instance for mocking. public static C C(string httpCode = null) { - return new C(httpCode); + return new C(httpCode, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -40,7 +40,7 @@ public static C C(string httpCode = null) /// A new instance for mocking. public static D D(string httpStatusCode = null) { - return new D(httpStatusCode); + return new D(httpStatusCode, serializedAdditionalRawData: null); } } } diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Models/B.Serialization.cs b/test/TestServerProjects/httpInfrastructure/Generated/Models/B.Serialization.cs index 49aa375fdc8..fe19253d48b 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Models/B.Serialization.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/Models/B.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace httpInfrastructure.Models { - public partial class B + public partial class B : IUtf8JsonSerializable, IJsonModel { - internal static B DeserializeB(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(B)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(TextStatusCode)) + { + writer.WritePropertyName("textStatusCode"u8); + writer.WriteStringValue(TextStatusCode); + } + if (Optional.IsDefined(StatusCode)) + { + writer.WritePropertyName("statusCode"u8); + writer.WriteStringValue(StatusCode); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + B IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(B)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeB(document.RootElement, options); + } + + internal static B DeserializeB(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional textStatusCode = default; Optional statusCode = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("textStatusCode"u8)) @@ -32,8 +90,44 @@ internal static B DeserializeB(JsonElement element) statusCode = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new B(statusCode.Value, serializedAdditionalRawData, textStatusCode.Value); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(B)} does not support '{options.Format}' format."); } - return new B(statusCode.Value, textStatusCode.Value); } + + B IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeB(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(B)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Models/B.cs b/test/TestServerProjects/httpInfrastructure/Generated/Models/B.cs index 56cdf8629c3..84eb06749da 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Models/B.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/Models/B.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace httpInfrastructure.Models { /// The B. @@ -17,8 +20,9 @@ internal B() /// Initializes a new instance of . /// + /// Keeps track of any properties unknown to the library. /// - internal B(string statusCode, string textStatusCode) : base(statusCode) + internal B(string statusCode, IDictionary serializedAdditionalRawData, string textStatusCode) : base(statusCode, serializedAdditionalRawData) { TextStatusCode = textStatusCode; } diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Models/C.Serialization.cs b/test/TestServerProjects/httpInfrastructure/Generated/Models/C.Serialization.cs index 4139b5a17bb..891aae584e5 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Models/C.Serialization.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/Models/C.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace httpInfrastructure.Models { - public partial class C + public partial class C : IUtf8JsonSerializable, IJsonModel { - internal static C DeserializeC(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(C)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(HttpCode)) + { + writer.WritePropertyName("httpCode"u8); + writer.WriteStringValue(HttpCode); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + C IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(C)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeC(document.RootElement, options); + } + + internal static C DeserializeC(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional httpCode = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("httpCode"u8)) @@ -26,8 +79,44 @@ internal static C DeserializeC(JsonElement element) httpCode = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new C(httpCode.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new C(httpCode.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(C)} does not support '{options.Format}' format."); + } + } + + C IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeC(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(C)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Models/C.cs b/test/TestServerProjects/httpInfrastructure/Generated/Models/C.cs index 9b31a829a9a..2b47c05e36d 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Models/C.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/Models/C.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace httpInfrastructure.Models { /// The C. public partial class C { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal C() { @@ -17,9 +52,11 @@ internal C() /// Initializes a new instance of . /// - internal C(string httpCode) + /// Keeps track of any properties unknown to the library. + internal C(string httpCode, IDictionary serializedAdditionalRawData) { HttpCode = httpCode; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the http code. diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Models/D.Serialization.cs b/test/TestServerProjects/httpInfrastructure/Generated/Models/D.Serialization.cs index 50aea5701dc..1fa8d182f9e 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Models/D.Serialization.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/Models/D.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace httpInfrastructure.Models { - public partial class D + public partial class D : IUtf8JsonSerializable, IJsonModel { - internal static D DeserializeD(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(D)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(HttpStatusCode)) + { + writer.WritePropertyName("httpStatusCode"u8); + writer.WriteStringValue(HttpStatusCode); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + D IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(D)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeD(document.RootElement, options); + } + + internal static D DeserializeD(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional httpStatusCode = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("httpStatusCode"u8)) @@ -26,8 +79,44 @@ internal static D DeserializeD(JsonElement element) httpStatusCode = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new D(httpStatusCode.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new D(httpStatusCode.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(D)} does not support '{options.Format}' format."); + } + } + + D IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeD(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(D)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Models/D.cs b/test/TestServerProjects/httpInfrastructure/Generated/Models/D.cs index f9be47c7dcc..12a6a050c63 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Models/D.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/Models/D.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace httpInfrastructure.Models { /// The D. public partial class D { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal D() { @@ -17,9 +52,11 @@ internal D() /// Initializes a new instance of . /// - internal D(string httpStatusCode) + /// Keeps track of any properties unknown to the library. + internal D(string httpStatusCode, IDictionary serializedAdditionalRawData) { HttpStatusCode = httpStatusCode; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the http status code. diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/httpInfrastructure/Generated/Models/Error.Serialization.cs index b9ca090817d..fd26b32c879 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace httpInfrastructure.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Models/Error.cs b/test/TestServerProjects/httpInfrastructure/Generated/Models/Error.cs index 1c15a069f59..94387eed3c0 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Models/Error.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace httpInfrastructure.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Models/MyException.Serialization.cs b/test/TestServerProjects/httpInfrastructure/Generated/Models/MyException.Serialization.cs index 72c5ebfe7fd..f2a59d3e5d3 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Models/MyException.Serialization.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/Models/MyException.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace httpInfrastructure.Models { - public partial class MyException + public partial class MyException : IUtf8JsonSerializable, IJsonModel { - internal static MyException DeserializeMyException(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MyException)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(StatusCode)) + { + writer.WritePropertyName("statusCode"u8); + writer.WriteStringValue(StatusCode); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + MyException IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(MyException)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeMyException(document.RootElement, options); + } + + internal static MyException DeserializeMyException(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional statusCode = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("statusCode"u8)) @@ -26,8 +79,44 @@ internal static MyException DeserializeMyException(JsonElement element) statusCode = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new MyException(statusCode.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new MyException(statusCode.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(MyException)} does not support '{options.Format}' format."); + } + } + + MyException IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeMyException(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(MyException)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/httpInfrastructure/Generated/Models/MyException.cs b/test/TestServerProjects/httpInfrastructure/Generated/Models/MyException.cs index b42ab967dca..6a70050249d 100644 --- a/test/TestServerProjects/httpInfrastructure/Generated/Models/MyException.cs +++ b/test/TestServerProjects/httpInfrastructure/Generated/Models/MyException.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace httpInfrastructure.Models { /// The MyException. public partial class MyException { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal MyException() { @@ -17,9 +52,11 @@ internal MyException() /// Initializes a new instance of . /// - internal MyException(string statusCode) + /// Keeps track of any properties unknown to the library. + internal MyException(string statusCode, IDictionary serializedAdditionalRawData) { StatusCode = statusCode; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status code. diff --git a/test/TestServerProjects/httpInfrastructure/httpInfrastructure.csproj b/test/TestServerProjects/httpInfrastructure/httpInfrastructure.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/httpInfrastructure/httpInfrastructure.csproj +++ b/test/TestServerProjects/httpInfrastructure/httpInfrastructure.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/lro-parameterized-endpoints/Generated/Configuration.json b/test/TestServerProjects/lro-parameterized-endpoints/Generated/Configuration.json index 490087a6a09..261300af0d4 100644 --- a/test/TestServerProjects/lro-parameterized-endpoints/Generated/Configuration.json +++ b/test/TestServerProjects/lro-parameterized-endpoints/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/lro-parameterized-endpoints/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/lro-parameterized-endpoints/Generated/Models/Error.Serialization.cs index 2b264747fd2..2c06bafd788 100644 --- a/test/TestServerProjects/lro-parameterized-endpoints/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/lro-parameterized-endpoints/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace lro_parameterized_endpoints.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/lro-parameterized-endpoints/Generated/Models/Error.cs b/test/TestServerProjects/lro-parameterized-endpoints/Generated/Models/Error.cs index 82226087552..802130e4162 100644 --- a/test/TestServerProjects/lro-parameterized-endpoints/Generated/Models/Error.cs +++ b/test/TestServerProjects/lro-parameterized-endpoints/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace lro_parameterized_endpoints.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/lro-parameterized-endpoints/lro_parameterized_endpoints.csproj b/test/TestServerProjects/lro-parameterized-endpoints/lro_parameterized_endpoints.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/lro-parameterized-endpoints/lro_parameterized_endpoints.csproj +++ b/test/TestServerProjects/lro-parameterized-endpoints/lro_parameterized_endpoints.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/lro/Generated/Configuration.json b/test/TestServerProjects/lro/Generated/Configuration.json index 9a43e37f0ff..76dd48f6886 100644 --- a/test/TestServerProjects/lro/Generated/Configuration.json +++ b/test/TestServerProjects/lro/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/lro/Generated/LroModelFactory.cs b/test/TestServerProjects/lro/Generated/LroModelFactory.cs index 7cbf6ffdf2a..3c61c023e94 100644 --- a/test/TestServerProjects/lro/Generated/LroModelFactory.cs +++ b/test/TestServerProjects/lro/Generated/LroModelFactory.cs @@ -25,7 +25,7 @@ public static Product Product(string id = null, string type = null, IDictionary< { tags ??= new Dictionary(); - return new Product(id, type, tags, location, name, provisioningState, provisioningStateValues); + return new Product(id, type, tags, location, name, serializedAdditionalRawData: null, provisioningState, provisioningStateValues); } /// Initializes a new instance of . @@ -39,7 +39,7 @@ public static Resource Resource(string id = null, string type = null, IDictionar { tags ??= new Dictionary(); - return new Resource(id, type, tags, location, name); + return new Resource(id, type, tags, location, name, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -49,7 +49,7 @@ public static Resource Resource(string id = null, string type = null, IDictionar /// A new instance for mocking. public static SubProduct SubProduct(string id = null, string provisioningState = null, SubProductPropertiesProvisioningStateValues? provisioningStateValues = null) { - return new SubProduct(id, provisioningState, provisioningStateValues); + return new SubProduct(id, serializedAdditionalRawData: null, provisioningState, provisioningStateValues); } /// Initializes a new instance of . @@ -57,7 +57,7 @@ public static SubProduct SubProduct(string id = null, string provisioningState = /// A new instance for mocking. public static SubResource SubResource(string id = null) { - return new SubResource(id); + return new SubResource(id, serializedAdditionalRawData: null); } } } diff --git a/test/TestServerProjects/lro/Generated/Models/CloudError.Serialization.cs b/test/TestServerProjects/lro/Generated/Models/CloudError.Serialization.cs index f620a57ea24..b2c6bd03007 100644 --- a/test/TestServerProjects/lro/Generated/Models/CloudError.Serialization.cs +++ b/test/TestServerProjects/lro/Generated/Models/CloudError.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace lro.Models { - internal partial class CloudError + internal partial class CloudError : IUtf8JsonSerializable, IJsonModel { - internal static CloudError DeserializeCloudError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(CloudError)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Code)) + { + writer.WritePropertyName("code"u8); + writer.WriteNumberValue(Code.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + CloudError IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(CloudError)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeCloudError(document.RootElement, options); + } + + internal static CloudError DeserializeCloudError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional code = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("code"u8)) @@ -36,8 +94,44 @@ internal static CloudError DeserializeCloudError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new CloudError(Optional.ToNullable(code), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(CloudError)} does not support '{options.Format}' format."); + } + } + + CloudError IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeCloudError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(CloudError)} does not support '{options.Format}' format."); } - return new CloudError(Optional.ToNullable(code), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/lro/Generated/Models/CloudError.cs b/test/TestServerProjects/lro/Generated/Models/CloudError.cs index 68930d82fb1..4300bc88a1d 100644 --- a/test/TestServerProjects/lro/Generated/Models/CloudError.cs +++ b/test/TestServerProjects/lro/Generated/Models/CloudError.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace lro.Models { /// The CloudError. internal partial class CloudError { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal CloudError() { @@ -18,10 +53,12 @@ internal CloudError() /// Initializes a new instance of . /// /// - internal CloudError(int? code, string message) + /// Keeps track of any properties unknown to the library. + internal CloudError(int? code, string message, IDictionary serializedAdditionalRawData) { Code = code; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the code. diff --git a/test/TestServerProjects/lro/Generated/Models/OperationResult.cs b/test/TestServerProjects/lro/Generated/Models/OperationResult.cs index 141d3de90dd..129d4634f47 100644 --- a/test/TestServerProjects/lro/Generated/Models/OperationResult.cs +++ b/test/TestServerProjects/lro/Generated/Models/OperationResult.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace lro.Models { /// The OperationResult. internal partial class OperationResult { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal OperationResult() { @@ -18,10 +53,12 @@ internal OperationResult() /// Initializes a new instance of . /// The status of the request. /// - internal OperationResult(OperationResultStatus? status, OperationResultError error) + /// Keeps track of any properties unknown to the library. + internal OperationResult(OperationResultStatus? status, OperationResultError error, IDictionary serializedAdditionalRawData) { Status = status; Error = error; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// The status of the request. diff --git a/test/TestServerProjects/lro/Generated/Models/OperationResultError.cs b/test/TestServerProjects/lro/Generated/Models/OperationResultError.cs index 3fabc49c3b4..b530c61a8dc 100644 --- a/test/TestServerProjects/lro/Generated/Models/OperationResultError.cs +++ b/test/TestServerProjects/lro/Generated/Models/OperationResultError.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace lro.Models { /// The OperationResultError. internal partial class OperationResultError { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal OperationResultError() { @@ -18,10 +53,12 @@ internal OperationResultError() /// Initializes a new instance of . /// The error code for an operation failure. /// The detailed arror message. - internal OperationResultError(int? code, string message) + /// Keeps track of any properties unknown to the library. + internal OperationResultError(int? code, string message, IDictionary serializedAdditionalRawData) { Code = code; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// The error code for an operation failure. diff --git a/test/TestServerProjects/lro/Generated/Models/Product.Serialization.cs b/test/TestServerProjects/lro/Generated/Models/Product.Serialization.cs index 79e68829faf..e7e2485f158 100644 --- a/test/TestServerProjects/lro/Generated/Models/Product.Serialization.cs +++ b/test/TestServerProjects/lro/Generated/Models/Product.Serialization.cs @@ -5,17 +5,37 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace lro.Models { - public partial class Product : IUtf8JsonSerializable + public partial class Product : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + writer.WriteStartObject(); + if (options.Format != "W" && Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (options.Format != "W" && Optional.IsDefined(Type)) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + } if (Optional.IsCollectionDefined(Tags)) { writer.WritePropertyName("tags"u8); @@ -32,6 +52,11 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("location"u8); writer.WriteStringValue(Location); } + if (options.Format != "W" && Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } writer.WritePropertyName("properties"u8); writer.WriteStartObject(); if (Optional.IsDefined(ProvisioningState)) @@ -39,12 +64,46 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("provisioningState"u8); writer.WriteStringValue(ProvisioningState); } + if (options.Format != "W" && Optional.IsDefined(ProvisioningStateValues)) + { + writer.WritePropertyName("provisioningStateValues"u8); + writer.WriteStringValue(ProvisioningStateValues.Value.ToString()); + } writer.WriteEndObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Product DeserializeProduct(JsonElement element) + Product IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProduct(document.RootElement, options); + } + + internal static Product DeserializeProduct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -56,6 +115,8 @@ internal static Product DeserializeProduct(JsonElement element) Optional name = default; Optional provisioningState = default; Optional provisioningStateValues = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -118,8 +179,44 @@ internal static Product DeserializeProduct(JsonElement element) } continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Product(id.Value, type.Value, Optional.ToDictionary(tags), location.Value, name.Value, provisioningState.Value, Optional.ToNullable(provisioningStateValues)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Product(id.Value, type.Value, Optional.ToDictionary(tags), location.Value, name.Value, serializedAdditionalRawData, provisioningState.Value, Optional.ToNullable(provisioningStateValues)); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + Product IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/lro/Generated/Models/Product.cs b/test/TestServerProjects/lro/Generated/Models/Product.cs index 608482d2a87..83617a3492a 100644 --- a/test/TestServerProjects/lro/Generated/Models/Product.cs +++ b/test/TestServerProjects/lro/Generated/Models/Product.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; namespace lro.Models @@ -23,9 +24,10 @@ public Product() /// Dictionary of <string>. /// Resource Location. /// Resource Name. + /// Keeps track of any properties unknown to the library. /// /// - internal Product(string id, string type, IDictionary tags, string location, string name, string provisioningState, ProductPropertiesProvisioningStateValues? provisioningStateValues) : base(id, type, tags, location, name) + internal Product(string id, string type, IDictionary tags, string location, string name, IDictionary serializedAdditionalRawData, string provisioningState, ProductPropertiesProvisioningStateValues? provisioningStateValues) : base(id, type, tags, location, name, serializedAdditionalRawData) { ProvisioningState = provisioningState; ProvisioningStateValues = provisioningStateValues; diff --git a/test/TestServerProjects/lro/Generated/Models/Resource.Serialization.cs b/test/TestServerProjects/lro/Generated/Models/Resource.Serialization.cs index 1bf057a6d38..d2a99d29683 100644 --- a/test/TestServerProjects/lro/Generated/Models/Resource.Serialization.cs +++ b/test/TestServerProjects/lro/Generated/Models/Resource.Serialization.cs @@ -5,17 +5,37 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace lro.Models { - public partial class Resource : IUtf8JsonSerializable + public partial class Resource : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Resource)} does not support '{format}' format."); + } + writer.WriteStartObject(); + if (options.Format != "W" && Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (options.Format != "W" && Optional.IsDefined(Type)) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + } if (Optional.IsCollectionDefined(Tags)) { writer.WritePropertyName("tags"u8); @@ -32,11 +52,45 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("location"u8); writer.WriteStringValue(Location); } + if (options.Format != "W" && Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Resource DeserializeResource(JsonElement element) + Resource IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Resource)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResource(document.RootElement, options); + } + + internal static Resource DeserializeResource(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -46,6 +100,8 @@ internal static Resource DeserializeResource(JsonElement element) Optional> tags = default; Optional location = default; Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -82,8 +138,44 @@ internal static Resource DeserializeResource(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Resource(id.Value, type.Value, Optional.ToDictionary(tags), location.Value, name.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Resource)} does not support '{options.Format}' format."); + } + } + + Resource IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeResource(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Resource)} does not support '{options.Format}' format."); } - return new Resource(id.Value, type.Value, Optional.ToDictionary(tags), location.Value, name.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/lro/Generated/Models/Resource.cs b/test/TestServerProjects/lro/Generated/Models/Resource.cs index 537b2da6103..33b4b932de3 100644 --- a/test/TestServerProjects/lro/Generated/Models/Resource.cs +++ b/test/TestServerProjects/lro/Generated/Models/Resource.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace lro.Models /// The Resource. public partial class Resource { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Resource() { @@ -25,13 +58,15 @@ public Resource() /// Dictionary of <string>. /// Resource Location. /// Resource Name. - internal Resource(string id, string type, IDictionary tags, string location, string name) + /// Keeps track of any properties unknown to the library. + internal Resource(string id, string type, IDictionary tags, string location, string name, IDictionary serializedAdditionalRawData) { Id = id; Type = type; Tags = tags; Location = location; Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Resource Id. diff --git a/test/TestServerProjects/lro/Generated/Models/Sku.Serialization.cs b/test/TestServerProjects/lro/Generated/Models/Sku.Serialization.cs index ca47989357c..a66f98df732 100644 --- a/test/TestServerProjects/lro/Generated/Models/Sku.Serialization.cs +++ b/test/TestServerProjects/lro/Generated/Models/Sku.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace lro.Models { - public partial class Sku : IUtf8JsonSerializable + public partial class Sku : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Sku)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Name)) { @@ -25,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("id"u8); writer.WriteStringValue(Id); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Sku DeserializeSku(JsonElement element) + Sku IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Sku)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSku(document.RootElement, options); + } + + internal static Sku DeserializeSku(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional name = default; Optional id = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("name"u8)) @@ -48,8 +90,44 @@ internal static Sku DeserializeSku(JsonElement element) id = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Sku(name.Value, id.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Sku)} does not support '{options.Format}' format."); } - return new Sku(name.Value, id.Value); } + + Sku IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSku(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Sku)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/lro/Generated/Models/Sku.cs b/test/TestServerProjects/lro/Generated/Models/Sku.cs index 94867de0bc8..7181787f1ff 100644 --- a/test/TestServerProjects/lro/Generated/Models/Sku.cs +++ b/test/TestServerProjects/lro/Generated/Models/Sku.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace lro.Models { /// The Sku. public partial class Sku { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Sku() { @@ -18,10 +53,12 @@ public Sku() /// Initializes a new instance of . /// /// - internal Sku(string name, string id) + /// Keeps track of any properties unknown to the library. + internal Sku(string name, string id, IDictionary serializedAdditionalRawData) { Name = name; Id = id; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the name. diff --git a/test/TestServerProjects/lro/Generated/Models/SubProduct.Serialization.cs b/test/TestServerProjects/lro/Generated/Models/SubProduct.Serialization.cs index 078ffe3ef9f..9cd2520da20 100644 --- a/test/TestServerProjects/lro/Generated/Models/SubProduct.Serialization.cs +++ b/test/TestServerProjects/lro/Generated/Models/SubProduct.Serialization.cs @@ -5,16 +5,32 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace lro.Models { - public partial class SubProduct : IUtf8JsonSerializable + public partial class SubProduct : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SubProduct)} does not support '{format}' format."); + } + writer.WriteStartObject(); + if (options.Format != "W" && Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } writer.WritePropertyName("properties"u8); writer.WriteStartObject(); if (Optional.IsDefined(ProvisioningState)) @@ -22,12 +38,46 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("provisioningState"u8); writer.WriteStringValue(ProvisioningState); } + if (options.Format != "W" && Optional.IsDefined(ProvisioningStateValues)) + { + writer.WritePropertyName("provisioningStateValues"u8); + writer.WriteStringValue(ProvisioningStateValues.Value.ToString()); + } writer.WriteEndObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static SubProduct DeserializeSubProduct(JsonElement element) + SubProduct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SubProduct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSubProduct(document.RootElement, options); + } + + internal static SubProduct DeserializeSubProduct(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -35,6 +85,8 @@ internal static SubProduct DeserializeSubProduct(JsonElement element) Optional id = default; Optional provisioningState = default; Optional provisioningStateValues = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -68,8 +120,44 @@ internal static SubProduct DeserializeSubProduct(JsonElement element) } continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new SubProduct(id.Value, serializedAdditionalRawData, provisioningState.Value, Optional.ToNullable(provisioningStateValues)); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(SubProduct)} does not support '{options.Format}' format."); } - return new SubProduct(id.Value, provisioningState.Value, Optional.ToNullable(provisioningStateValues)); } + + SubProduct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSubProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SubProduct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/lro/Generated/Models/SubProduct.cs b/test/TestServerProjects/lro/Generated/Models/SubProduct.cs index 9b681ae2af2..8e9e2c13ca6 100644 --- a/test/TestServerProjects/lro/Generated/Models/SubProduct.cs +++ b/test/TestServerProjects/lro/Generated/Models/SubProduct.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace lro.Models { /// The SubProduct. @@ -17,9 +20,10 @@ public SubProduct() /// Initializes a new instance of . /// Sub Resource Id. + /// Keeps track of any properties unknown to the library. /// /// - internal SubProduct(string id, string provisioningState, SubProductPropertiesProvisioningStateValues? provisioningStateValues) : base(id) + internal SubProduct(string id, IDictionary serializedAdditionalRawData, string provisioningState, SubProductPropertiesProvisioningStateValues? provisioningStateValues) : base(id, serializedAdditionalRawData) { ProvisioningState = provisioningState; ProvisioningStateValues = provisioningStateValues; diff --git a/test/TestServerProjects/lro/Generated/Models/SubResource.Serialization.cs b/test/TestServerProjects/lro/Generated/Models/SubResource.Serialization.cs index 791a2135153..30ec62d0030 100644 --- a/test/TestServerProjects/lro/Generated/Models/SubResource.Serialization.cs +++ b/test/TestServerProjects/lro/Generated/Models/SubResource.Serialization.cs @@ -5,26 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace lro.Models { - public partial class SubResource : IUtf8JsonSerializable + public partial class SubResource : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SubResource)} does not support '{format}' format."); + } + writer.WriteStartObject(); + if (options.Format != "W" && Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static SubResource DeserializeSubResource(JsonElement element) + SubResource IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SubResource)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSubResource(document.RootElement, options); + } + + internal static SubResource DeserializeSubResource(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional id = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -32,8 +79,44 @@ internal static SubResource DeserializeSubResource(JsonElement element) id = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new SubResource(id.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(SubResource)} does not support '{options.Format}' format."); + } + } + + SubResource IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSubResource(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SubResource)} does not support '{options.Format}' format."); } - return new SubResource(id.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/lro/Generated/Models/SubResource.cs b/test/TestServerProjects/lro/Generated/Models/SubResource.cs index c96d7959dec..51bb35c0922 100644 --- a/test/TestServerProjects/lro/Generated/Models/SubResource.cs +++ b/test/TestServerProjects/lro/Generated/Models/SubResource.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace lro.Models { /// The SubResource. public partial class SubResource { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public SubResource() { @@ -17,9 +52,11 @@ public SubResource() /// Initializes a new instance of . /// Sub Resource Id. - internal SubResource(string id) + /// Keeps track of any properties unknown to the library. + internal SubResource(string id, IDictionary serializedAdditionalRawData) { Id = id; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Sub Resource Id. diff --git a/test/TestServerProjects/lro/lro.csproj b/test/TestServerProjects/lro/lro.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/lro/lro.csproj +++ b/test/TestServerProjects/lro/lro.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/media_types/Generated/Configuration.json b/test/TestServerProjects/media_types/Generated/Configuration.json index 42addd645a7..07fc7cdc17a 100644 --- a/test/TestServerProjects/media_types/Generated/Configuration.json +++ b/test/TestServerProjects/media_types/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/media_types/Generated/Models/SourcePath.Serialization.cs b/test/TestServerProjects/media_types/Generated/Models/SourcePath.Serialization.cs index 990dbba414b..fa8f369044b 100644 --- a/test/TestServerProjects/media_types/Generated/Models/SourcePath.Serialization.cs +++ b/test/TestServerProjects/media_types/Generated/Models/SourcePath.Serialization.cs @@ -5,22 +5,118 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace media_types.Models { - public partial class SourcePath : IUtf8JsonSerializable + public partial class SourcePath : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SourcePath)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Source)) { writer.WritePropertyName("source"u8); writer.WriteStringValue(Source); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + SourcePath IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SourcePath)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSourcePath(document.RootElement, options); + } + + internal static SourcePath DeserializeSourcePath(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional source = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("source"u8)) + { + source = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new SourcePath(source.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(SourcePath)} does not support '{options.Format}' format."); + } + } + + SourcePath IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSourcePath(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SourcePath)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/media_types/Generated/Models/SourcePath.cs b/test/TestServerProjects/media_types/Generated/Models/SourcePath.cs index 25f1c178cb4..cc3005a5d4f 100644 --- a/test/TestServerProjects/media_types/Generated/Models/SourcePath.cs +++ b/test/TestServerProjects/media_types/Generated/Models/SourcePath.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace media_types.Models { /// Uri or local path to source data. public partial class SourcePath { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public SourcePath() { @@ -17,9 +52,11 @@ public SourcePath() /// Initializes a new instance of . /// File source path. - internal SourcePath(string source) + /// Keeps track of any properties unknown to the library. + internal SourcePath(string source, IDictionary serializedAdditionalRawData) { Source = source; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// File source path. diff --git a/test/TestServerProjects/media_types/media_types.csproj b/test/TestServerProjects/media_types/media_types.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/media_types/media_types.csproj +++ b/test/TestServerProjects/media_types/media_types.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/model-flattening/Generated/Configuration.json b/test/TestServerProjects/model-flattening/Generated/Configuration.json index 726ff9993b9..a1f63d6c9b0 100644 --- a/test/TestServerProjects/model-flattening/Generated/Configuration.json +++ b/test/TestServerProjects/model-flattening/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/model-flattening/Generated/ModelFlatteningModelFactory.cs b/test/TestServerProjects/model-flattening/Generated/ModelFlatteningModelFactory.cs index 84a5965c311..589b10c5344 100644 --- a/test/TestServerProjects/model-flattening/Generated/ModelFlatteningModelFactory.cs +++ b/test/TestServerProjects/model-flattening/Generated/ModelFlatteningModelFactory.cs @@ -23,7 +23,7 @@ public static Resource Resource(string id = null, string type = null, IDictionar { tags ??= new Dictionary(); - return new Resource(id, type, tags, location, name); + return new Resource(id, type, tags, location, name, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -41,7 +41,7 @@ public static FlattenedProduct FlattenedProduct(string id = null, string type = { tags ??= new Dictionary(); - return new FlattenedProduct(id, type, tags, location, name, pName, typePropertiesType, provisioningStateValues, provisioningState); + return new FlattenedProduct(id, type, tags, location, name, serializedAdditionalRawData: null, pName, typePropertiesType, provisioningStateValues, provisioningState); } /// Initializes a new instance of . @@ -49,7 +49,22 @@ public static FlattenedProduct FlattenedProduct(string id = null, string type = /// A new instance for mocking. public static ProductWrapper ProductWrapper(string value = null) { - return new ProductWrapper(value); + return new ProductWrapper(value, serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// Product name with value 'groupproduct'. + /// Simple body product to put. + /// Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles. + /// Description of product. + /// Display name of product. + /// Capacity of product. For example, 4 people. + /// Generic URL value. + /// URL value. + /// A new instance for mocking. + public static FlattenParameterGroup FlattenParameterGroup(string name = null, SimpleProduct simpleBodyProduct = null, string productId = null, string description = null, string maxProductDisplayName = null, SimpleProductPropertiesMaxProductCapacity? capacity = null, string genericValue = null, string odataValue = null) + { + return new FlattenParameterGroup(name, simpleBodyProduct, productId, description, maxProductDisplayName, capacity, genericValue, odataValue, serializedAdditionalRawData: null); } } } diff --git a/test/TestServerProjects/model-flattening/Generated/Models/BaseProduct.Serialization.cs b/test/TestServerProjects/model-flattening/Generated/Models/BaseProduct.Serialization.cs index b8a68aad4cc..a636d91124d 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/BaseProduct.Serialization.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/BaseProduct.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace model_flattening.Models { - public partial class BaseProduct : IUtf8JsonSerializable + public partial class BaseProduct : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseProduct)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("base_product_id"u8); writer.WriteStringValue(ProductId); @@ -22,17 +33,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("base_product_description"u8); writer.WriteStringValue(Description); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static BaseProduct DeserializeBaseProduct(JsonElement element) + BaseProduct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseProduct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeBaseProduct(document.RootElement, options); + } + + internal static BaseProduct DeserializeBaseProduct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } string baseProductId = default; Optional baseProductDescription = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("base_product_id"u8)) @@ -45,8 +87,44 @@ internal static BaseProduct DeserializeBaseProduct(JsonElement element) baseProductDescription = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new BaseProduct(baseProductId, baseProductDescription.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(BaseProduct)} does not support '{options.Format}' format."); } - return new BaseProduct(baseProductId, baseProductDescription.Value); } + + BaseProduct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeBaseProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(BaseProduct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/model-flattening/Generated/Models/BaseProduct.cs b/test/TestServerProjects/model-flattening/Generated/Models/BaseProduct.cs index b088811b6b1..44a09156031 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/BaseProduct.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/BaseProduct.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace model_flattening.Models @@ -13,6 +14,38 @@ namespace model_flattening.Models /// The product documentation. public partial class BaseProduct { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles. /// is null. @@ -26,10 +59,17 @@ public BaseProduct(string productId) /// Initializes a new instance of . /// Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles. /// Description of product. - internal BaseProduct(string productId, string description) + /// Keeps track of any properties unknown to the library. + internal BaseProduct(string productId, string description, IDictionary serializedAdditionalRawData) { ProductId = productId; Description = description; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal BaseProduct() + { } /// Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles. diff --git a/test/TestServerProjects/model-flattening/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/model-flattening/Generated/Models/Error.Serialization.cs index e31dcfa879a..8241553cc61 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/Error.Serialization.cs @@ -5,15 +5,76 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace model_flattening.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (Optional.IsDefined(ParentError)) + { + writer.WritePropertyName("parentError"u8); + writer.WriteObjectValue(ParentError); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -21,6 +82,8 @@ internal static Error DeserializeError(JsonElement element) Optional status = default; Optional message = default; Optional parentError = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -46,8 +109,44 @@ internal static Error DeserializeError(JsonElement element) parentError = DeserializeError(property.Value); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Error(Optional.ToNullable(status), message.Value, parentError.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, parentError.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/model-flattening/Generated/Models/Error.cs b/test/TestServerProjects/model-flattening/Generated/Models/Error.cs index c4d5a64e6fb..f6b6983c963 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/Error.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace model_flattening.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -19,11 +54,13 @@ internal Error() /// /// /// - internal Error(int? status, string message, Error parentError) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, Error parentError, IDictionary serializedAdditionalRawData) { Status = status; Message = message; ParentError = parentError; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/model-flattening/Generated/Models/FlattenParameterGroup.cs b/test/TestServerProjects/model-flattening/Generated/Models/FlattenParameterGroup.cs index 9c7fe4d18a7..06a70372ae1 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/FlattenParameterGroup.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/FlattenParameterGroup.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace model_flattening.Models @@ -13,6 +14,38 @@ namespace model_flattening.Models /// Parameter group. public partial class FlattenParameterGroup { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Product name with value 'groupproduct'. /// Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles. @@ -35,7 +68,8 @@ public FlattenParameterGroup(string name, string productId) /// Capacity of product. For example, 4 people. /// Generic URL value. /// URL value. - internal FlattenParameterGroup(string name, SimpleProduct simpleBodyProduct, string productId, string description, string maxProductDisplayName, SimpleProductPropertiesMaxProductCapacity? capacity, string genericValue, string odataValue) + /// Keeps track of any properties unknown to the library. + internal FlattenParameterGroup(string name, SimpleProduct simpleBodyProduct, string productId, string description, string maxProductDisplayName, SimpleProductPropertiesMaxProductCapacity? capacity, string genericValue, string odataValue, IDictionary serializedAdditionalRawData) { Name = name; SimpleBodyProduct = simpleBodyProduct; @@ -45,6 +79,12 @@ internal FlattenParameterGroup(string name, SimpleProduct simpleBodyProduct, str Capacity = capacity; GenericValue = genericValue; OdataValue = odataValue; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal FlattenParameterGroup() + { } /// Product name with value 'groupproduct'. diff --git a/test/TestServerProjects/model-flattening/Generated/Models/FlattenedProduct.Serialization.cs b/test/TestServerProjects/model-flattening/Generated/Models/FlattenedProduct.Serialization.cs index c45f3a4e744..0cf60db39e4 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/FlattenedProduct.Serialization.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/FlattenedProduct.Serialization.cs @@ -5,17 +5,37 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace model_flattening.Models { - public partial class FlattenedProduct : IUtf8JsonSerializable + public partial class FlattenedProduct : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(FlattenedProduct)} does not support '{format}' format."); + } + writer.WriteStartObject(); + if (options.Format != "W" && Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (options.Format != "W" && Optional.IsDefined(Type)) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + } if (Optional.IsCollectionDefined(Tags)) { writer.WritePropertyName("tags"u8); @@ -32,6 +52,11 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("location"u8); writer.WriteStringValue(Location); } + if (options.Format != "W" && Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } writer.WritePropertyName("properties"u8); writer.WriteStartObject(); if (Optional.IsDefined(PName)) @@ -44,17 +69,51 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("type"u8); writer.WriteStringValue(TypePropertiesType); } + if (options.Format != "W" && Optional.IsDefined(ProvisioningStateValues)) + { + writer.WritePropertyName("provisioningStateValues"u8); + writer.WriteStringValue(ProvisioningStateValues.Value.ToString()); + } if (Optional.IsDefined(ProvisioningState)) { writer.WritePropertyName("provisioningState"u8); writer.WriteStringValue(ProvisioningState); } writer.WriteEndObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static FlattenedProduct DeserializeFlattenedProduct(JsonElement element) + FlattenedProduct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(FlattenedProduct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeFlattenedProduct(document.RootElement, options); + } + + internal static FlattenedProduct DeserializeFlattenedProduct(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -68,6 +127,8 @@ internal static FlattenedProduct DeserializeFlattenedProduct(JsonElement element Optional type0 = default; Optional provisioningStateValues = default; Optional provisioningState = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -140,8 +201,44 @@ internal static FlattenedProduct DeserializeFlattenedProduct(JsonElement element } continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new FlattenedProduct(id.Value, type.Value, Optional.ToDictionary(tags), location.Value, name.Value, serializedAdditionalRawData, pName.Value, type0.Value, Optional.ToNullable(provisioningStateValues), provisioningState.Value); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(FlattenedProduct)} does not support '{options.Format}' format."); } - return new FlattenedProduct(id.Value, type.Value, Optional.ToDictionary(tags), location.Value, name.Value, pName.Value, type0.Value, Optional.ToNullable(provisioningStateValues), provisioningState.Value); } + + FlattenedProduct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeFlattenedProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(FlattenedProduct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/model-flattening/Generated/Models/FlattenedProduct.cs b/test/TestServerProjects/model-flattening/Generated/Models/FlattenedProduct.cs index 35714f499dc..1c95e0ac931 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/FlattenedProduct.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/FlattenedProduct.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; namespace model_flattening.Models @@ -23,11 +24,12 @@ public FlattenedProduct() /// Dictionary of <string>. /// Resource Location. /// Resource Name. + /// Keeps track of any properties unknown to the library. /// /// /// /// - internal FlattenedProduct(string id, string type, IDictionary tags, string location, string name, string pName, string typePropertiesType, FlattenedProductPropertiesProvisioningStateValues? provisioningStateValues, string provisioningState) : base(id, type, tags, location, name) + internal FlattenedProduct(string id, string type, IDictionary tags, string location, string name, IDictionary serializedAdditionalRawData, string pName, string typePropertiesType, FlattenedProductPropertiesProvisioningStateValues? provisioningStateValues, string provisioningState) : base(id, type, tags, location, name, serializedAdditionalRawData) { PName = pName; TypePropertiesType = typePropertiesType; diff --git a/test/TestServerProjects/model-flattening/Generated/Models/GenericUrl.Serialization.cs b/test/TestServerProjects/model-flattening/Generated/Models/GenericUrl.Serialization.cs new file mode 100644 index 00000000000..6d5cb673aae --- /dev/null +++ b/test/TestServerProjects/model-flattening/Generated/Models/GenericUrl.Serialization.cs @@ -0,0 +1,122 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure.Core; + +namespace model_flattening.Models +{ + internal partial class GenericUrl : IUtf8JsonSerializable, IJsonModel + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(GenericUrl)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(GenericValue)) + { + writer.WritePropertyName("generic_value"u8); + writer.WriteStringValue(GenericValue); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + GenericUrl IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(GenericUrl)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeGenericUrl(document.RootElement, options); + } + + internal static GenericUrl DeserializeGenericUrl(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional genericValue = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("generic_value"u8)) + { + genericValue = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new GenericUrl(genericValue.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(GenericUrl)} does not support '{options.Format}' format."); + } + } + + GenericUrl IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeGenericUrl(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(GenericUrl)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/test/TestServerProjects/model-flattening/Generated/Models/GenericUrl.cs b/test/TestServerProjects/model-flattening/Generated/Models/GenericUrl.cs index 6e13f394dab..34fef587c25 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/GenericUrl.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/GenericUrl.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace model_flattening.Models { /// The Generic URL. internal partial class GenericUrl { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal GenericUrl() { @@ -17,9 +52,11 @@ internal GenericUrl() /// Initializes a new instance of . /// Generic URL value. - internal GenericUrl(string genericValue) + /// Keeps track of any properties unknown to the library. + internal GenericUrl(string genericValue, IDictionary serializedAdditionalRawData) { GenericValue = genericValue; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Generic URL value. diff --git a/test/TestServerProjects/model-flattening/Generated/Models/ProductUrl.Serialization.cs b/test/TestServerProjects/model-flattening/Generated/Models/ProductUrl.Serialization.cs new file mode 100644 index 00000000000..8d6d744287d --- /dev/null +++ b/test/TestServerProjects/model-flattening/Generated/Models/ProductUrl.Serialization.cs @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure.Core; + +namespace model_flattening.Models +{ + internal partial class ProductUrl : IUtf8JsonSerializable, IJsonModel + { + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductUrl)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(OdataValue)) + { + writer.WritePropertyName("@odata.value"u8); + writer.WriteStringValue(OdataValue); + } + if (Optional.IsDefined(GenericValue)) + { + writer.WritePropertyName("generic_value"u8); + writer.WriteStringValue(GenericValue); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ProductUrl IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductUrl)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProductUrl(document.RootElement, options); + } + + internal static ProductUrl DeserializeProductUrl(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional odataValue = default; + Optional genericValue = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("@odata.value"u8)) + { + odataValue = property.Value.GetString(); + continue; + } + if (property.NameEquals("generic_value"u8)) + { + genericValue = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ProductUrl(genericValue.Value, serializedAdditionalRawData, odataValue.Value); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ProductUrl)} does not support '{options.Format}' format."); + } + } + + ProductUrl IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProductUrl(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ProductUrl)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/test/TestServerProjects/model-flattening/Generated/Models/ProductUrl.cs b/test/TestServerProjects/model-flattening/Generated/Models/ProductUrl.cs index b1bca68bae8..182252399d3 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/ProductUrl.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/ProductUrl.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace model_flattening.Models { /// The product URL. @@ -17,8 +20,9 @@ internal ProductUrl() /// Initializes a new instance of . /// Generic URL value. + /// Keeps track of any properties unknown to the library. /// URL value. - internal ProductUrl(string genericValue, string odataValue) : base(genericValue) + internal ProductUrl(string genericValue, IDictionary serializedAdditionalRawData, string odataValue) : base(genericValue, serializedAdditionalRawData) { OdataValue = odataValue; } diff --git a/test/TestServerProjects/model-flattening/Generated/Models/ProductWrapper.Serialization.cs b/test/TestServerProjects/model-flattening/Generated/Models/ProductWrapper.Serialization.cs index c312ad10745..8fe12e78303 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/ProductWrapper.Serialization.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/ProductWrapper.Serialization.cs @@ -5,20 +5,76 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace model_flattening.Models { - public partial class ProductWrapper + public partial class ProductWrapper : IUtf8JsonSerializable, IJsonModel { - internal static ProductWrapper DeserializeProductWrapper(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductWrapper)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("property"u8); + writer.WriteStartObject(); + if (Optional.IsDefined(Value)) + { + writer.WritePropertyName("value"u8); + writer.WriteStringValue(Value); + } + writer.WriteEndObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ProductWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProductWrapper(document.RootElement, options); + } + + internal static ProductWrapper DeserializeProductWrapper(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("property"u8)) @@ -38,8 +94,44 @@ internal static ProductWrapper DeserializeProductWrapper(JsonElement element) } continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ProductWrapper(value.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ProductWrapper)} does not support '{options.Format}' format."); } - return new ProductWrapper(value.Value); } + + ProductWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProductWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ProductWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/model-flattening/Generated/Models/ProductWrapper.cs b/test/TestServerProjects/model-flattening/Generated/Models/ProductWrapper.cs index 5d2bd820a08..4474539bd9c 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/ProductWrapper.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/ProductWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace model_flattening.Models { /// The wrapped produc. public partial class ProductWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ProductWrapper() { @@ -17,9 +52,11 @@ internal ProductWrapper() /// Initializes a new instance of . /// the product value. - internal ProductWrapper(string value) + /// Keeps track of any properties unknown to the library. + internal ProductWrapper(string value, IDictionary serializedAdditionalRawData) { Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// the product value. diff --git a/test/TestServerProjects/model-flattening/Generated/Models/Resource.Serialization.cs b/test/TestServerProjects/model-flattening/Generated/Models/Resource.Serialization.cs index 30b2943107a..e877378d006 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/Resource.Serialization.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/Resource.Serialization.cs @@ -5,17 +5,37 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace model_flattening.Models { - public partial class Resource : IUtf8JsonSerializable + public partial class Resource : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Resource)} does not support '{format}' format."); + } + writer.WriteStartObject(); + if (options.Format != "W" && Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (options.Format != "W" && Optional.IsDefined(Type)) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + } if (Optional.IsCollectionDefined(Tags)) { writer.WritePropertyName("tags"u8); @@ -32,11 +52,45 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("location"u8); writer.WriteStringValue(Location); } + if (options.Format != "W" && Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Resource DeserializeResource(JsonElement element) + Resource IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Resource)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResource(document.RootElement, options); + } + + internal static Resource DeserializeResource(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -46,6 +100,8 @@ internal static Resource DeserializeResource(JsonElement element) Optional> tags = default; Optional location = default; Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -82,8 +138,44 @@ internal static Resource DeserializeResource(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Resource(id.Value, type.Value, Optional.ToDictionary(tags), location.Value, name.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Resource)} does not support '{options.Format}' format."); + } + } + + Resource IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeResource(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Resource)} does not support '{options.Format}' format."); } - return new Resource(id.Value, type.Value, Optional.ToDictionary(tags), location.Value, name.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/model-flattening/Generated/Models/Resource.cs b/test/TestServerProjects/model-flattening/Generated/Models/Resource.cs index b1d345210d2..968dab994f1 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/Resource.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/Resource.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace model_flattening.Models /// The Resource. public partial class Resource { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Resource() { @@ -25,13 +58,15 @@ public Resource() /// Dictionary of <string>. /// Resource Location. /// Resource Name. - internal Resource(string id, string type, IDictionary tags, string location, string name) + /// Keeps track of any properties unknown to the library. + internal Resource(string id, string type, IDictionary tags, string location, string name, IDictionary serializedAdditionalRawData) { Id = id; Type = type; Tags = tags; Location = location; Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Resource Id. diff --git a/test/TestServerProjects/model-flattening/Generated/Models/ResourceCollection.Serialization.cs b/test/TestServerProjects/model-flattening/Generated/Models/ResourceCollection.Serialization.cs index a03776f81ed..e6daf6deb49 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/ResourceCollection.Serialization.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/ResourceCollection.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace model_flattening.Models { - public partial class ResourceCollection : IUtf8JsonSerializable + public partial class ResourceCollection : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResourceCollection)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Productresource)) { @@ -42,11 +52,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndObject(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ResourceCollection DeserializeResourceCollection(JsonElement element) + ResourceCollection IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResourceCollection)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResourceCollection(document.RootElement, options); + } + + internal static ResourceCollection DeserializeResourceCollection(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -54,6 +93,8 @@ internal static ResourceCollection DeserializeResourceCollection(JsonElement ele Optional productresource = default; Optional> arrayofresources = default; Optional> dictionaryofresources = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("productresource"u8)) @@ -93,8 +134,44 @@ internal static ResourceCollection DeserializeResourceCollection(JsonElement ele dictionaryofresources = dictionary; continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ResourceCollection(productresource.Value, Optional.ToList(arrayofresources), Optional.ToDictionary(dictionaryofresources)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ResourceCollection(productresource.Value, Optional.ToList(arrayofresources), Optional.ToDictionary(dictionaryofresources), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ResourceCollection)} does not support '{options.Format}' format."); + } + } + + ResourceCollection IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeResourceCollection(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResourceCollection)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/model-flattening/Generated/Models/ResourceCollection.cs b/test/TestServerProjects/model-flattening/Generated/Models/ResourceCollection.cs index b7d85e3b49a..fef1f7bed18 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/ResourceCollection.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/ResourceCollection.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace model_flattening.Models /// The ResourceCollection. public partial class ResourceCollection { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ResourceCollection() { @@ -24,11 +57,13 @@ public ResourceCollection() /// Flattened product. /// /// Dictionary of <FlattenedProduct>. - internal ResourceCollection(FlattenedProduct productresource, IList arrayofresources, IDictionary dictionaryofresources) + /// Keeps track of any properties unknown to the library. + internal ResourceCollection(FlattenedProduct productresource, IList arrayofresources, IDictionary dictionaryofresources, IDictionary serializedAdditionalRawData) { Productresource = productresource; Arrayofresources = arrayofresources; Dictionaryofresources = dictionaryofresources; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Flattened product. diff --git a/test/TestServerProjects/model-flattening/Generated/Models/SimpleProduct.Serialization.cs b/test/TestServerProjects/model-flattening/Generated/Models/SimpleProduct.Serialization.cs index bc4acfb5f66..91d940f7292 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/SimpleProduct.Serialization.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/SimpleProduct.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace model_flattening.Models { - public partial class SimpleProduct : IUtf8JsonSerializable + public partial class SimpleProduct : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SimpleProduct)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("base_product_id"u8); writer.WriteStringValue(ProductId); @@ -48,11 +59,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndObject(); writer.WriteEndObject(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static SimpleProduct DeserializeSimpleProduct(JsonElement element) + SimpleProduct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SimpleProduct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSimpleProduct(document.RootElement, options); + } + + internal static SimpleProduct DeserializeSimpleProduct(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -63,6 +103,8 @@ internal static SimpleProduct DeserializeSimpleProduct(JsonElement element) Optional maxProductCapacity = default; Optional genericValue = default; Optional odataValue = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("base_product_id"u8)) @@ -123,8 +165,44 @@ internal static SimpleProduct DeserializeSimpleProduct(JsonElement element) } continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new SimpleProduct(baseProductId, baseProductDescription.Value, maxProductDisplayName.Value, Optional.ToNullable(maxProductCapacity), genericValue.Value, odataValue.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new SimpleProduct(baseProductId, baseProductDescription.Value, serializedAdditionalRawData, maxProductDisplayName.Value, Optional.ToNullable(maxProductCapacity), genericValue.Value, odataValue.Value); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(SimpleProduct)} does not support '{options.Format}' format."); + } + } + + SimpleProduct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSimpleProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SimpleProduct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/model-flattening/Generated/Models/SimpleProduct.cs b/test/TestServerProjects/model-flattening/Generated/Models/SimpleProduct.cs index 31bb75a873d..248cd6fb966 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/SimpleProduct.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/SimpleProduct.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace model_flattening.Models @@ -24,11 +25,12 @@ public SimpleProduct(string productId) : base(productId) /// Initializes a new instance of . /// Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles. /// Description of product. + /// Keeps track of any properties unknown to the library. /// Display name of product. /// Capacity of product. For example, 4 people. /// Generic URL value. /// URL value. - internal SimpleProduct(string productId, string description, string maxProductDisplayName, SimpleProductPropertiesMaxProductCapacity? capacity, string genericValue, string odataValue) : base(productId, description) + internal SimpleProduct(string productId, string description, IDictionary serializedAdditionalRawData, string maxProductDisplayName, SimpleProductPropertiesMaxProductCapacity? capacity, string genericValue, string odataValue) : base(productId, description, serializedAdditionalRawData) { MaxProductDisplayName = maxProductDisplayName; Capacity = capacity; @@ -36,6 +38,11 @@ internal SimpleProduct(string productId, string description, string maxProductDi OdataValue = odataValue; } + /// Initializes a new instance of for deserialization. + internal SimpleProduct() + { + } + /// Display name of product. public string MaxProductDisplayName { get; set; } /// Capacity of product. For example, 4 people. diff --git a/test/TestServerProjects/model-flattening/Generated/Models/WrappedProduct.Serialization.cs b/test/TestServerProjects/model-flattening/Generated/Models/WrappedProduct.Serialization.cs index 50d3b793228..215170126d5 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/WrappedProduct.Serialization.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/WrappedProduct.Serialization.cs @@ -5,22 +5,118 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace model_flattening.Models { - public partial class WrappedProduct : IUtf8JsonSerializable + public partial class WrappedProduct : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(WrappedProduct)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Value)) { writer.WritePropertyName("value"u8); writer.WriteStringValue(Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + WrappedProduct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(WrappedProduct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeWrappedProduct(document.RootElement, options); + } + + internal static WrappedProduct DeserializeWrappedProduct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("value"u8)) + { + value = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new WrappedProduct(value.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(WrappedProduct)} does not support '{options.Format}' format."); + } + } + + WrappedProduct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeWrappedProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(WrappedProduct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/model-flattening/Generated/Models/WrappedProduct.cs b/test/TestServerProjects/model-flattening/Generated/Models/WrappedProduct.cs index 1daebfea605..c311f86cf2d 100644 --- a/test/TestServerProjects/model-flattening/Generated/Models/WrappedProduct.cs +++ b/test/TestServerProjects/model-flattening/Generated/Models/WrappedProduct.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace model_flattening.Models { /// The wrapped produc. public partial class WrappedProduct { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public WrappedProduct() { @@ -17,9 +52,11 @@ public WrappedProduct() /// Initializes a new instance of . /// the product value. - internal WrappedProduct(string value) + /// Keeps track of any properties unknown to the library. + internal WrappedProduct(string value, IDictionary serializedAdditionalRawData) { Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// the product value. diff --git a/test/TestServerProjects/model-flattening/model_flattening.csproj b/test/TestServerProjects/model-flattening/model_flattening.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/model-flattening/model_flattening.csproj +++ b/test/TestServerProjects/model-flattening/model_flattening.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Configuration.json b/test/TestServerProjects/multiple-inheritance/Generated/Configuration.json index 08191cda023..617d80c27b2 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Configuration.json +++ b/test/TestServerProjects/multiple-inheritance/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Cat.Serialization.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Cat.Serialization.cs index 0e27de4d9f2..4489ead9171 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Cat.Serialization.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Cat.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace multiple_inheritance.Models { - public partial class Cat : IUtf8JsonSerializable + public partial class Cat : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Cat)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(LikesMilk)) { @@ -32,11 +43,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Cat DeserializeCat(JsonElement element) + Cat IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Cat)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeCat(document.RootElement, options); + } + + internal static Cat DeserializeCat(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -45,6 +85,8 @@ internal static Cat DeserializeCat(JsonElement element) Optional meows = default; Optional hisses = default; string name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("likesMilk"u8)) @@ -79,8 +121,44 @@ internal static Cat DeserializeCat(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Cat(name, Optional.ToNullable(likesMilk), Optional.ToNullable(meows), Optional.ToNullable(hisses)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Cat(name, serializedAdditionalRawData, Optional.ToNullable(likesMilk), Optional.ToNullable(meows), Optional.ToNullable(hisses)); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Cat)} does not support '{options.Format}' format."); + } + } + + Cat IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeCat(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Cat)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Cat.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Cat.cs index d45a11cf620..25a17e48cb4 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Cat.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Cat.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace multiple_inheritance.Models @@ -23,19 +24,22 @@ public Cat(string name) : base(name) /// Initializes a new instance of . /// + /// Keeps track of any properties unknown to the library. /// /// /// - /// is null. - internal Cat(string name, bool? likesMilk, bool? meows, bool? hisses) : base(name) + internal Cat(string name, IDictionary serializedAdditionalRawData, bool? likesMilk, bool? meows, bool? hisses) : base(name, serializedAdditionalRawData) { - Argument.AssertNotNull(name, nameof(name)); - LikesMilk = likesMilk; Meows = meows; Hisses = hisses; } + /// Initializes a new instance of for deserialization. + internal Cat() + { + } + /// Gets or sets the likes milk. public bool? LikesMilk { get; set; } /// Gets or sets the meows. diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Error.Serialization.cs index 072d20c39b8..cc20a52f705 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace multiple_inheritance.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Error.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Error.cs index 82d2c87604c..ec6271a8473 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Error.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace multiple_inheritance.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Feline.Serialization.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Feline.Serialization.cs index 595d1e62713..6721810e4de 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Feline.Serialization.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Feline.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace multiple_inheritance.Models { - public partial class Feline : IUtf8JsonSerializable + public partial class Feline : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Feline)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Meows)) { @@ -25,17 +36,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("hisses"u8); writer.WriteBooleanValue(Hisses.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Feline DeserializeFeline(JsonElement element) + Feline IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Feline)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeFeline(document.RootElement, options); + } + + internal static Feline DeserializeFeline(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional meows = default; Optional hisses = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("meows"u8)) @@ -56,8 +98,44 @@ internal static Feline DeserializeFeline(JsonElement element) hisses = property.Value.GetBoolean(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Feline(Optional.ToNullable(meows), Optional.ToNullable(hisses)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Feline(Optional.ToNullable(meows), Optional.ToNullable(hisses), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Feline)} does not support '{options.Format}' format."); + } + } + + Feline IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeFeline(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Feline)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Feline.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Feline.cs index ea89d5d0e7b..b7f7a3e351f 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Feline.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Feline.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace multiple_inheritance.Models { /// The Feline. public partial class Feline { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Feline() { @@ -18,10 +53,12 @@ public Feline() /// Initializes a new instance of . /// /// - internal Feline(bool? meows, bool? hisses) + /// Keeps track of any properties unknown to the library. + internal Feline(bool? meows, bool? hisses, IDictionary serializedAdditionalRawData) { Meows = meows; Hisses = hisses; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the meows. diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Horse.Serialization.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Horse.Serialization.cs index c23628be786..4efe84ef22d 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Horse.Serialization.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Horse.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace multiple_inheritance.Models { - public partial class Horse : IUtf8JsonSerializable + public partial class Horse : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Horse)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(IsAShowHorse)) { @@ -22,17 +33,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Horse DeserializeHorse(JsonElement element) + Horse IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Horse)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeHorse(document.RootElement, options); + } + + internal static Horse DeserializeHorse(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional isAShowHorse = default; string name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("isAShowHorse"u8)) @@ -49,8 +91,44 @@ internal static Horse DeserializeHorse(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Horse(name, Optional.ToNullable(isAShowHorse)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Horse(name, serializedAdditionalRawData, Optional.ToNullable(isAShowHorse)); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Horse)} does not support '{options.Format}' format."); + } + } + + Horse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeHorse(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Horse)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Horse.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Horse.cs index 18ea2a4b61e..c72fb328a94 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Horse.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Horse.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace multiple_inheritance.Models @@ -23,15 +24,18 @@ public Horse(string name) : base(name) /// Initializes a new instance of . /// + /// Keeps track of any properties unknown to the library. /// - /// is null. - internal Horse(string name, bool? isAShowHorse) : base(name) + internal Horse(string name, IDictionary serializedAdditionalRawData, bool? isAShowHorse) : base(name, serializedAdditionalRawData) { - Argument.AssertNotNull(name, nameof(name)); - IsAShowHorse = isAShowHorse; } + /// Initializes a new instance of for deserialization. + internal Horse() + { + } + /// Gets or sets the is a show horse. public bool? IsAShowHorse { get; set; } } diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Kitten.Serialization.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Kitten.Serialization.cs index b1b1e5277fb..50c8b0bac6f 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Kitten.Serialization.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Kitten.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace multiple_inheritance.Models { - public partial class Kitten : IUtf8JsonSerializable + public partial class Kitten : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Kitten)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(EatsMiceYet)) { @@ -37,11 +48,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Kitten DeserializeKitten(JsonElement element) + Kitten IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Kitten)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeKitten(document.RootElement, options); + } + + internal static Kitten DeserializeKitten(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -51,6 +91,8 @@ internal static Kitten DeserializeKitten(JsonElement element) Optional meows = default; Optional hisses = default; string name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("eatsMiceYet"u8)) @@ -94,8 +136,44 @@ internal static Kitten DeserializeKitten(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Kitten(name, Optional.ToNullable(likesMilk), Optional.ToNullable(meows), Optional.ToNullable(hisses), Optional.ToNullable(eatsMiceYet)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Kitten(name, serializedAdditionalRawData, Optional.ToNullable(likesMilk), Optional.ToNullable(meows), Optional.ToNullable(hisses), Optional.ToNullable(eatsMiceYet)); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Kitten)} does not support '{options.Format}' format."); + } + } + + Kitten IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeKitten(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Kitten)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Kitten.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Kitten.cs index 4efe4f3619e..618f78fc67c 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Kitten.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Kitten.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace multiple_inheritance.Models @@ -23,18 +24,21 @@ public Kitten(string name) : base(name) /// Initializes a new instance of . /// + /// Keeps track of any properties unknown to the library. /// /// /// /// - /// is null. - internal Kitten(string name, bool? likesMilk, bool? meows, bool? hisses, bool? eatsMiceYet) : base(name, likesMilk, meows, hisses) + internal Kitten(string name, IDictionary serializedAdditionalRawData, bool? likesMilk, bool? meows, bool? hisses, bool? eatsMiceYet) : base(name, serializedAdditionalRawData, likesMilk, meows, hisses) { - Argument.AssertNotNull(name, nameof(name)); - EatsMiceYet = eatsMiceYet; } + /// Initializes a new instance of for deserialization. + internal Kitten() + { + } + /// Gets or sets the eats mice yet. public bool? EatsMiceYet { get; set; } } diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Pet.Serialization.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Pet.Serialization.cs index 2284f1ba9ea..c943f599f07 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Pet.Serialization.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Pet.Serialization.cs @@ -5,28 +5,70 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace multiple_inheritance.Models { - public partial class Pet : IUtf8JsonSerializable + public partial class Pet : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Pet DeserializePet(JsonElement element) + Pet IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePet(document.RootElement, options); + } + + internal static Pet DeserializePet(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } string name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("name"u8)) @@ -34,8 +76,44 @@ internal static Pet DeserializePet(JsonElement element) name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Pet(name, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Pet)} does not support '{options.Format}' format."); } - return new Pet(name); } + + Pet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePet(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Pet)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/multiple-inheritance/Generated/Models/Pet.cs b/test/TestServerProjects/multiple-inheritance/Generated/Models/Pet.cs index 261b555ff3d..4da0a64bbc4 100644 --- a/test/TestServerProjects/multiple-inheritance/Generated/Models/Pet.cs +++ b/test/TestServerProjects/multiple-inheritance/Generated/Models/Pet.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace multiple_inheritance.Models @@ -13,6 +14,38 @@ namespace multiple_inheritance.Models /// The Pet. public partial class Pet { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// is null. @@ -23,6 +56,20 @@ public Pet(string name) Name = name; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal Pet(string name, IDictionary serializedAdditionalRawData) + { + Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Pet() + { + } + /// Gets or sets the name. public string Name { get; set; } } diff --git a/test/TestServerProjects/multiple-inheritance/multiple_inheritance.csproj b/test/TestServerProjects/multiple-inheritance/multiple_inheritance.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/multiple-inheritance/multiple_inheritance.csproj +++ b/test/TestServerProjects/multiple-inheritance/multiple_inheritance.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/non-string-enum/Generated/Configuration.json b/test/TestServerProjects/non-string-enum/Generated/Configuration.json index 179bb01dd2c..fe966da6941 100644 --- a/test/TestServerProjects/non-string-enum/Generated/Configuration.json +++ b/test/TestServerProjects/non-string-enum/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/non-string-enum/non_string_enum.csproj b/test/TestServerProjects/non-string-enum/non_string_enum.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/non-string-enum/non_string_enum.csproj +++ b/test/TestServerProjects/non-string-enum/non_string_enum.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/object-type/Generated/Configuration.json b/test/TestServerProjects/object-type/Generated/Configuration.json index a951a57a7f7..f258beb15d0 100644 --- a/test/TestServerProjects/object-type/Generated/Configuration.json +++ b/test/TestServerProjects/object-type/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/object-type/object_type.csproj b/test/TestServerProjects/object-type/object_type.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/object-type/object_type.csproj +++ b/test/TestServerProjects/object-type/object_type.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/paging/Generated/Configuration.json b/test/TestServerProjects/paging/Generated/Configuration.json index b90cb6749c6..7d1b5e058ff 100644 --- a/test/TestServerProjects/paging/Generated/Configuration.json +++ b/test/TestServerProjects/paging/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/paging/Generated/Models/BodyParam.Serialization.cs b/test/TestServerProjects/paging/Generated/Models/BodyParam.Serialization.cs index 616441ba465..71cf6c505f4 100644 --- a/test/TestServerProjects/paging/Generated/Models/BodyParam.Serialization.cs +++ b/test/TestServerProjects/paging/Generated/Models/BodyParam.Serialization.cs @@ -5,22 +5,118 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace paging.Models { - public partial class BodyParam : IUtf8JsonSerializable + public partial class BodyParam : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BodyParam)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Name)) { writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + BodyParam IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BodyParam)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeBodyParam(document.RootElement, options); + } + + internal static BodyParam DeserializeBodyParam(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("name"u8)) + { + name = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new BodyParam(name.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(BodyParam)} does not support '{options.Format}' format."); + } + } + + BodyParam IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeBodyParam(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(BodyParam)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/paging/Generated/Models/BodyParam.cs b/test/TestServerProjects/paging/Generated/Models/BodyParam.cs index 305ab46068c..e61c71a19c0 100644 --- a/test/TestServerProjects/paging/Generated/Models/BodyParam.cs +++ b/test/TestServerProjects/paging/Generated/Models/BodyParam.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace paging.Models { /// The BodyParam. public partial class BodyParam { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public BodyParam() { @@ -17,9 +52,11 @@ public BodyParam() /// Initializes a new instance of . /// - internal BodyParam(string name) + /// Keeps track of any properties unknown to the library. + internal BodyParam(string name, IDictionary serializedAdditionalRawData) { Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the name. diff --git a/test/TestServerProjects/paging/Generated/Models/CustomParameterGroup.cs b/test/TestServerProjects/paging/Generated/Models/CustomParameterGroup.cs index 34a67a0887c..0d25de6b258 100644 --- a/test/TestServerProjects/paging/Generated/Models/CustomParameterGroup.cs +++ b/test/TestServerProjects/paging/Generated/Models/CustomParameterGroup.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace paging.Models @@ -13,6 +14,38 @@ namespace paging.Models /// Parameter group. public partial class CustomParameterGroup { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Sets the api version to use. /// Sets the tenant to use. @@ -26,6 +59,22 @@ public CustomParameterGroup(string apiVersion, string tenant) Tenant = tenant; } + /// Initializes a new instance of . + /// Sets the api version to use. + /// Sets the tenant to use. + /// Keeps track of any properties unknown to the library. + internal CustomParameterGroup(string apiVersion, string tenant, IDictionary serializedAdditionalRawData) + { + ApiVersion = apiVersion; + Tenant = tenant; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal CustomParameterGroup() + { + } + /// Sets the api version to use. public string ApiVersion { get; } /// Sets the tenant to use. diff --git a/test/TestServerProjects/paging/Generated/Models/OdataProductResult.Serialization.cs b/test/TestServerProjects/paging/Generated/Models/OdataProductResult.Serialization.cs index 8c384213289..f6d1238627c 100644 --- a/test/TestServerProjects/paging/Generated/Models/OdataProductResult.Serialization.cs +++ b/test/TestServerProjects/paging/Generated/Models/OdataProductResult.Serialization.cs @@ -5,22 +5,84 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace paging.Models { - internal partial class OdataProductResult + internal partial class OdataProductResult : IUtf8JsonSerializable, IJsonModel { - internal static OdataProductResult DeserializeOdataProductResult(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OdataProductResult)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsCollectionDefined(Values)) + { + writer.WritePropertyName("values"u8); + writer.WriteStartArray(); + foreach (var item in Values) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(OdataNextLink)) + { + writer.WritePropertyName("odata.nextLink"u8); + writer.WriteStringValue(OdataNextLink); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + OdataProductResult IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(OdataProductResult)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeOdataProductResult(document.RootElement, options); + } + + internal static OdataProductResult DeserializeOdataProductResult(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional> values = default; Optional odataNextLink = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("values"u8)) @@ -42,8 +104,44 @@ internal static OdataProductResult DeserializeOdataProductResult(JsonElement ele odataNextLink = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new OdataProductResult(Optional.ToList(values), odataNextLink.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new OdataProductResult(Optional.ToList(values), odataNextLink.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(OdataProductResult)} does not support '{options.Format}' format."); + } + } + + OdataProductResult IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeOdataProductResult(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(OdataProductResult)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/paging/Generated/Models/OdataProductResult.cs b/test/TestServerProjects/paging/Generated/Models/OdataProductResult.cs index 6909dff8b25..426775309c3 100644 --- a/test/TestServerProjects/paging/Generated/Models/OdataProductResult.cs +++ b/test/TestServerProjects/paging/Generated/Models/OdataProductResult.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace paging.Models /// The OdataProductResult. internal partial class OdataProductResult { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal OdataProductResult() { @@ -22,10 +55,12 @@ internal OdataProductResult() /// Initializes a new instance of . /// /// - internal OdataProductResult(IReadOnlyList values, string odataNextLink) + /// Keeps track of any properties unknown to the library. + internal OdataProductResult(IReadOnlyList values, string odataNextLink, IDictionary serializedAdditionalRawData) { Values = values; OdataNextLink = odataNextLink; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the values. diff --git a/test/TestServerProjects/paging/Generated/Models/OperationResult.cs b/test/TestServerProjects/paging/Generated/Models/OperationResult.cs index 103986c5fa5..16317436c87 100644 --- a/test/TestServerProjects/paging/Generated/Models/OperationResult.cs +++ b/test/TestServerProjects/paging/Generated/Models/OperationResult.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace paging.Models { /// The OperationResult. internal partial class OperationResult { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal OperationResult() { @@ -17,9 +52,11 @@ internal OperationResult() /// Initializes a new instance of . /// The status of the request. - internal OperationResult(OperationResultStatus? status) + /// Keeps track of any properties unknown to the library. + internal OperationResult(OperationResultStatus? status, IDictionary serializedAdditionalRawData) { Status = status; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// The status of the request. diff --git a/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesLroOptions.cs b/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesLroOptions.cs index 2523c10c2ee..5ba1574da75 100644 --- a/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesLroOptions.cs +++ b/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesLroOptions.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace paging.Models { /// Parameter group. public partial class PagingGetMultiplePagesLroOptions { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public PagingGetMultiplePagesLroOptions() { @@ -18,10 +53,12 @@ public PagingGetMultiplePagesLroOptions() /// Initializes a new instance of . /// Sets the maximum number of items to return in the response. /// Sets the maximum time that the server can spend processing the request, in seconds. The default is 30 seconds. - internal PagingGetMultiplePagesLroOptions(int? maxresults, int? timeout) + /// Keeps track of any properties unknown to the library. + internal PagingGetMultiplePagesLroOptions(int? maxresults, int? timeout, IDictionary serializedAdditionalRawData) { Maxresults = maxresults; Timeout = timeout; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Sets the maximum number of items to return in the response. diff --git a/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesOptions.cs b/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesOptions.cs index e64cf474cee..b0105d7a6b7 100644 --- a/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesOptions.cs +++ b/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesOptions.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace paging.Models { /// Parameter group. public partial class PagingGetMultiplePagesOptions { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public PagingGetMultiplePagesOptions() { @@ -18,10 +53,12 @@ public PagingGetMultiplePagesOptions() /// Initializes a new instance of . /// Sets the maximum number of items to return in the response. /// Sets the maximum time that the server can spend processing the request, in seconds. The default is 30 seconds. - internal PagingGetMultiplePagesOptions(int? maxresults, int? timeout) + /// Keeps track of any properties unknown to the library. + internal PagingGetMultiplePagesOptions(int? maxresults, int? timeout, IDictionary serializedAdditionalRawData) { Maxresults = maxresults; Timeout = timeout; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Sets the maximum number of items to return in the response. diff --git a/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesWithOffsetOptions.cs b/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesWithOffsetOptions.cs index 637ecb16034..6b89b45b8b5 100644 --- a/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesWithOffsetOptions.cs +++ b/test/TestServerProjects/paging/Generated/Models/PagingGetMultiplePagesWithOffsetOptions.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace paging.Models { /// Parameter group. public partial class PagingGetMultiplePagesWithOffsetOptions { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Offset of return value. public PagingGetMultiplePagesWithOffsetOptions(int offset) @@ -21,11 +56,18 @@ public PagingGetMultiplePagesWithOffsetOptions(int offset) /// Sets the maximum number of items to return in the response. /// Offset of return value. /// Sets the maximum time that the server can spend processing the request, in seconds. The default is 30 seconds. - internal PagingGetMultiplePagesWithOffsetOptions(int? maxresults, int offset, int? timeout) + /// Keeps track of any properties unknown to the library. + internal PagingGetMultiplePagesWithOffsetOptions(int? maxresults, int offset, int? timeout, IDictionary serializedAdditionalRawData) { Maxresults = maxresults; Offset = offset; Timeout = timeout; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal PagingGetMultiplePagesWithOffsetOptions() + { } /// Sets the maximum number of items to return in the response. diff --git a/test/TestServerProjects/paging/Generated/Models/PagingGetOdataMultiplePagesOptions.cs b/test/TestServerProjects/paging/Generated/Models/PagingGetOdataMultiplePagesOptions.cs index f68bb78a876..fb733f97362 100644 --- a/test/TestServerProjects/paging/Generated/Models/PagingGetOdataMultiplePagesOptions.cs +++ b/test/TestServerProjects/paging/Generated/Models/PagingGetOdataMultiplePagesOptions.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace paging.Models { /// Parameter group. public partial class PagingGetOdataMultiplePagesOptions { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public PagingGetOdataMultiplePagesOptions() { @@ -18,10 +53,12 @@ public PagingGetOdataMultiplePagesOptions() /// Initializes a new instance of . /// Sets the maximum number of items to return in the response. /// Sets the maximum time that the server can spend processing the request, in seconds. The default is 30 seconds. - internal PagingGetOdataMultiplePagesOptions(int? maxresults, int? timeout) + /// Keeps track of any properties unknown to the library. + internal PagingGetOdataMultiplePagesOptions(int? maxresults, int? timeout, IDictionary serializedAdditionalRawData) { Maxresults = maxresults; Timeout = timeout; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Sets the maximum number of items to return in the response. diff --git a/test/TestServerProjects/paging/Generated/Models/Product.Serialization.cs b/test/TestServerProjects/paging/Generated/Models/Product.Serialization.cs index 4454e72644d..3a6e8c796fa 100644 --- a/test/TestServerProjects/paging/Generated/Models/Product.Serialization.cs +++ b/test/TestServerProjects/paging/Generated/Models/Product.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace paging.Models { - public partial class Product + public partial class Product : IUtf8JsonSerializable, IJsonModel { - internal static Product DeserializeProduct(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Properties)) + { + writer.WritePropertyName("properties"u8); + writer.WriteObjectValue(Properties); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Product IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProduct(document.RootElement, options); + } + + internal static Product DeserializeProduct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional properties = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("properties"u8)) @@ -30,8 +83,44 @@ internal static Product DeserializeProduct(JsonElement element) properties = ProductProperties.DeserializeProductProperties(property.Value); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Product(properties.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); } - return new Product(properties.Value); } + + Product IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/paging/Generated/Models/Product.cs b/test/TestServerProjects/paging/Generated/Models/Product.cs index 360cab3653d..e5e7ab68aac 100644 --- a/test/TestServerProjects/paging/Generated/Models/Product.cs +++ b/test/TestServerProjects/paging/Generated/Models/Product.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace paging.Models { /// The Product. public partial class Product { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Product() { @@ -17,9 +52,11 @@ internal Product() /// Initializes a new instance of . /// - internal Product(ProductProperties properties) + /// Keeps track of any properties unknown to the library. + internal Product(ProductProperties properties, IDictionary serializedAdditionalRawData) { Properties = properties; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the properties. diff --git a/test/TestServerProjects/paging/Generated/Models/ProductProperties.Serialization.cs b/test/TestServerProjects/paging/Generated/Models/ProductProperties.Serialization.cs index 5b07b2c6219..7b67c98b7b8 100644 --- a/test/TestServerProjects/paging/Generated/Models/ProductProperties.Serialization.cs +++ b/test/TestServerProjects/paging/Generated/Models/ProductProperties.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace paging.Models { - public partial class ProductProperties + public partial class ProductProperties : IUtf8JsonSerializable, IJsonModel { - internal static ProductProperties DeserializeProductProperties(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductProperties)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteNumberValue(Id.Value); + } + if (Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ProductProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductProperties)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProductProperties(document.RootElement, options); + } + + internal static ProductProperties DeserializeProductProperties(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional id = default; Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -36,8 +94,44 @@ internal static ProductProperties DeserializeProductProperties(JsonElement eleme name = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ProductProperties(Optional.ToNullable(id), name.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ProductProperties)} does not support '{options.Format}' format."); + } + } + + ProductProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProductProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ProductProperties)} does not support '{options.Format}' format."); } - return new ProductProperties(Optional.ToNullable(id), name.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/paging/Generated/Models/ProductProperties.cs b/test/TestServerProjects/paging/Generated/Models/ProductProperties.cs index 5859222fb7e..b570e73c487 100644 --- a/test/TestServerProjects/paging/Generated/Models/ProductProperties.cs +++ b/test/TestServerProjects/paging/Generated/Models/ProductProperties.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace paging.Models { /// The ProductProperties. public partial class ProductProperties { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ProductProperties() { @@ -18,10 +53,12 @@ internal ProductProperties() /// Initializes a new instance of . /// /// - internal ProductProperties(int? id, string name) + /// Keeps track of any properties unknown to the library. + internal ProductProperties(int? id, string name, IDictionary serializedAdditionalRawData) { Id = id; Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the id. diff --git a/test/TestServerProjects/paging/Generated/Models/ProductResult.Serialization.cs b/test/TestServerProjects/paging/Generated/Models/ProductResult.Serialization.cs index 2b41bcccf86..ad9e927ef81 100644 --- a/test/TestServerProjects/paging/Generated/Models/ProductResult.Serialization.cs +++ b/test/TestServerProjects/paging/Generated/Models/ProductResult.Serialization.cs @@ -5,22 +5,84 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace paging.Models { - internal partial class ProductResult + internal partial class ProductResult : IUtf8JsonSerializable, IJsonModel { - internal static ProductResult DeserializeProductResult(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductResult)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsCollectionDefined(Values)) + { + writer.WritePropertyName("values"u8); + writer.WriteStartArray(); + foreach (var item in Values) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(NextLink)) + { + writer.WritePropertyName("nextLink"u8); + writer.WriteStringValue(NextLink); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ProductResult IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductResult)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProductResult(document.RootElement, options); + } + + internal static ProductResult DeserializeProductResult(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional> values = default; Optional nextLink = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("values"u8)) @@ -42,8 +104,44 @@ internal static ProductResult DeserializeProductResult(JsonElement element) nextLink = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ProductResult(Optional.ToList(values), nextLink.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ProductResult(Optional.ToList(values), nextLink.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ProductResult)} does not support '{options.Format}' format."); + } + } + + ProductResult IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProductResult(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ProductResult)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/paging/Generated/Models/ProductResult.cs b/test/TestServerProjects/paging/Generated/Models/ProductResult.cs index 27b2b5800b8..36ba8951d48 100644 --- a/test/TestServerProjects/paging/Generated/Models/ProductResult.cs +++ b/test/TestServerProjects/paging/Generated/Models/ProductResult.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace paging.Models /// The ProductResult. internal partial class ProductResult { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ProductResult() { @@ -22,10 +55,12 @@ internal ProductResult() /// Initializes a new instance of . /// /// - internal ProductResult(IReadOnlyList values, string nextLink) + /// Keeps track of any properties unknown to the library. + internal ProductResult(IReadOnlyList values, string nextLink, IDictionary serializedAdditionalRawData) { Values = values; NextLink = nextLink; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the values. diff --git a/test/TestServerProjects/paging/Generated/Models/ProductResultValue.Serialization.cs b/test/TestServerProjects/paging/Generated/Models/ProductResultValue.Serialization.cs index f8c3c74b0ff..addf667e530 100644 --- a/test/TestServerProjects/paging/Generated/Models/ProductResultValue.Serialization.cs +++ b/test/TestServerProjects/paging/Generated/Models/ProductResultValue.Serialization.cs @@ -5,22 +5,84 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace paging.Models { - internal partial class ProductResultValue + internal partial class ProductResultValue : IUtf8JsonSerializable, IJsonModel { - internal static ProductResultValue DeserializeProductResultValue(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductResultValue)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsCollectionDefined(Value)) + { + writer.WritePropertyName("value"u8); + writer.WriteStartArray(); + foreach (var item in Value) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(NextLink)) + { + writer.WritePropertyName("nextLink"u8); + writer.WriteStringValue(NextLink); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ProductResultValue IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductResultValue)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProductResultValue(document.RootElement, options); + } + + internal static ProductResultValue DeserializeProductResultValue(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional> value = default; Optional nextLink = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("value"u8)) @@ -42,8 +104,44 @@ internal static ProductResultValue DeserializeProductResultValue(JsonElement ele nextLink = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ProductResultValue(Optional.ToList(value), nextLink.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ProductResultValue(Optional.ToList(value), nextLink.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ProductResultValue)} does not support '{options.Format}' format."); + } + } + + ProductResultValue IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProductResultValue(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ProductResultValue)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/paging/Generated/Models/ProductResultValue.cs b/test/TestServerProjects/paging/Generated/Models/ProductResultValue.cs index fc034310bda..d96e2cc0453 100644 --- a/test/TestServerProjects/paging/Generated/Models/ProductResultValue.cs +++ b/test/TestServerProjects/paging/Generated/Models/ProductResultValue.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace paging.Models /// The ProductResultValue. internal partial class ProductResultValue { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ProductResultValue() { @@ -22,10 +55,12 @@ internal ProductResultValue() /// Initializes a new instance of . /// /// - internal ProductResultValue(IReadOnlyList value, string nextLink) + /// Keeps track of any properties unknown to the library. + internal ProductResultValue(IReadOnlyList value, string nextLink, IDictionary serializedAdditionalRawData) { Value = value; NextLink = nextLink; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the value. diff --git a/test/TestServerProjects/paging/Generated/Models/ProductResultValueWithXMSClientName.Serialization.cs b/test/TestServerProjects/paging/Generated/Models/ProductResultValueWithXMSClientName.Serialization.cs index 493297eea31..8f9f0836fcc 100644 --- a/test/TestServerProjects/paging/Generated/Models/ProductResultValueWithXMSClientName.Serialization.cs +++ b/test/TestServerProjects/paging/Generated/Models/ProductResultValueWithXMSClientName.Serialization.cs @@ -5,22 +5,84 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace paging.Models { - internal partial class ProductResultValueWithXMSClientName + internal partial class ProductResultValueWithXMSClientName : IUtf8JsonSerializable, IJsonModel { - internal static ProductResultValueWithXMSClientName DeserializeProductResultValueWithXMSClientName(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductResultValueWithXMSClientName)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsCollectionDefined(Indexes)) + { + writer.WritePropertyName("values"u8); + writer.WriteStartArray(); + foreach (var item in Indexes) + { + writer.WriteObjectValue(item); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(NextLink)) + { + writer.WritePropertyName("nextLink"u8); + writer.WriteStringValue(NextLink); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + ProductResultValueWithXMSClientName IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ProductResultValueWithXMSClientName)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProductResultValueWithXMSClientName(document.RootElement, options); + } + + internal static ProductResultValueWithXMSClientName DeserializeProductResultValueWithXMSClientName(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional> values = default; Optional nextLink = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("values"u8)) @@ -42,8 +104,44 @@ internal static ProductResultValueWithXMSClientName DeserializeProductResultValu nextLink = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ProductResultValueWithXMSClientName(Optional.ToList(values), nextLink.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ProductResultValueWithXMSClientName(Optional.ToList(values), nextLink.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ProductResultValueWithXMSClientName)} does not support '{options.Format}' format."); + } + } + + ProductResultValueWithXMSClientName IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProductResultValueWithXMSClientName(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ProductResultValueWithXMSClientName)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/paging/Generated/Models/ProductResultValueWithXMSClientName.cs b/test/TestServerProjects/paging/Generated/Models/ProductResultValueWithXMSClientName.cs index 667e25f3242..2c8c4e4fa9d 100644 --- a/test/TestServerProjects/paging/Generated/Models/ProductResultValueWithXMSClientName.cs +++ b/test/TestServerProjects/paging/Generated/Models/ProductResultValueWithXMSClientName.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace paging.Models /// The ProductResultValueWithXMSClientName. internal partial class ProductResultValueWithXMSClientName { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ProductResultValueWithXMSClientName() { @@ -22,10 +55,12 @@ internal ProductResultValueWithXMSClientName() /// Initializes a new instance of . /// /// - internal ProductResultValueWithXMSClientName(IReadOnlyList indexes, string nextLink) + /// Keeps track of any properties unknown to the library. + internal ProductResultValueWithXMSClientName(IReadOnlyList indexes, string nextLink, IDictionary serializedAdditionalRawData) { Indexes = indexes; NextLink = nextLink; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the indexes. diff --git a/test/TestServerProjects/paging/Generated/PagingClient.cs b/test/TestServerProjects/paging/Generated/PagingClient.cs index 0078010745c..3963ec5c19f 100644 --- a/test/TestServerProjects/paging/Generated/PagingClient.cs +++ b/test/TestServerProjects/paging/Generated/PagingClient.cs @@ -47,7 +47,7 @@ public virtual AsyncPageable GetNoItemNamePagesAsync(CancellationToken { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetNoItemNamePagesRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetNoItemNamePagesNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetNoItemNamePages", "value", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetNoItemNamePages", "value", "nextLink", cancellationToken); } /// A paging operation that must return result of the default 'value' node. @@ -56,7 +56,7 @@ public virtual Pageable GetNoItemNamePages(CancellationToken cancellati { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetNoItemNamePagesRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetNoItemNamePagesNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetNoItemNamePages", "value", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetNoItemNamePages", "value", "nextLink", cancellationToken); } /// A paging operation that gets an empty next link and should stop after page 1. @@ -65,7 +65,7 @@ public virtual AsyncPageable GetEmptyNextLinkNamePagesAsync(Cancellatio { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetEmptyNextLinkNamePagesRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetEmptyNextLinkNamePagesNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetEmptyNextLinkNamePages", "value", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetEmptyNextLinkNamePages", "value", "nextLink", cancellationToken); } /// A paging operation that gets an empty next link and should stop after page 1. @@ -74,7 +74,7 @@ public virtual Pageable GetEmptyNextLinkNamePages(CancellationToken can { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetEmptyNextLinkNamePagesRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetEmptyNextLinkNamePagesNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetEmptyNextLinkNamePages", "value", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetEmptyNextLinkNamePages", "value", "nextLink", cancellationToken); } /// A paging operation that must ignore any kind of nextLink, and stop after page 1. @@ -82,7 +82,7 @@ public virtual Pageable GetEmptyNextLinkNamePages(CancellationToken can public virtual AsyncPageable GetNullNextLinkNamePagesAsync(CancellationToken cancellationToken = default) { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetNullNextLinkNamePagesRequest(); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, null, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetNullNextLinkNamePages", "values", null, cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, null, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetNullNextLinkNamePages", "values", null, cancellationToken); } /// A paging operation that must ignore any kind of nextLink, and stop after page 1. @@ -90,7 +90,7 @@ public virtual AsyncPageable GetNullNextLinkNamePagesAsync(Cancellation public virtual Pageable GetNullNextLinkNamePages(CancellationToken cancellationToken = default) { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetNullNextLinkNamePagesRequest(); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, null, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetNullNextLinkNamePages", "values", null, cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, null, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetNullNextLinkNamePages", "values", null, cancellationToken); } /// A paging operation that finishes on the first call without a nextlink. @@ -99,7 +99,7 @@ public virtual AsyncPageable GetSinglePagesAsync(CancellationToken canc { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetSinglePagesRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetSinglePagesNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetSinglePages", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetSinglePages", "values", "nextLink", cancellationToken); } /// A paging operation that finishes on the first call without a nextlink. @@ -108,7 +108,7 @@ public virtual Pageable GetSinglePages(CancellationToken cancellationTo { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetSinglePagesRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetSinglePagesNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetSinglePages", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetSinglePages", "values", "nextLink", cancellationToken); } /// A paging operation that finishes on the first call with body params without a nextlink. @@ -121,7 +121,7 @@ public virtual AsyncPageable GetSinglePagesWithBodyParamsAsync(BodyPara HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetSinglePagesWithBodyParamsRequest(parameters); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetSinglePagesWithBodyParamsNextPageRequest(nextLink, parameters); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetSinglePagesWithBodyParams", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetSinglePagesWithBodyParams", "values", "nextLink", cancellationToken); } /// A paging operation that finishes on the first call with body params without a nextlink. @@ -134,7 +134,7 @@ public virtual Pageable GetSinglePagesWithBodyParams(BodyParam paramete HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetSinglePagesWithBodyParamsRequest(parameters); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetSinglePagesWithBodyParamsNextPageRequest(nextLink, parameters); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetSinglePagesWithBodyParams", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetSinglePagesWithBodyParams", "values", "nextLink", cancellationToken); } /// A paging operation whose first response's items list is empty, but still returns a next link. Second (and final) call, will give you an items list of 1. @@ -143,7 +143,7 @@ public virtual AsyncPageable FirstResponseEmptyAsync(CancellationToken { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateFirstResponseEmptyRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateFirstResponseEmptyNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.FirstResponseEmpty", "value", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.FirstResponseEmpty", "value", "nextLink", cancellationToken); } /// A paging operation whose first response's items list is empty, but still returns a next link. Second (and final) call, will give you an items list of 1. @@ -152,7 +152,7 @@ public virtual Pageable FirstResponseEmpty(CancellationToken cancellati { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateFirstResponseEmptyRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateFirstResponseEmptyNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.FirstResponseEmpty", "value", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.FirstResponseEmpty", "value", "nextLink", cancellationToken); } /// A paging operation that includes a nextLink that has 10 pages. @@ -162,7 +162,7 @@ public virtual AsyncPageable GetMultiplePagesAsync(PagingGetMultiplePag { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesRequest(pagingGetMultiplePagesOptions); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesNextPageRequest(nextLink, pagingGetMultiplePagesOptions); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePages", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePages", "values", "nextLink", cancellationToken); } /// A paging operation that includes a nextLink that has 10 pages. @@ -172,7 +172,7 @@ public virtual Pageable GetMultiplePages(PagingGetMultiplePagesOptions { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesRequest(pagingGetMultiplePagesOptions); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesNextPageRequest(nextLink, pagingGetMultiplePagesOptions); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePages", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePages", "values", "nextLink", cancellationToken); } /// A paging operation that includes a next operation. It has a different query parameter from it's next operation nextOperationWithQueryParams. Returns a ProductResult. @@ -182,7 +182,7 @@ public virtual AsyncPageable GetWithQueryParamsAsync(int requiredQueryP { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetWithQueryParamsRequest(requiredQueryParameter); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateNextOperationWithQueryParamsRequest(); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetWithQueryParams", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetWithQueryParams", "values", "nextLink", cancellationToken); } /// A paging operation that includes a next operation. It has a different query parameter from it's next operation nextOperationWithQueryParams. Returns a ProductResult. @@ -192,7 +192,7 @@ public virtual Pageable GetWithQueryParams(int requiredQueryParameter, { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetWithQueryParamsRequest(requiredQueryParameter); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateNextOperationWithQueryParamsRequest(); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetWithQueryParams", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetWithQueryParams", "values", "nextLink", cancellationToken); } /// Define `filter` as a query param for all calls. However, the returned next link will also include the `filter` as part of it. Make sure you don't end up duplicating the `filter` param in the url sent. @@ -202,7 +202,7 @@ public virtual AsyncPageable DuplicateParamsAsync(string filter = null, { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateDuplicateParamsRequest(filter); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateDuplicateParamsNextPageRequest(nextLink, filter); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.DuplicateParams", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.DuplicateParams", "values", "nextLink", cancellationToken); } /// Define `filter` as a query param for all calls. However, the returned next link will also include the `filter` as part of it. Make sure you don't end up duplicating the `filter` param in the url sent. @@ -212,7 +212,7 @@ public virtual Pageable DuplicateParams(string filter = null, Cancellat { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateDuplicateParamsRequest(filter); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateDuplicateParamsNextPageRequest(nextLink, filter); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.DuplicateParams", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.DuplicateParams", "values", "nextLink", cancellationToken); } /// Paging with max page size. We don't want to. @@ -222,7 +222,7 @@ public virtual AsyncPageable PageWithMaxPageSizeAsync(MaxPageSizeType? { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreatePageWithMaxPageSizeRequest(maxpagesize); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreatePageWithMaxPageSizeNextPageRequest(nextLink, maxpagesize); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.PageWithMaxPageSize", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.PageWithMaxPageSize", "values", "nextLink", cancellationToken); } /// Paging with max page size. We don't want to. @@ -232,7 +232,7 @@ public virtual Pageable PageWithMaxPageSize(MaxPageSizeType? maxpagesiz { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreatePageWithMaxPageSizeRequest(maxpagesize); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreatePageWithMaxPageSizeNextPageRequest(nextLink, maxpagesize); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.PageWithMaxPageSize", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.PageWithMaxPageSize", "values", "nextLink", cancellationToken); } /// Next operation for getWithQueryParams. Pass in next=True to pass test. Returns a ProductResult. @@ -240,7 +240,7 @@ public virtual Pageable PageWithMaxPageSize(MaxPageSizeType? maxpagesiz public virtual AsyncPageable NextOperationWithQueryParamsAsync(CancellationToken cancellationToken = default) { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateNextOperationWithQueryParamsRequest(); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, null, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.NextOperationWithQueryParams", "values", null, cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, null, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.NextOperationWithQueryParams", "values", null, cancellationToken); } /// Next operation for getWithQueryParams. Pass in next=True to pass test. Returns a ProductResult. @@ -248,7 +248,7 @@ public virtual AsyncPageable NextOperationWithQueryParamsAsync(Cancella public virtual Pageable NextOperationWithQueryParams(CancellationToken cancellationToken = default) { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateNextOperationWithQueryParamsRequest(); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, null, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.NextOperationWithQueryParams", "values", null, cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, null, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.NextOperationWithQueryParams", "values", null, cancellationToken); } /// A paging operation that includes a nextLink in odata format that has 10 pages. @@ -258,7 +258,7 @@ public virtual AsyncPageable GetOdataMultiplePagesAsync(PagingGetOdataM { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetOdataMultiplePagesRequest(pagingGetOdataMultiplePagesOptions); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetOdataMultiplePagesNextPageRequest(nextLink, pagingGetOdataMultiplePagesOptions); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetOdataMultiplePages", "values", "odata.nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetOdataMultiplePages", "values", "odata.nextLink", cancellationToken); } /// A paging operation that includes a nextLink in odata format that has 10 pages. @@ -268,7 +268,7 @@ public virtual Pageable GetOdataMultiplePages(PagingGetOdataMultiplePag { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetOdataMultiplePagesRequest(pagingGetOdataMultiplePagesOptions); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetOdataMultiplePagesNextPageRequest(nextLink, pagingGetOdataMultiplePagesOptions); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetOdataMultiplePages", "values", "odata.nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetOdataMultiplePages", "values", "odata.nextLink", cancellationToken); } /// A paging operation that includes a nextLink that has 10 pages. @@ -281,7 +281,7 @@ public virtual AsyncPageable GetMultiplePagesWithOffsetAsync(PagingGetM HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesWithOffsetRequest(pagingGetMultiplePagesWithOffsetOptions); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesWithOffsetNextPageRequest(nextLink, pagingGetMultiplePagesWithOffsetOptions); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesWithOffset", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesWithOffset", "values", "nextLink", cancellationToken); } /// A paging operation that includes a nextLink that has 10 pages. @@ -294,7 +294,7 @@ public virtual Pageable GetMultiplePagesWithOffset(PagingGetMultiplePag HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesWithOffsetRequest(pagingGetMultiplePagesWithOffsetOptions); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesWithOffsetNextPageRequest(nextLink, pagingGetMultiplePagesWithOffsetOptions); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesWithOffset", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesWithOffset", "values", "nextLink", cancellationToken); } /// A paging operation that fails on the first call with 500 and then retries and then get a response including a nextLink that has 10 pages. @@ -303,7 +303,7 @@ public virtual AsyncPageable GetMultiplePagesRetryFirstAsync(Cancellati { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesRetryFirstRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesRetryFirstNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesRetryFirst", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesRetryFirst", "values", "nextLink", cancellationToken); } /// A paging operation that fails on the first call with 500 and then retries and then get a response including a nextLink that has 10 pages. @@ -312,7 +312,7 @@ public virtual Pageable GetMultiplePagesRetryFirst(CancellationToken ca { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesRetryFirstRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesRetryFirstNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesRetryFirst", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesRetryFirst", "values", "nextLink", cancellationToken); } /// A paging operation that includes a nextLink that has 10 pages, of which the 2nd call fails first with 500. The client should retry and finish all 10 pages eventually. @@ -321,7 +321,7 @@ public virtual AsyncPageable GetMultiplePagesRetrySecondAsync(Cancellat { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesRetrySecondRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesRetrySecondNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesRetrySecond", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesRetrySecond", "values", "nextLink", cancellationToken); } /// A paging operation that includes a nextLink that has 10 pages, of which the 2nd call fails first with 500. The client should retry and finish all 10 pages eventually. @@ -330,7 +330,7 @@ public virtual Pageable GetMultiplePagesRetrySecond(CancellationToken c { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesRetrySecondRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesRetrySecondNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesRetrySecond", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesRetrySecond", "values", "nextLink", cancellationToken); } /// A paging operation that receives a 400 on the first call. @@ -339,7 +339,7 @@ public virtual AsyncPageable GetSinglePagesFailureAsync(CancellationTok { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetSinglePagesFailureRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetSinglePagesFailureNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetSinglePagesFailure", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetSinglePagesFailure", "values", "nextLink", cancellationToken); } /// A paging operation that receives a 400 on the first call. @@ -348,7 +348,7 @@ public virtual Pageable GetSinglePagesFailure(CancellationToken cancell { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetSinglePagesFailureRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetSinglePagesFailureNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetSinglePagesFailure", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetSinglePagesFailure", "values", "nextLink", cancellationToken); } /// A paging operation that receives a 400 on the second call. @@ -357,7 +357,7 @@ public virtual AsyncPageable GetMultiplePagesFailureAsync(CancellationT { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesFailureRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesFailureNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFailure", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFailure", "values", "nextLink", cancellationToken); } /// A paging operation that receives a 400 on the second call. @@ -366,7 +366,7 @@ public virtual Pageable GetMultiplePagesFailure(CancellationToken cance { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesFailureRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesFailureNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFailure", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFailure", "values", "nextLink", cancellationToken); } /// A paging operation that receives an invalid nextLink. @@ -375,7 +375,7 @@ public virtual AsyncPageable GetMultiplePagesFailureUriAsync(Cancellati { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesFailureUriRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesFailureUriNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFailureUri", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFailureUri", "values", "nextLink", cancellationToken); } /// A paging operation that receives an invalid nextLink. @@ -384,7 +384,7 @@ public virtual Pageable GetMultiplePagesFailureUri(CancellationToken ca { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesFailureUriRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetMultiplePagesFailureUriNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFailureUri", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFailureUri", "values", "nextLink", cancellationToken); } /// A paging operation that doesn't return a full URL, just a fragment. @@ -399,7 +399,7 @@ public virtual AsyncPageable GetMultiplePagesFragmentNextLinkAsync(stri HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesFragmentNextLinkRequest(apiVersion, tenant); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateNextFragmentRequest(apiVersion, tenant, nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFragmentNextLink", "values", "odata.nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFragmentNextLink", "values", "odata.nextLink", cancellationToken); } /// A paging operation that doesn't return a full URL, just a fragment. @@ -414,7 +414,7 @@ public virtual Pageable GetMultiplePagesFragmentNextLink(string apiVers HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesFragmentNextLinkRequest(apiVersion, tenant); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateNextFragmentRequest(apiVersion, tenant, nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFragmentNextLink", "values", "odata.nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFragmentNextLink", "values", "odata.nextLink", cancellationToken); } /// A paging operation that doesn't return a full URL, just a fragment with parameters grouped. @@ -427,7 +427,7 @@ public virtual AsyncPageable GetMultiplePagesFragmentWithGroupingNextLi HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesFragmentWithGroupingNextLinkRequest(customParameterGroup); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateNextFragmentWithGroupingRequest(nextLink, customParameterGroup); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFragmentWithGroupingNextLink", "values", "odata.nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFragmentWithGroupingNextLink", "values", "odata.nextLink", cancellationToken); } /// A paging operation that doesn't return a full URL, just a fragment with parameters grouped. @@ -440,7 +440,7 @@ public virtual Pageable GetMultiplePagesFragmentWithGroupingNextLink(Cu HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetMultiplePagesFragmentWithGroupingNextLinkRequest(customParameterGroup); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateNextFragmentWithGroupingRequest(nextLink, customParameterGroup); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFragmentWithGroupingNextLink", "values", "odata.nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetMultiplePagesFragmentWithGroupingNextLink", "values", "odata.nextLink", cancellationToken); } /// A paging operation with api version. When calling the next link, you want to append your client's api version to the next link. @@ -449,7 +449,7 @@ public virtual AsyncPageable AppendApiVersionAsync(CancellationToken ca { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateAppendApiVersionRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateAppendApiVersionNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.AppendApiVersion", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.AppendApiVersion", "values", "nextLink", cancellationToken); } /// A paging operation with api version. When calling the next link, you want to append your client's api version to the next link. @@ -458,7 +458,7 @@ public virtual Pageable AppendApiVersion(CancellationToken cancellation { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateAppendApiVersionRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateAppendApiVersionNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.AppendApiVersion", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.AppendApiVersion", "values", "nextLink", cancellationToken); } /// A paging operation with api version. When calling the next link, you want to reformat it and override the returned api version with your client's api version. @@ -467,7 +467,7 @@ public virtual AsyncPageable ReplaceApiVersionAsync(CancellationToken c { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateReplaceApiVersionRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateReplaceApiVersionNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.ReplaceApiVersion", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.ReplaceApiVersion", "values", "nextLink", cancellationToken); } /// A paging operation with api version. When calling the next link, you want to reformat it and override the returned api version with your client's api version. @@ -476,7 +476,7 @@ public virtual Pageable ReplaceApiVersion(CancellationToken cancellatio { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateReplaceApiVersionRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateReplaceApiVersionNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.ReplaceApiVersion", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.ReplaceApiVersion", "values", "nextLink", cancellationToken); } /// A paging operation that doesn't return a full URL, just a fragment. @@ -493,7 +493,7 @@ public virtual AsyncPageable NextFragmentAsync(string apiVersion, strin HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateNextFragmentRequest(apiVersion, tenant, nextLink); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateNextFragmentRequest(apiVersion, tenant, nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.NextFragment", "values", "odata.nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.NextFragment", "values", "odata.nextLink", cancellationToken); } /// A paging operation that doesn't return a full URL, just a fragment. @@ -510,7 +510,7 @@ public virtual Pageable NextFragment(string apiVersion, string tenant, HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateNextFragmentRequest(apiVersion, tenant, nextLink); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateNextFragmentRequest(apiVersion, tenant, nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.NextFragment", "values", "odata.nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.NextFragment", "values", "odata.nextLink", cancellationToken); } /// A paging operation that doesn't return a full URL, just a fragment. @@ -525,7 +525,7 @@ public virtual AsyncPageable NextFragmentWithGroupingAsync(string nextL HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateNextFragmentWithGroupingRequest(nextLink, customParameterGroup); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateNextFragmentWithGroupingRequest(nextLink, customParameterGroup); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.NextFragmentWithGrouping", "values", "odata.nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.NextFragmentWithGrouping", "values", "odata.nextLink", cancellationToken); } /// A paging operation that doesn't return a full URL, just a fragment. @@ -540,7 +540,7 @@ public virtual Pageable NextFragmentWithGrouping(string nextLink, Custo HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateNextFragmentWithGroupingRequest(nextLink, customParameterGroup); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateNextFragmentWithGroupingRequest(nextLink, customParameterGroup); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.NextFragmentWithGrouping", "values", "odata.nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.NextFragmentWithGrouping", "values", "odata.nextLink", cancellationToken); } /// A paging operation that returns a paging model whose item name is is overriden by x-ms-client-name 'indexes'. @@ -549,7 +549,7 @@ public virtual AsyncPageable GetPagingModelWithItemNameWithXMSClientNam { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetPagingModelWithItemNameWithXMSClientNameRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetPagingModelWithItemNameWithXMSClientNameNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetPagingModelWithItemNameWithXMSClientName", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetPagingModelWithItemNameWithXMSClientName", "values", "nextLink", cancellationToken); } /// A paging operation that returns a paging model whose item name is is overriden by x-ms-client-name 'indexes'. @@ -558,7 +558,7 @@ public virtual Pageable GetPagingModelWithItemNameWithXMSClientName(Can { HttpMessage FirstPageRequest(int? pageSizeHint) => RestClient.CreateGetPagingModelWithItemNameWithXMSClientNameRequest(); HttpMessage NextPageRequest(int? pageSizeHint, string nextLink) => RestClient.CreateGetPagingModelWithItemNameWithXMSClientNameNextPageRequest(nextLink); - return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingClient.GetPagingModelWithItemNameWithXMSClientName", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreatePageable(FirstPageRequest, NextPageRequest, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingClient.GetPagingModelWithItemNameWithXMSClientName", "values", "nextLink", cancellationToken); } /// A long-running paging operation that includes a nextLink that has 10 pages. diff --git a/test/TestServerProjects/paging/Generated/PagingGetMultiplePagesLROOperation.cs b/test/TestServerProjects/paging/Generated/PagingGetMultiplePagesLROOperation.cs index 79f07d8ad8a..696c872024e 100644 --- a/test/TestServerProjects/paging/Generated/PagingGetMultiplePagesLROOperation.cs +++ b/test/TestServerProjects/paging/Generated/PagingGetMultiplePagesLROOperation.cs @@ -75,12 +75,12 @@ internal PagingGetMultiplePagesLROOperation(ClientDiagnostics clientDiagnostics, AsyncPageable IOperationSource>.CreateResult(Response response, CancellationToken cancellationToken) { - return GeneratorPageableHelpers.CreateAsyncPageable(response, _nextPageFunc, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingGetMultiplePagesLROOperation", "values", "nextLink", cancellationToken); + return GeneratorPageableHelpers.CreateAsyncPageable(response, _nextPageFunc, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingGetMultiplePagesLROOperation", "values", "nextLink", cancellationToken); } ValueTask> IOperationSource>.CreateResultAsync(Response response, CancellationToken cancellationToken) { - return new ValueTask>(GeneratorPageableHelpers.CreateAsyncPageable(response, _nextPageFunc, Product.DeserializeProduct, _clientDiagnostics, _pipeline, "PagingGetMultiplePagesLROOperation", "values", "nextLink", cancellationToken)); + return new ValueTask>(GeneratorPageableHelpers.CreateAsyncPageable(response, _nextPageFunc, e => Product.DeserializeProduct(e), _clientDiagnostics, _pipeline, "PagingGetMultiplePagesLROOperation", "values", "nextLink", cancellationToken)); } } } diff --git a/test/TestServerProjects/paging/Generated/PagingModelFactory.cs b/test/TestServerProjects/paging/Generated/PagingModelFactory.cs index 3d50b8b8492..6c3e1740b46 100644 --- a/test/TestServerProjects/paging/Generated/PagingModelFactory.cs +++ b/test/TestServerProjects/paging/Generated/PagingModelFactory.cs @@ -15,7 +15,7 @@ public static partial class PagingModelFactory /// A new instance for mocking. public static Product Product(ProductProperties properties = null) { - return new Product(properties); + return new Product(properties, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -24,7 +24,17 @@ public static Product Product(ProductProperties properties = null) /// A new instance for mocking. public static ProductProperties ProductProperties(int? id = null, string name = null) { - return new ProductProperties(id, name); + return new ProductProperties(id, name, serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// Sets the maximum number of items to return in the response. + /// Offset of return value. + /// Sets the maximum time that the server can spend processing the request, in seconds. The default is 30 seconds. + /// A new instance for mocking. + public static PagingGetMultiplePagesWithOffsetOptions PagingGetMultiplePagesWithOffsetOptions(int? maxresults = null, int offset = default, int? timeout = null) + { + return new PagingGetMultiplePagesWithOffsetOptions(maxresults, offset, timeout, serializedAdditionalRawData: null); } } } diff --git a/test/TestServerProjects/paging/paging.csproj b/test/TestServerProjects/paging/paging.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/paging/paging.csproj +++ b/test/TestServerProjects/paging/paging.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/required-optional/Generated/Configuration.json b/test/TestServerProjects/required-optional/Generated/Configuration.json index 2ecae70a524..2b8e5a41cf4 100644 --- a/test/TestServerProjects/required-optional/Generated/Configuration.json +++ b/test/TestServerProjects/required-optional/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/required-optional/Generated/Models/ArrayOptionalWrapper.Serialization.cs b/test/TestServerProjects/required-optional/Generated/Models/ArrayOptionalWrapper.Serialization.cs index 4ca1d6b6132..179b97998c4 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/ArrayOptionalWrapper.Serialization.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/ArrayOptionalWrapper.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace required_optional.Models { - public partial class ArrayOptionalWrapper : IUtf8JsonSerializable + public partial class ArrayOptionalWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ArrayOptionalWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsCollectionDefined(Value)) { @@ -25,7 +36,101 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) } writer.WriteEndArray(); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + ArrayOptionalWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ArrayOptionalWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeArrayOptionalWrapper(document.RootElement, options); + } + + internal static ArrayOptionalWrapper DeserializeArrayOptionalWrapper(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional> value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("value"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + value = array; + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ArrayOptionalWrapper(Optional.ToList(value), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ArrayOptionalWrapper)} does not support '{options.Format}' format."); + } + } + + ArrayOptionalWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeArrayOptionalWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ArrayOptionalWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/ArrayOptionalWrapper.cs b/test/TestServerProjects/required-optional/Generated/Models/ArrayOptionalWrapper.cs index 3ee49bda3a3..e1b65cd3d1c 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/ArrayOptionalWrapper.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/ArrayOptionalWrapper.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace required_optional.Models /// The ArrayOptionalWrapper. public partial class ArrayOptionalWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ArrayOptionalWrapper() { @@ -21,9 +54,11 @@ public ArrayOptionalWrapper() /// Initializes a new instance of . /// - internal ArrayOptionalWrapper(IList value) + /// Keeps track of any properties unknown to the library. + internal ArrayOptionalWrapper(IList value, IDictionary serializedAdditionalRawData) { Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the value. diff --git a/test/TestServerProjects/required-optional/Generated/Models/ArrayWrapper.Serialization.cs b/test/TestServerProjects/required-optional/Generated/Models/ArrayWrapper.Serialization.cs index 642250be83b..2b6141ec352 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/ArrayWrapper.Serialization.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/ArrayWrapper.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace required_optional.Models { - public partial class ArrayWrapper : IUtf8JsonSerializable + public partial class ArrayWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ArrayWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("value"u8); writer.WriteStartArray(); @@ -22,7 +33,97 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WriteStringValue(item); } writer.WriteEndArray(); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + ArrayWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ArrayWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeArrayWrapper(document.RootElement, options); + } + + internal static ArrayWrapper DeserializeArrayWrapper(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IList value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("value"u8)) + { + List array = new List(); + foreach (var item in property.Value.EnumerateArray()) + { + array.Add(item.GetString()); + } + value = array; + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ArrayWrapper(value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ArrayWrapper)} does not support '{options.Format}' format."); + } + } + + ArrayWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeArrayWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ArrayWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/ArrayWrapper.cs b/test/TestServerProjects/required-optional/Generated/Models/ArrayWrapper.cs index d77aa928f83..b016a29f8e0 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/ArrayWrapper.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/ArrayWrapper.cs @@ -15,6 +15,38 @@ namespace required_optional.Models /// The ArrayWrapper. public partial class ArrayWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// is null. @@ -27,9 +59,16 @@ public ArrayWrapper(IEnumerable value) /// Initializes a new instance of . /// - internal ArrayWrapper(IList value) + /// Keeps track of any properties unknown to the library. + internal ArrayWrapper(IList value, IDictionary serializedAdditionalRawData) { Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ArrayWrapper() + { } /// Gets the value. diff --git a/test/TestServerProjects/required-optional/Generated/Models/ClassOptionalWrapper.Serialization.cs b/test/TestServerProjects/required-optional/Generated/Models/ClassOptionalWrapper.Serialization.cs index e47b3209f05..23b5e985b5d 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/ClassOptionalWrapper.Serialization.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/ClassOptionalWrapper.Serialization.cs @@ -5,22 +5,122 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace required_optional.Models { - public partial class ClassOptionalWrapper : IUtf8JsonSerializable + public partial class ClassOptionalWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClassOptionalWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Value)) { writer.WritePropertyName("value"u8); writer.WriteObjectValue(Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + ClassOptionalWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClassOptionalWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClassOptionalWrapper(document.RootElement, options); + } + + internal static ClassOptionalWrapper DeserializeClassOptionalWrapper(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("value"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + value = Product.DeserializeProduct(property.Value); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ClassOptionalWrapper(value.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ClassOptionalWrapper)} does not support '{options.Format}' format."); + } + } + + ClassOptionalWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeClassOptionalWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClassOptionalWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/ClassOptionalWrapper.cs b/test/TestServerProjects/required-optional/Generated/Models/ClassOptionalWrapper.cs index 869bbabe290..a80153b4c15 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/ClassOptionalWrapper.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/ClassOptionalWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace required_optional.Models { /// The ClassOptionalWrapper. public partial class ClassOptionalWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ClassOptionalWrapper() { @@ -17,9 +52,11 @@ public ClassOptionalWrapper() /// Initializes a new instance of . /// - internal ClassOptionalWrapper(Product value) + /// Keeps track of any properties unknown to the library. + internal ClassOptionalWrapper(Product value, IDictionary serializedAdditionalRawData) { Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the value. diff --git a/test/TestServerProjects/required-optional/Generated/Models/ClassWrapper.Serialization.cs b/test/TestServerProjects/required-optional/Generated/Models/ClassWrapper.Serialization.cs index c57921fc65c..4e17f07ae54 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/ClassWrapper.Serialization.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/ClassWrapper.Serialization.cs @@ -5,19 +5,115 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace required_optional.Models { - public partial class ClassWrapper : IUtf8JsonSerializable + public partial class ClassWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClassWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("value"u8); writer.WriteObjectValue(Value); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + ClassWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClassWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClassWrapper(document.RootElement, options); + } + + internal static ClassWrapper DeserializeClassWrapper(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Product value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("value"u8)) + { + value = Product.DeserializeProduct(property.Value); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ClassWrapper(value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ClassWrapper)} does not support '{options.Format}' format."); + } + } + + ClassWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeClassWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClassWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/ClassWrapper.cs b/test/TestServerProjects/required-optional/Generated/Models/ClassWrapper.cs index c1300e30f72..08c9ed805ac 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/ClassWrapper.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/ClassWrapper.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace required_optional.Models @@ -13,6 +14,38 @@ namespace required_optional.Models /// The ClassWrapper. public partial class ClassWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// is null. @@ -23,6 +56,20 @@ public ClassWrapper(Product value) Value = value; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal ClassWrapper(Product value, IDictionary serializedAdditionalRawData) + { + Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ClassWrapper() + { + } + /// Gets the value. public Product Value { get; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/required-optional/Generated/Models/Error.Serialization.cs index 8945b27eeef..2e50b2a0408 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace required_optional.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/Error.cs b/test/TestServerProjects/required-optional/Generated/Models/Error.cs index ad237bc4010..64b197026c7 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/Error.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace required_optional.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/required-optional/Generated/Models/IntOptionalWrapper.Serialization.cs b/test/TestServerProjects/required-optional/Generated/Models/IntOptionalWrapper.Serialization.cs index 779eca21322..6c0c6be4636 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/IntOptionalWrapper.Serialization.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/IntOptionalWrapper.Serialization.cs @@ -5,22 +5,122 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace required_optional.Models { - public partial class IntOptionalWrapper : IUtf8JsonSerializable + public partial class IntOptionalWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IntOptionalWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Value)) { writer.WritePropertyName("value"u8); writer.WriteNumberValue(Value.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + IntOptionalWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IntOptionalWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIntOptionalWrapper(document.RootElement, options); + } + + internal static IntOptionalWrapper DeserializeIntOptionalWrapper(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("value"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + value = property.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new IntOptionalWrapper(Optional.ToNullable(value), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IntOptionalWrapper)} does not support '{options.Format}' format."); + } + } + + IntOptionalWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIntOptionalWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IntOptionalWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/IntOptionalWrapper.cs b/test/TestServerProjects/required-optional/Generated/Models/IntOptionalWrapper.cs index fb5ef63b86f..34c2c87047e 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/IntOptionalWrapper.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/IntOptionalWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace required_optional.Models { /// The IntOptionalWrapper. public partial class IntOptionalWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public IntOptionalWrapper() { @@ -17,9 +52,11 @@ public IntOptionalWrapper() /// Initializes a new instance of . /// - internal IntOptionalWrapper(int? value) + /// Keeps track of any properties unknown to the library. + internal IntOptionalWrapper(int? value, IDictionary serializedAdditionalRawData) { Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the value. diff --git a/test/TestServerProjects/required-optional/Generated/Models/IntWrapper.Serialization.cs b/test/TestServerProjects/required-optional/Generated/Models/IntWrapper.Serialization.cs index 6a16087ca63..0b9aaeee94c 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/IntWrapper.Serialization.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/IntWrapper.Serialization.cs @@ -5,19 +5,115 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace required_optional.Models { - public partial class IntWrapper : IUtf8JsonSerializable + public partial class IntWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IntWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("value"u8); writer.WriteNumberValue(Value); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + IntWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IntWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIntWrapper(document.RootElement, options); + } + + internal static IntWrapper DeserializeIntWrapper(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + int value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("value"u8)) + { + value = property.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new IntWrapper(value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(IntWrapper)} does not support '{options.Format}' format."); + } + } + + IntWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeIntWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IntWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/IntWrapper.cs b/test/TestServerProjects/required-optional/Generated/Models/IntWrapper.cs index 66633aaa276..e9ee13bab26 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/IntWrapper.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/IntWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace required_optional.Models { /// The IntWrapper. public partial class IntWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// public IntWrapper(int value) @@ -17,6 +52,20 @@ public IntWrapper(int value) Value = value; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal IntWrapper(int value, IDictionary serializedAdditionalRawData) + { + Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal IntWrapper() + { + } + /// Gets the value. public int Value { get; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/Product.Serialization.cs b/test/TestServerProjects/required-optional/Generated/Models/Product.Serialization.cs index 5cfff282ce3..258e9c42992 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/Product.Serialization.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/Product.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace required_optional.Models { - public partial class Product : IUtf8JsonSerializable + public partial class Product : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id); @@ -22,7 +33,98 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("name"u8); writer.WriteStringValue(Name); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + Product IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProduct(document.RootElement, options); + } + + internal static Product DeserializeProduct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + int id = default; + Optional name = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("id"u8)) + { + id = property.Value.GetInt32(); + continue; + } + if (property.NameEquals("name"u8)) + { + name = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Product(id, name.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + Product IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/Product.cs b/test/TestServerProjects/required-optional/Generated/Models/Product.cs index 70a1434199f..25ffcea4fd1 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/Product.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/Product.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace required_optional.Models { /// The Product. public partial class Product { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// public Product(int id) @@ -20,10 +55,17 @@ public Product(int id) /// Initializes a new instance of . /// /// - internal Product(int id, string name) + /// Keeps track of any properties unknown to the library. + internal Product(int id, string name, IDictionary serializedAdditionalRawData) { Id = id; Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Product() + { } /// Gets the id. diff --git a/test/TestServerProjects/required-optional/Generated/Models/StringOptionalWrapper.Serialization.cs b/test/TestServerProjects/required-optional/Generated/Models/StringOptionalWrapper.Serialization.cs index 5ab7415484b..7080bbcb141 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/StringOptionalWrapper.Serialization.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/StringOptionalWrapper.Serialization.cs @@ -5,22 +5,118 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace required_optional.Models { - public partial class StringOptionalWrapper : IUtf8JsonSerializable + public partial class StringOptionalWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(StringOptionalWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Value)) { writer.WritePropertyName("value"u8); writer.WriteStringValue(Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + StringOptionalWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(StringOptionalWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeStringOptionalWrapper(document.RootElement, options); + } + + internal static StringOptionalWrapper DeserializeStringOptionalWrapper(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("value"u8)) + { + value = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new StringOptionalWrapper(value.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(StringOptionalWrapper)} does not support '{options.Format}' format."); + } + } + + StringOptionalWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeStringOptionalWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(StringOptionalWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/StringOptionalWrapper.cs b/test/TestServerProjects/required-optional/Generated/Models/StringOptionalWrapper.cs index 889c9e3f638..e9566b378e4 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/StringOptionalWrapper.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/StringOptionalWrapper.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace required_optional.Models { /// The StringOptionalWrapper. public partial class StringOptionalWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public StringOptionalWrapper() { @@ -17,9 +52,11 @@ public StringOptionalWrapper() /// Initializes a new instance of . /// - internal StringOptionalWrapper(string value) + /// Keeps track of any properties unknown to the library. + internal StringOptionalWrapper(string value, IDictionary serializedAdditionalRawData) { Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the value. diff --git a/test/TestServerProjects/required-optional/Generated/Models/StringWrapper.Serialization.cs b/test/TestServerProjects/required-optional/Generated/Models/StringWrapper.Serialization.cs index b6adeba40f2..bffac8e6972 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/StringWrapper.Serialization.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/StringWrapper.Serialization.cs @@ -5,19 +5,115 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace required_optional.Models { - public partial class StringWrapper : IUtf8JsonSerializable + public partial class StringWrapper : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(StringWrapper)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("value"u8); writer.WriteStringValue(Value); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + StringWrapper IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(StringWrapper)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeStringWrapper(document.RootElement, options); + } + + internal static StringWrapper DeserializeStringWrapper(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string value = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("value"u8)) + { + value = property.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new StringWrapper(value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(StringWrapper)} does not support '{options.Format}' format."); + } + } + + StringWrapper IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeStringWrapper(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(StringWrapper)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/required-optional/Generated/Models/StringWrapper.cs b/test/TestServerProjects/required-optional/Generated/Models/StringWrapper.cs index db48840fe02..00c9e7e5e62 100644 --- a/test/TestServerProjects/required-optional/Generated/Models/StringWrapper.cs +++ b/test/TestServerProjects/required-optional/Generated/Models/StringWrapper.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace required_optional.Models @@ -13,6 +14,38 @@ namespace required_optional.Models /// The StringWrapper. public partial class StringWrapper { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// is null. @@ -23,6 +56,20 @@ public StringWrapper(string value) Value = value; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal StringWrapper(string value, IDictionary serializedAdditionalRawData) + { + Value = value; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal StringWrapper() + { + } + /// Gets the value. public string Value { get; } } diff --git a/test/TestServerProjects/required-optional/Generated/RequiredOptionalModelFactory.cs b/test/TestServerProjects/required-optional/Generated/RequiredOptionalModelFactory.cs new file mode 100644 index 00000000000..5123dda6a1c --- /dev/null +++ b/test/TestServerProjects/required-optional/Generated/RequiredOptionalModelFactory.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace required_optional.Models +{ + /// Model factory for models. + public static partial class RequiredOptionalModelFactory + { + /// Initializes a new instance of . + /// + /// + /// A new instance for mocking. + public static Product Product(int id = default, string name = null) + { + return new Product(id, name, serializedAdditionalRawData: null); + } + } +} diff --git a/test/TestServerProjects/required-optional/required_optional.csproj b/test/TestServerProjects/required-optional/required_optional.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/required-optional/required_optional.csproj +++ b/test/TestServerProjects/required-optional/required_optional.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/subscriptionId-apiVersion/Generated/Configuration.json b/test/TestServerProjects/subscriptionId-apiVersion/Generated/Configuration.json index fe47802ef5b..06313bf4b82 100644 --- a/test/TestServerProjects/subscriptionId-apiVersion/Generated/Configuration.json +++ b/test/TestServerProjects/subscriptionId-apiVersion/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/Error.Serialization.cs index 20f552c0cbb..b0ca34060e1 100644 --- a/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace subscriptionId_apiVersion.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Code)) + { + writer.WritePropertyName("code"u8); + writer.WriteNumberValue(Code.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional code = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("code"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(code), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(code), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/Error.cs b/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/Error.cs index 5792724709d..7fae7a19b46 100644 --- a/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/Error.cs +++ b/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace subscriptionId_apiVersion.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? code, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? code, string message, IDictionary serializedAdditionalRawData) { Code = code; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the code. diff --git a/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/SampleResourceGroup.Serialization.cs b/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/SampleResourceGroup.Serialization.cs index c9bdc442597..4ae6c77be94 100644 --- a/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/SampleResourceGroup.Serialization.cs +++ b/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/SampleResourceGroup.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace subscriptionId_apiVersion.Models { - public partial class SampleResourceGroup + public partial class SampleResourceGroup : IUtf8JsonSerializable, IJsonModel { - internal static SampleResourceGroup DeserializeSampleResourceGroup(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SampleResourceGroup)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + if (Optional.IsDefined(Location)) + { + writer.WritePropertyName("location"u8); + writer.WriteStringValue(Location); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + SampleResourceGroup IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(SampleResourceGroup)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeSampleResourceGroup(document.RootElement, options); + } + + internal static SampleResourceGroup DeserializeSampleResourceGroup(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional name = default; Optional location = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("name"u8)) @@ -32,8 +90,44 @@ internal static SampleResourceGroup DeserializeSampleResourceGroup(JsonElement e location = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new SampleResourceGroup(name.Value, location.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(SampleResourceGroup)} does not support '{options.Format}' format."); } - return new SampleResourceGroup(name.Value, location.Value); } + + SampleResourceGroup IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeSampleResourceGroup(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(SampleResourceGroup)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/SampleResourceGroup.cs b/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/SampleResourceGroup.cs index 6d22a42c51e..7123d36de5e 100644 --- a/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/SampleResourceGroup.cs +++ b/test/TestServerProjects/subscriptionId-apiVersion/Generated/Models/SampleResourceGroup.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace subscriptionId_apiVersion.Models { /// The SampleResourceGroup. public partial class SampleResourceGroup { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal SampleResourceGroup() { @@ -18,10 +53,12 @@ internal SampleResourceGroup() /// Initializes a new instance of . /// resource group name 'testgroup101'. /// resource group location 'West US'. - internal SampleResourceGroup(string name, string location) + /// Keeps track of any properties unknown to the library. + internal SampleResourceGroup(string name, string location, IDictionary serializedAdditionalRawData) { Name = name; Location = location; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// resource group name 'testgroup101'. diff --git a/test/TestServerProjects/subscriptionId-apiVersion/Generated/SubscriptionIdApiVersionModelFactory.cs b/test/TestServerProjects/subscriptionId-apiVersion/Generated/SubscriptionIdApiVersionModelFactory.cs index 603500cc589..c35509cb4e8 100644 --- a/test/TestServerProjects/subscriptionId-apiVersion/Generated/SubscriptionIdApiVersionModelFactory.cs +++ b/test/TestServerProjects/subscriptionId-apiVersion/Generated/SubscriptionIdApiVersionModelFactory.cs @@ -16,7 +16,7 @@ public static partial class SubscriptionIdApiVersionModelFactory /// A new instance for mocking. public static SampleResourceGroup SampleResourceGroup(string name = null, string location = null) { - return new SampleResourceGroup(name, location); + return new SampleResourceGroup(name, location, serializedAdditionalRawData: null); } } } diff --git a/test/TestServerProjects/subscriptionId-apiVersion/subscriptionId_apiVersion.csproj b/test/TestServerProjects/subscriptionId-apiVersion/subscriptionId_apiVersion.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/subscriptionId-apiVersion/subscriptionId_apiVersion.csproj +++ b/test/TestServerProjects/subscriptionId-apiVersion/subscriptionId_apiVersion.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/url-multi-collectionFormat/Generated/Configuration.json b/test/TestServerProjects/url-multi-collectionFormat/Generated/Configuration.json index 1b7b648ee0a..9705bdf7929 100644 --- a/test/TestServerProjects/url-multi-collectionFormat/Generated/Configuration.json +++ b/test/TestServerProjects/url-multi-collectionFormat/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/url-multi-collectionFormat/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/url-multi-collectionFormat/Generated/Models/Error.Serialization.cs index 946c0a291a5..e5de200f382 100644 --- a/test/TestServerProjects/url-multi-collectionFormat/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/url-multi-collectionFormat/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace url_multi_collectionFormat.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/url-multi-collectionFormat/Generated/Models/Error.cs b/test/TestServerProjects/url-multi-collectionFormat/Generated/Models/Error.cs index 8b3a7b5ae3f..3d3e7ff9e0e 100644 --- a/test/TestServerProjects/url-multi-collectionFormat/Generated/Models/Error.cs +++ b/test/TestServerProjects/url-multi-collectionFormat/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace url_multi_collectionFormat.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/url-multi-collectionFormat/url_multi_collectionFormat.csproj b/test/TestServerProjects/url-multi-collectionFormat/url_multi_collectionFormat.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/url-multi-collectionFormat/url_multi_collectionFormat.csproj +++ b/test/TestServerProjects/url-multi-collectionFormat/url_multi_collectionFormat.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/url/Generated/Configuration.json b/test/TestServerProjects/url/Generated/Configuration.json index 5840e9491ad..00521da64e1 100644 --- a/test/TestServerProjects/url/Generated/Configuration.json +++ b/test/TestServerProjects/url/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/url/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/url/Generated/Models/Error.Serialization.cs index a33ceb36307..826f1aff158 100644 --- a/test/TestServerProjects/url/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/url/Generated/Models/Error.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace url.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteNumberValue(Status.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional status = default; Optional message = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("status"u8)) @@ -36,8 +94,44 @@ internal static Error DeserializeError(JsonElement element) message = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(status), message.Value, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); } - return new Error(Optional.ToNullable(status), message.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/url/Generated/Models/Error.cs b/test/TestServerProjects/url/Generated/Models/Error.cs index e5f5672fa1d..8b82373b7f9 100644 --- a/test/TestServerProjects/url/Generated/Models/Error.cs +++ b/test/TestServerProjects/url/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace url.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/url/url.csproj b/test/TestServerProjects/url/url.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/url/url.csproj +++ b/test/TestServerProjects/url/url.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/validation/Generated/Configuration.json b/test/TestServerProjects/validation/Generated/Configuration.json index e1589686541..e20d6a8c5f0 100644 --- a/test/TestServerProjects/validation/Generated/Configuration.json +++ b/test/TestServerProjects/validation/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/validation/Generated/Models/ChildProduct.Serialization.cs b/test/TestServerProjects/validation/Generated/Models/ChildProduct.Serialization.cs index 049c2c7d256..1567dcd12d4 100644 --- a/test/TestServerProjects/validation/Generated/Models/ChildProduct.Serialization.cs +++ b/test/TestServerProjects/validation/Generated/Models/ChildProduct.Serialization.cs @@ -5,15 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace validation.Models { - public partial class ChildProduct : IUtf8JsonSerializable + public partial class ChildProduct : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChildProduct)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("constProperty"u8); writer.WriteStringValue(ConstProperty.ToString()); @@ -22,17 +33,48 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("count"u8); writer.WriteNumberValue(Count.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ChildProduct DeserializeChildProduct(JsonElement element) + ChildProduct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ChildProduct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeChildProduct(document.RootElement, options); + } + + internal static ChildProduct DeserializeChildProduct(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } ChildProductConstProperty constProperty = default; Optional count = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("constProperty"u8)) @@ -49,8 +91,44 @@ internal static ChildProduct DeserializeChildProduct(JsonElement element) count = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new ChildProduct(constProperty, Optional.ToNullable(count)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ChildProduct(constProperty, Optional.ToNullable(count), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ChildProduct)} does not support '{options.Format}' format."); + } + } + + ChildProduct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeChildProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ChildProduct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/validation/Generated/Models/ChildProduct.cs b/test/TestServerProjects/validation/Generated/Models/ChildProduct.cs index 72d528b64d6..c88bf600532 100644 --- a/test/TestServerProjects/validation/Generated/Models/ChildProduct.cs +++ b/test/TestServerProjects/validation/Generated/Models/ChildProduct.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace validation.Models { /// The product documentation. public partial class ChildProduct { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ChildProduct() { @@ -19,10 +54,12 @@ public ChildProduct() /// Initializes a new instance of . /// Constant string. /// Count. - internal ChildProduct(ChildProductConstProperty constProperty, int? count) + /// Keeps track of any properties unknown to the library. + internal ChildProduct(ChildProductConstProperty constProperty, int? count, IDictionary serializedAdditionalRawData) { ConstProperty = constProperty; Count = count; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Constant string. diff --git a/test/TestServerProjects/validation/Generated/Models/ConstantProduct.Serialization.cs b/test/TestServerProjects/validation/Generated/Models/ConstantProduct.Serialization.cs index a3424255127..f9464d7459e 100644 --- a/test/TestServerProjects/validation/Generated/Models/ConstantProduct.Serialization.cs +++ b/test/TestServerProjects/validation/Generated/Models/ConstantProduct.Serialization.cs @@ -5,31 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace validation.Models { - public partial class ConstantProduct : IUtf8JsonSerializable + public partial class ConstantProduct : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConstantProduct)} does not support '{format}' format."); + } + writer.WriteStartObject(); writer.WritePropertyName("constProperty"u8); writer.WriteStringValue(ConstProperty.ToString()); writer.WritePropertyName("constProperty2"u8); writer.WriteStringValue(ConstProperty2.ToString()); + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static ConstantProduct DeserializeConstantProduct(JsonElement element) + ConstantProduct IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConstantProduct)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeConstantProduct(document.RootElement, options); + } + + internal static ConstantProduct DeserializeConstantProduct(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } ConstantProductConstProperty constProperty = default; ConstantProductConstProperty2 constProperty2 = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("constProperty"u8)) @@ -42,8 +84,44 @@ internal static ConstantProduct DeserializeConstantProduct(JsonElement element) constProperty2 = new ConstantProductConstProperty2(property.Value.GetString()); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new ConstantProduct(constProperty, constProperty2, serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(ConstantProduct)} does not support '{options.Format}' format."); } - return new ConstantProduct(constProperty, constProperty2); } + + ConstantProduct IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeConstantProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ConstantProduct)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/validation/Generated/Models/ConstantProduct.cs b/test/TestServerProjects/validation/Generated/Models/ConstantProduct.cs index 02b48dcb36b..9fe15e0a457 100644 --- a/test/TestServerProjects/validation/Generated/Models/ConstantProduct.cs +++ b/test/TestServerProjects/validation/Generated/Models/ConstantProduct.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace validation.Models { /// The product documentation. public partial class ConstantProduct { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ConstantProduct() { @@ -20,10 +55,12 @@ public ConstantProduct() /// Initializes a new instance of . /// Constant string. /// Constant string2. - internal ConstantProduct(ConstantProductConstProperty constProperty, ConstantProductConstProperty2 constProperty2) + /// Keeps track of any properties unknown to the library. + internal ConstantProduct(ConstantProductConstProperty constProperty, ConstantProductConstProperty2 constProperty2, IDictionary serializedAdditionalRawData) { ConstProperty = constProperty; ConstProperty2 = constProperty2; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Constant string. diff --git a/test/TestServerProjects/validation/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/validation/Generated/Models/Error.Serialization.cs index 8217892d4eb..3748948c335 100644 --- a/test/TestServerProjects/validation/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/validation/Generated/Models/Error.Serialization.cs @@ -5,15 +5,76 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace validation.Models { - internal partial class Error + internal partial class Error : IUtf8JsonSerializable, IJsonModel { - internal static Error DeserializeError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Code)) + { + writer.WritePropertyName("code"u8); + writer.WriteNumberValue(Code.Value); + } + if (Optional.IsDefined(Message)) + { + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + } + if (Optional.IsDefined(Fields)) + { + writer.WritePropertyName("fields"u8); + writer.WriteStringValue(Fields); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Error IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Error)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeError(document.RootElement, options); + } + + internal static Error DeserializeError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -21,6 +82,8 @@ internal static Error DeserializeError(JsonElement element) Optional code = default; Optional message = default; Optional fields = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("code"u8)) @@ -42,8 +105,44 @@ internal static Error DeserializeError(JsonElement element) fields = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Error(Optional.ToNullable(code), message.Value, fields.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Error(Optional.ToNullable(code), message.Value, fields.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/validation/Generated/Models/Error.cs b/test/TestServerProjects/validation/Generated/Models/Error.cs index a108c2141d3..8f6dd6975fd 100644 --- a/test/TestServerProjects/validation/Generated/Models/Error.cs +++ b/test/TestServerProjects/validation/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace validation.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -19,11 +54,13 @@ internal Error() /// /// /// - internal Error(int? code, string message, string fields) + /// Keeps track of any properties unknown to the library. + internal Error(int? code, string message, string fields, IDictionary serializedAdditionalRawData) { Code = code; Message = message; Fields = fields; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the code. diff --git a/test/TestServerProjects/validation/Generated/Models/Product.Serialization.cs b/test/TestServerProjects/validation/Generated/Models/Product.Serialization.cs index b01cdd65a7a..8b3ffb742d2 100644 --- a/test/TestServerProjects/validation/Generated/Models/Product.Serialization.cs +++ b/test/TestServerProjects/validation/Generated/Models/Product.Serialization.cs @@ -5,16 +5,26 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace validation.Models { - public partial class Product : IUtf8JsonSerializable + public partial class Product : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsCollectionDefined(DisplayNames)) { @@ -49,11 +59,40 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) writer.WritePropertyName("constStringAsEnum"u8); writer.WriteStringValue(ConstStringAsEnum.Value.ToString()); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } - internal static Product DeserializeProduct(JsonElement element) + Product IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Product)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeProduct(document.RootElement, options); + } + + internal static Product DeserializeProduct(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -66,6 +105,8 @@ internal static Product DeserializeProduct(JsonElement element) ProductConstInt constInt = default; ProductConstString constString = default; Optional constStringAsEnum = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("display_names"u8)) @@ -125,8 +166,44 @@ internal static Product DeserializeProduct(JsonElement element) constStringAsEnum = new EnumConst(property.Value.GetString()); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Product(Optional.ToList(displayNames), Optional.ToNullable(capacity), image.Value, child, constChild, constInt, constString, Optional.ToNullable(constStringAsEnum)); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Product(Optional.ToList(displayNames), Optional.ToNullable(capacity), image.Value, child, constChild, constInt, constString, Optional.ToNullable(constStringAsEnum), serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + Product IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeProduct(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Product)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/validation/Generated/Models/Product.cs b/test/TestServerProjects/validation/Generated/Models/Product.cs index c74276f12d3..0068bcae0bf 100644 --- a/test/TestServerProjects/validation/Generated/Models/Product.cs +++ b/test/TestServerProjects/validation/Generated/Models/Product.cs @@ -14,6 +14,38 @@ namespace validation.Models /// The product documentation. public partial class Product { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// The product documentation. /// The product documentation. @@ -39,7 +71,8 @@ public Product(ChildProduct child, ConstantProduct constChild) /// Constant int. /// Constant string. /// Constant string as Enum. - internal Product(IList displayNames, int? capacity, string image, ChildProduct child, ConstantProduct constChild, ProductConstInt constInt, ProductConstString constString, EnumConst? constStringAsEnum) + /// Keeps track of any properties unknown to the library. + internal Product(IList displayNames, int? capacity, string image, ChildProduct child, ConstantProduct constChild, ProductConstInt constInt, ProductConstString constString, EnumConst? constStringAsEnum, IDictionary serializedAdditionalRawData) { DisplayNames = displayNames; Capacity = capacity; @@ -49,6 +82,12 @@ internal Product(IList displayNames, int? capacity, string image, ChildP ConstInt = constInt; ConstString = constString; ConstStringAsEnum = constStringAsEnum; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Product() + { } /// Non required array of unique items from 0 to 6 elements. diff --git a/test/TestServerProjects/validation/Generated/ValidationModelFactory.cs b/test/TestServerProjects/validation/Generated/ValidationModelFactory.cs index d94a3455a46..6cd345b28c6 100644 --- a/test/TestServerProjects/validation/Generated/ValidationModelFactory.cs +++ b/test/TestServerProjects/validation/Generated/ValidationModelFactory.cs @@ -27,7 +27,7 @@ public static Product Product(IEnumerable displayNames = null, int? capa { displayNames ??= new List(); - return new Product(displayNames?.ToList(), capacity, image, child, constChild, constInt, constString, constStringAsEnum); + return new Product(displayNames?.ToList(), capacity, image, child, constChild, constInt, constString, constStringAsEnum, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -36,7 +36,7 @@ public static Product Product(IEnumerable displayNames = null, int? capa /// A new instance for mocking. public static ChildProduct ChildProduct(ChildProductConstProperty constProperty = default, int? count = null) { - return new ChildProduct(constProperty, count); + return new ChildProduct(constProperty, count, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -45,7 +45,7 @@ public static ChildProduct ChildProduct(ChildProductConstProperty constProperty /// A new instance for mocking. public static ConstantProduct ConstantProduct(ConstantProductConstProperty constProperty = default, ConstantProductConstProperty2 constProperty2 = default) { - return new ConstantProduct(constProperty, constProperty2); + return new ConstantProduct(constProperty, constProperty2, serializedAdditionalRawData: null); } } } diff --git a/test/TestServerProjects/validation/validation.csproj b/test/TestServerProjects/validation/validation.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/validation/validation.csproj +++ b/test/TestServerProjects/validation/validation.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/xml-service/Generated/Configuration.json b/test/TestServerProjects/xml-service/Generated/Configuration.json index b17684ca399..67485a44f15 100644 --- a/test/TestServerProjects/xml-service/Generated/Configuration.json +++ b/test/TestServerProjects/xml-service/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/xml-service/Generated/Models/AccessPolicy.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/AccessPolicy.Serialization.cs index 49c9bc1d4cf..66917bdefbd 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/AccessPolicy.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/AccessPolicy.Serialization.cs @@ -6,15 +6,17 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class AccessPolicy : IXmlSerializable + public partial class AccessPolicy : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "AccessPolicy"); writer.WriteStartElement("Start"); @@ -29,8 +31,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static AccessPolicy DeserializeAccessPolicy(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static AccessPolicy DeserializeAccessPolicy(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + DateTimeOffset start = default; DateTimeOffset expiry = default; string permission = default; @@ -46,7 +52,41 @@ internal static AccessPolicy DeserializeAccessPolicy(XElement element) { permission = (string)permissionElement; } - return new AccessPolicy(start, expiry, permission); + return new AccessPolicy(start, expiry, permission, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(AccessPolicy)} does not support '{options.Format}' format."); + } } + + AccessPolicy IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeAccessPolicy(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(AccessPolicy)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/AccessPolicy.cs b/test/TestServerProjects/xml-service/Generated/Models/AccessPolicy.cs index 809c98aaaa8..4427ecc11b1 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/AccessPolicy.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/AccessPolicy.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace xml_service.Models @@ -13,6 +14,38 @@ namespace xml_service.Models /// An Access policy. public partial class AccessPolicy { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// the date-time the policy is active. /// the date-time the policy expires. @@ -27,6 +60,24 @@ public AccessPolicy(DateTimeOffset start, DateTimeOffset expiry, string permissi Permission = permission; } + /// Initializes a new instance of . + /// the date-time the policy is active. + /// the date-time the policy expires. + /// the permissions for the acl policy. + /// Keeps track of any properties unknown to the library. + internal AccessPolicy(DateTimeOffset start, DateTimeOffset expiry, string permission, IDictionary serializedAdditionalRawData) + { + Start = start; + Expiry = expiry; + Permission = permission; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal AccessPolicy() + { + } + /// the date-time the policy is active. public DateTimeOffset Start { get; set; } /// the date-time the policy expires. diff --git a/test/TestServerProjects/xml-service/Generated/Models/AppleBarrel.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/AppleBarrel.Serialization.cs index 337dba045dd..087eba76bae 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/AppleBarrel.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/AppleBarrel.Serialization.cs @@ -5,16 +5,19 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class AppleBarrel : IXmlSerializable + public partial class AppleBarrel : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "AppleBarrel"); if (Optional.IsCollectionDefined(GoodApples)) @@ -42,8 +45,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static AppleBarrel DeserializeAppleBarrel(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static AppleBarrel DeserializeAppleBarrel(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + IList goodApples = default; IList badApples = default; if (element.Element("GoodApples") is XElement goodApplesElement) @@ -64,7 +71,41 @@ internal static AppleBarrel DeserializeAppleBarrel(XElement element) } badApples = array; } - return new AppleBarrel(goodApples, badApples); + return new AppleBarrel(goodApples, badApples, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(AppleBarrel)} does not support '{options.Format}' format."); + } } + + AppleBarrel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeAppleBarrel(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(AppleBarrel)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/AppleBarrel.cs b/test/TestServerProjects/xml-service/Generated/Models/AppleBarrel.cs index 997e9f585d6..a0b375dde5f 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/AppleBarrel.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/AppleBarrel.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace xml_service.Models /// A barrel of apples. public partial class AppleBarrel { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public AppleBarrel() { @@ -23,10 +56,12 @@ public AppleBarrel() /// Initializes a new instance of . /// /// - internal AppleBarrel(IList goodApples, IList badApples) + /// Keeps track of any properties unknown to the library. + internal AppleBarrel(IList goodApples, IList badApples, IDictionary serializedAdditionalRawData) { GoodApples = goodApples; BadApples = badApples; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the good apples. diff --git a/test/TestServerProjects/xml-service/Generated/Models/Banana.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/Banana.Serialization.cs index 439c84aae2d..9727ddc4701 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Banana.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Banana.Serialization.cs @@ -6,15 +6,17 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class Banana : IXmlSerializable + public partial class Banana : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "banana"); if (Optional.IsDefined(Name)) @@ -38,8 +40,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static Banana DeserializeBanana(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static Banana DeserializeBanana(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string name = default; string flavor = default; DateTimeOffset? expiration = default; @@ -55,7 +61,41 @@ internal static Banana DeserializeBanana(XElement element) { expiration = expirationElement.GetDateTimeOffsetValue("O"); } - return new Banana(name, flavor, expiration); + return new Banana(name, flavor, expiration, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(Banana)} does not support '{options.Format}' format."); + } } + + Banana IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeBanana(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(Banana)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/Banana.cs b/test/TestServerProjects/xml-service/Generated/Models/Banana.cs index c4b3d06e9ea..79e9ca702ae 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Banana.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Banana.cs @@ -6,12 +6,45 @@ #nullable disable using System; +using System.Collections.Generic; namespace xml_service.Models { /// A banana. public partial class Banana { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Banana() { @@ -21,11 +54,13 @@ public Banana() /// /// /// The time at which you should reconsider eating this banana. - internal Banana(string name, string flavor, DateTimeOffset? expiration) + /// Keeps track of any properties unknown to the library. + internal Banana(string name, string flavor, DateTimeOffset? expiration, IDictionary serializedAdditionalRawData) { Name = name; Flavor = flavor; Expiration = expiration; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the name. diff --git a/test/TestServerProjects/xml-service/Generated/Models/Blob.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/Blob.Serialization.cs index 6645fced5d7..1663cf3718a 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Blob.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Blob.Serialization.cs @@ -5,15 +5,49 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; +using System.Xml; using System.Xml.Linq; +using Azure.Core; namespace xml_service.Models { - public partial class Blob + public partial class Blob : IXmlSerializable, IPersistableModel { - internal static Blob DeserializeBlob(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "Blob"); + writer.WriteStartElement("Name"); + writer.WriteValue(Name); + writer.WriteEndElement(); + writer.WriteStartElement("Deleted"); + writer.WriteValue(Deleted); + writer.WriteEndElement(); + writer.WriteStartElement("Snapshot"); + writer.WriteValue(Snapshot); + writer.WriteEndElement(); + writer.WriteObjectValue(Properties, "Properties"); + if (Optional.IsCollectionDefined(Metadata)) + { + foreach (var pair in Metadata) + { + writer.WriteStartElement("String"); + writer.WriteValue(pair.Value); + writer.WriteEndElement(); + } + } + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static Blob DeserializeBlob(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + string name = default; bool deleted = default; string snapshot = default; @@ -44,7 +78,41 @@ internal static Blob DeserializeBlob(XElement element) } metadata = dictionary; } - return new Blob(name, deleted, snapshot, properties, metadata); + return new Blob(name, deleted, snapshot, properties, metadata, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(Blob)} does not support '{options.Format}' format."); + } } + + Blob IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeBlob(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(Blob)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/Blob.cs b/test/TestServerProjects/xml-service/Generated/Models/Blob.cs index d0ea1a31198..7544b9701dd 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Blob.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Blob.cs @@ -14,6 +14,38 @@ namespace xml_service.Models /// An Azure Storage blob. public partial class Blob { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// @@ -39,13 +71,20 @@ internal Blob(string name, bool deleted, string snapshot, BlobProperties propert /// /// Properties of a blob. /// Dictionary of <string>. - internal Blob(string name, bool deleted, string snapshot, BlobProperties properties, IReadOnlyDictionary metadata) + /// Keeps track of any properties unknown to the library. + internal Blob(string name, bool deleted, string snapshot, BlobProperties properties, IReadOnlyDictionary metadata, IDictionary serializedAdditionalRawData) { Name = name; Deleted = deleted; Snapshot = snapshot; Properties = properties; Metadata = metadata; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Blob() + { } /// Gets the name. diff --git a/test/TestServerProjects/xml-service/Generated/Models/BlobPrefix.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/BlobPrefix.Serialization.cs index faaa0826e5e..83149fbd33f 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/BlobPrefix.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/BlobPrefix.Serialization.cs @@ -5,20 +5,72 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; +using System.Xml; using System.Xml.Linq; +using Azure.Core; namespace xml_service.Models { - public partial class BlobPrefix + public partial class BlobPrefix : IXmlSerializable, IPersistableModel { - internal static BlobPrefix DeserializeBlobPrefix(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "BlobPrefix"); + writer.WriteStartElement("Name"); + writer.WriteValue(Name); + writer.WriteEndElement(); + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static BlobPrefix DeserializeBlobPrefix(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + string name = default; if (element.Element("Name") is XElement nameElement) { name = (string)nameElement; } - return new BlobPrefix(name); + return new BlobPrefix(name, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(BlobPrefix)} does not support '{options.Format}' format."); + } } + + BlobPrefix IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeBlobPrefix(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(BlobPrefix)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/BlobPrefix.cs b/test/TestServerProjects/xml-service/Generated/Models/BlobPrefix.cs index e0d868ad030..1d62d9c7807 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/BlobPrefix.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/BlobPrefix.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace xml_service.Models @@ -13,6 +14,38 @@ namespace xml_service.Models /// The BlobPrefix. public partial class BlobPrefix { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// is null. @@ -23,6 +56,20 @@ internal BlobPrefix(string name) Name = name; } + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal BlobPrefix(string name, IDictionary serializedAdditionalRawData) + { + Name = name; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal BlobPrefix() + { + } + /// Gets the name. public string Name { get; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/BlobProperties.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/BlobProperties.Serialization.cs index a5ad4469c87..679689a242d 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/BlobProperties.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/BlobProperties.Serialization.cs @@ -6,15 +6,190 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.IO; +using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class BlobProperties + public partial class BlobProperties : IXmlSerializable, IPersistableModel { - internal static BlobProperties DeserializeBlobProperties(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "BlobProperties"); + writer.WriteStartElement("Last-Modified"); + writer.WriteValue(LastModified, "R"); + writer.WriteEndElement(); + writer.WriteStartElement("Etag"); + writer.WriteValue(Etag); + writer.WriteEndElement(); + if (Optional.IsDefined(ContentLength)) + { + writer.WriteStartElement("Content-Length"); + writer.WriteValue(ContentLength.Value); + writer.WriteEndElement(); + } + if (Optional.IsDefined(ContentType)) + { + writer.WriteStartElement("Content-Type"); + writer.WriteValue(ContentType); + writer.WriteEndElement(); + } + if (Optional.IsDefined(ContentEncoding)) + { + writer.WriteStartElement("Content-Encoding"); + writer.WriteValue(ContentEncoding); + writer.WriteEndElement(); + } + if (Optional.IsDefined(ContentLanguage)) + { + writer.WriteStartElement("Content-Language"); + writer.WriteValue(ContentLanguage); + writer.WriteEndElement(); + } + if (Optional.IsDefined(ContentMD5)) + { + writer.WriteStartElement("Content-MD5"); + writer.WriteValue(ContentMD5); + writer.WriteEndElement(); + } + if (Optional.IsDefined(ContentDisposition)) + { + writer.WriteStartElement("Content-Disposition"); + writer.WriteValue(ContentDisposition); + writer.WriteEndElement(); + } + if (Optional.IsDefined(CacheControl)) + { + writer.WriteStartElement("Cache-Control"); + writer.WriteValue(CacheControl); + writer.WriteEndElement(); + } + if (Optional.IsDefined(BlobSequenceNumber)) + { + writer.WriteStartElement("x-ms-blob-sequence-number"); + writer.WriteValue(BlobSequenceNumber.Value); + writer.WriteEndElement(); + } + if (Optional.IsDefined(BlobType)) + { + writer.WriteStartElement("BlobType"); + writer.WriteValue(BlobType.Value.ToSerialString()); + writer.WriteEndElement(); + } + if (Optional.IsDefined(LeaseStatus)) + { + writer.WriteStartElement("LeaseStatus"); + writer.WriteValue(LeaseStatus.Value.ToSerialString()); + writer.WriteEndElement(); + } + if (Optional.IsDefined(LeaseState)) + { + writer.WriteStartElement("LeaseState"); + writer.WriteValue(LeaseState.Value.ToSerialString()); + writer.WriteEndElement(); + } + if (Optional.IsDefined(LeaseDuration)) + { + writer.WriteStartElement("LeaseDuration"); + writer.WriteValue(LeaseDuration.Value.ToSerialString()); + writer.WriteEndElement(); + } + if (Optional.IsDefined(CopyId)) + { + writer.WriteStartElement("CopyId"); + writer.WriteValue(CopyId); + writer.WriteEndElement(); + } + if (Optional.IsDefined(CopyStatus)) + { + writer.WriteStartElement("CopyStatus"); + writer.WriteValue(CopyStatus.Value.ToSerialString()); + writer.WriteEndElement(); + } + if (Optional.IsDefined(CopySource)) + { + writer.WriteStartElement("CopySource"); + writer.WriteValue(CopySource); + writer.WriteEndElement(); + } + if (Optional.IsDefined(CopyProgress)) + { + writer.WriteStartElement("CopyProgress"); + writer.WriteValue(CopyProgress); + writer.WriteEndElement(); + } + if (Optional.IsDefined(CopyCompletionTime)) + { + writer.WriteStartElement("CopyCompletionTime"); + writer.WriteValue(CopyCompletionTime.Value, "R"); + writer.WriteEndElement(); + } + if (Optional.IsDefined(CopyStatusDescription)) + { + writer.WriteStartElement("CopyStatusDescription"); + writer.WriteValue(CopyStatusDescription); + writer.WriteEndElement(); + } + if (Optional.IsDefined(ServerEncrypted)) + { + writer.WriteStartElement("ServerEncrypted"); + writer.WriteValue(ServerEncrypted.Value); + writer.WriteEndElement(); + } + if (Optional.IsDefined(IncrementalCopy)) + { + writer.WriteStartElement("IncrementalCopy"); + writer.WriteValue(IncrementalCopy.Value); + writer.WriteEndElement(); + } + if (Optional.IsDefined(DestinationSnapshot)) + { + writer.WriteStartElement("DestinationSnapshot"); + writer.WriteValue(DestinationSnapshot); + writer.WriteEndElement(); + } + if (Optional.IsDefined(DeletedTime)) + { + writer.WriteStartElement("DeletedTime"); + writer.WriteValue(DeletedTime.Value, "R"); + writer.WriteEndElement(); + } + if (Optional.IsDefined(RemainingRetentionDays)) + { + writer.WriteStartElement("RemainingRetentionDays"); + writer.WriteValue(RemainingRetentionDays.Value); + writer.WriteEndElement(); + } + if (Optional.IsDefined(AccessTier)) + { + writer.WriteStartElement("AccessTier"); + writer.WriteValue(AccessTier.Value.ToString()); + writer.WriteEndElement(); + } + if (Optional.IsDefined(AccessTierInferred)) + { + writer.WriteStartElement("AccessTierInferred"); + writer.WriteValue(AccessTierInferred.Value); + writer.WriteEndElement(); + } + if (Optional.IsDefined(ArchiveStatus)) + { + writer.WriteStartElement("ArchiveStatus"); + writer.WriteValue(ArchiveStatus.Value.ToString()); + writer.WriteEndElement(); + } + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static BlobProperties DeserializeBlobProperties(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + DateTimeOffset lastModified = default; string etag = default; long? contentLength = default; @@ -155,7 +330,41 @@ internal static BlobProperties DeserializeBlobProperties(XElement element) { archiveStatus = new ArchiveStatus(archiveStatusElement.Value); } - return new BlobProperties(lastModified, etag, contentLength, contentType, contentEncoding, contentLanguage, contentMD5, contentDisposition, cacheControl, blobSequenceNumber, blobType, leaseStatus, leaseState, leaseDuration, copyId, copyStatus, copySource, copyProgress, copyCompletionTime, copyStatusDescription, serverEncrypted, incrementalCopy, destinationSnapshot, deletedTime, remainingRetentionDays, accessTier, accessTierInferred, archiveStatus); + return new BlobProperties(lastModified, etag, contentLength, contentType, contentEncoding, contentLanguage, contentMD5, contentDisposition, cacheControl, blobSequenceNumber, blobType, leaseStatus, leaseState, leaseDuration, copyId, copyStatus, copySource, copyProgress, copyCompletionTime, copyStatusDescription, serverEncrypted, incrementalCopy, destinationSnapshot, deletedTime, remainingRetentionDays, accessTier, accessTierInferred, archiveStatus, serializedAdditionalRawData: null); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(BlobProperties)} does not support '{options.Format}' format."); + } + } + + BlobProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeBlobProperties(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(BlobProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/BlobProperties.cs b/test/TestServerProjects/xml-service/Generated/Models/BlobProperties.cs index 2ea3fae8b5b..0277494aff5 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/BlobProperties.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/BlobProperties.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace xml_service.Models @@ -13,6 +14,38 @@ namespace xml_service.Models /// Properties of a blob. public partial class BlobProperties { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// @@ -54,7 +87,8 @@ internal BlobProperties(DateTimeOffset lastModified, string etag) /// /// /// - internal BlobProperties(DateTimeOffset lastModified, string etag, long? contentLength, string contentType, string contentEncoding, string contentLanguage, string contentMD5, string contentDisposition, string cacheControl, int? blobSequenceNumber, BlobType? blobType, LeaseStatusType? leaseStatus, LeaseStateType? leaseState, LeaseDurationType? leaseDuration, string copyId, CopyStatusType? copyStatus, string copySource, string copyProgress, DateTimeOffset? copyCompletionTime, string copyStatusDescription, bool? serverEncrypted, bool? incrementalCopy, string destinationSnapshot, DateTimeOffset? deletedTime, int? remainingRetentionDays, AccessTier? accessTier, bool? accessTierInferred, ArchiveStatus? archiveStatus) + /// Keeps track of any properties unknown to the library. + internal BlobProperties(DateTimeOffset lastModified, string etag, long? contentLength, string contentType, string contentEncoding, string contentLanguage, string contentMD5, string contentDisposition, string cacheControl, int? blobSequenceNumber, BlobType? blobType, LeaseStatusType? leaseStatus, LeaseStateType? leaseState, LeaseDurationType? leaseDuration, string copyId, CopyStatusType? copyStatus, string copySource, string copyProgress, DateTimeOffset? copyCompletionTime, string copyStatusDescription, bool? serverEncrypted, bool? incrementalCopy, string destinationSnapshot, DateTimeOffset? deletedTime, int? remainingRetentionDays, AccessTier? accessTier, bool? accessTierInferred, ArchiveStatus? archiveStatus, IDictionary serializedAdditionalRawData) { LastModified = lastModified; Etag = etag; @@ -84,6 +118,12 @@ internal BlobProperties(DateTimeOffset lastModified, string etag, long? contentL AccessTier = accessTier; AccessTierInferred = accessTierInferred; ArchiveStatus = archiveStatus; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal BlobProperties() + { } /// Gets the last modified. diff --git a/test/TestServerProjects/xml-service/Generated/Models/Blobs.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/Blobs.Serialization.cs index 69ce1f67e96..489573fdc2c 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Blobs.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Blobs.Serialization.cs @@ -5,15 +5,44 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; +using System.Xml; using System.Xml.Linq; +using Azure.Core; namespace xml_service.Models { - public partial class Blobs + public partial class Blobs : IXmlSerializable, IPersistableModel { - internal static Blobs DeserializeBlobs(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "Blobs"); + if (Optional.IsCollectionDefined(BlobPrefix)) + { + foreach (var item in BlobPrefix) + { + writer.WriteObjectValue(item, "BlobPrefix"); + } + } + if (Optional.IsCollectionDefined(Blob)) + { + foreach (var item in Blob) + { + writer.WriteObjectValue(item, "Blob"); + } + } + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static Blobs DeserializeBlobs(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + IReadOnlyList blobPrefix = default; IReadOnlyList blob = default; var array = new List(); @@ -28,7 +57,41 @@ internal static Blobs DeserializeBlobs(XElement element) array0.Add(Models.Blob.DeserializeBlob(e)); } blob = array0; - return new Blobs(blobPrefix, blob); + return new Blobs(blobPrefix, blob, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(Blobs)} does not support '{options.Format}' format."); + } } + + Blobs IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeBlobs(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(Blobs)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/Blobs.cs b/test/TestServerProjects/xml-service/Generated/Models/Blobs.cs index 66eab27a1a5..e8f8b37d3e5 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Blobs.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Blobs.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace xml_service.Models /// The Blobs. public partial class Blobs { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Blobs() { @@ -23,10 +56,12 @@ internal Blobs() /// Initializes a new instance of . /// /// - internal Blobs(IReadOnlyList blobPrefix, IReadOnlyList blob) + /// Keeps track of any properties unknown to the library. + internal Blobs(IReadOnlyList blobPrefix, IReadOnlyList blob, IDictionary serializedAdditionalRawData) { BlobPrefix = blobPrefix; Blob = blob; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the blob prefix. diff --git a/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeNoMeta.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeNoMeta.Serialization.cs index e2e961355f9..3dc2f3e6187 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeNoMeta.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeNoMeta.Serialization.cs @@ -5,15 +5,18 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class ComplexTypeNoMeta : IXmlSerializable + public partial class ComplexTypeNoMeta : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "ComplexTypeNoMeta"); if (Optional.IsDefined(ID)) @@ -25,14 +28,52 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static ComplexTypeNoMeta DeserializeComplexTypeNoMeta(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ComplexTypeNoMeta DeserializeComplexTypeNoMeta(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string id = default; if (element.Element("ID") is XElement idElement) { id = (string)idElement; } - return new ComplexTypeNoMeta(id); + return new ComplexTypeNoMeta(id, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ComplexTypeNoMeta)} does not support '{options.Format}' format."); + } } + + ComplexTypeNoMeta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeComplexTypeNoMeta(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ComplexTypeNoMeta)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeNoMeta.cs b/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeNoMeta.cs index 3c8aa4ee7d6..3d8425f34e3 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeNoMeta.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeNoMeta.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xml_service.Models { /// I am a complex type with no XML node. public partial class ComplexTypeNoMeta { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ComplexTypeNoMeta() { @@ -17,9 +52,11 @@ public ComplexTypeNoMeta() /// Initializes a new instance of . /// The id of the res. - internal ComplexTypeNoMeta(string id) + /// Keeps track of any properties unknown to the library. + internal ComplexTypeNoMeta(string id, IDictionary serializedAdditionalRawData) { ID = id; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// The id of the res. diff --git a/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeWithMeta.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeWithMeta.Serialization.cs index bbb4ca031b5..2613593224a 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeWithMeta.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeWithMeta.Serialization.cs @@ -5,15 +5,18 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class ComplexTypeWithMeta : IXmlSerializable + public partial class ComplexTypeWithMeta : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "XMLComplexTypeWithMeta"); if (Optional.IsDefined(ID)) @@ -25,14 +28,52 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static ComplexTypeWithMeta DeserializeComplexTypeWithMeta(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ComplexTypeWithMeta DeserializeComplexTypeWithMeta(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string id = default; if (element.Element("ID") is XElement idElement) { id = (string)idElement; } - return new ComplexTypeWithMeta(id); + return new ComplexTypeWithMeta(id, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ComplexTypeWithMeta)} does not support '{options.Format}' format."); + } } + + ComplexTypeWithMeta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeComplexTypeWithMeta(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ComplexTypeWithMeta)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeWithMeta.cs b/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeWithMeta.cs index b4e6b244029..6b5147c9304 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeWithMeta.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ComplexTypeWithMeta.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xml_service.Models { /// I am a complex type with XML node. public partial class ComplexTypeWithMeta { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ComplexTypeWithMeta() { @@ -17,9 +52,11 @@ public ComplexTypeWithMeta() /// Initializes a new instance of . /// The id of the res. - internal ComplexTypeWithMeta(string id) + /// Keeps track of any properties unknown to the library. + internal ComplexTypeWithMeta(string id, IDictionary serializedAdditionalRawData) { ID = id; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// The id of the res. diff --git a/test/TestServerProjects/xml-service/Generated/Models/Container.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/Container.Serialization.cs index fe91a7683a4..20aca975f51 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Container.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Container.Serialization.cs @@ -5,15 +5,43 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; +using System.Xml; using System.Xml.Linq; +using Azure.Core; namespace xml_service.Models { - public partial class Container + public partial class Container : IXmlSerializable, IPersistableModel { - internal static Container DeserializeContainer(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "Container"); + writer.WriteStartElement("Name"); + writer.WriteValue(Name); + writer.WriteEndElement(); + writer.WriteObjectValue(Properties, "Properties"); + if (Optional.IsCollectionDefined(Metadata)) + { + foreach (var pair in Metadata) + { + writer.WriteStartElement("String"); + writer.WriteValue(pair.Value); + writer.WriteEndElement(); + } + } + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static Container DeserializeContainer(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + string name = default; ContainerProperties properties = default; IReadOnlyDictionary metadata = default; @@ -34,7 +62,41 @@ internal static Container DeserializeContainer(XElement element) } metadata = dictionary; } - return new Container(name, properties, metadata); + return new Container(name, properties, metadata, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(Container)} does not support '{options.Format}' format."); + } } + + Container IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeContainer(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(Container)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/Container.cs b/test/TestServerProjects/xml-service/Generated/Models/Container.cs index ed2392c2d10..30fe8961fe7 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Container.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Container.cs @@ -14,6 +14,38 @@ namespace xml_service.Models /// An Azure Storage container. public partial class Container { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// Properties of a container. @@ -32,11 +64,18 @@ internal Container(string name, ContainerProperties properties) /// /// Properties of a container. /// Dictionary of <string>. - internal Container(string name, ContainerProperties properties, IReadOnlyDictionary metadata) + /// Keeps track of any properties unknown to the library. + internal Container(string name, ContainerProperties properties, IReadOnlyDictionary metadata, IDictionary serializedAdditionalRawData) { Name = name; Properties = properties; Metadata = metadata; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Container() + { } /// Gets the name. diff --git a/test/TestServerProjects/xml-service/Generated/Models/ContainerProperties.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/ContainerProperties.Serialization.cs index b062bea0c85..3a054a964fb 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ContainerProperties.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ContainerProperties.Serialization.cs @@ -6,15 +6,58 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.IO; +using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class ContainerProperties + public partial class ContainerProperties : IXmlSerializable, IPersistableModel { - internal static ContainerProperties DeserializeContainerProperties(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "ContainerProperties"); + writer.WriteStartElement("Last-Modified"); + writer.WriteValue(LastModified, "R"); + writer.WriteEndElement(); + writer.WriteStartElement("Etag"); + writer.WriteValue(Etag); + writer.WriteEndElement(); + if (Optional.IsDefined(LeaseStatus)) + { + writer.WriteStartElement("LeaseStatus"); + writer.WriteValue(LeaseStatus.Value.ToSerialString()); + writer.WriteEndElement(); + } + if (Optional.IsDefined(LeaseState)) + { + writer.WriteStartElement("LeaseState"); + writer.WriteValue(LeaseState.Value.ToSerialString()); + writer.WriteEndElement(); + } + if (Optional.IsDefined(LeaseDuration)) + { + writer.WriteStartElement("LeaseDuration"); + writer.WriteValue(LeaseDuration.Value.ToSerialString()); + writer.WriteEndElement(); + } + if (Optional.IsDefined(PublicAccess)) + { + writer.WriteStartElement("PublicAccess"); + writer.WriteValue(PublicAccess.Value.ToString()); + writer.WriteEndElement(); + } + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ContainerProperties DeserializeContainerProperties(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + DateTimeOffset lastModified = default; string etag = default; LeaseStatusType? leaseStatus = default; @@ -45,7 +88,41 @@ internal static ContainerProperties DeserializeContainerProperties(XElement elem { publicAccess = new PublicAccessType(publicAccessElement.Value); } - return new ContainerProperties(lastModified, etag, leaseStatus, leaseState, leaseDuration, publicAccess); + return new ContainerProperties(lastModified, etag, leaseStatus, leaseState, leaseDuration, publicAccess, serializedAdditionalRawData: null); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ContainerProperties)} does not support '{options.Format}' format."); + } + } + + ContainerProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeContainerProperties(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ContainerProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/ContainerProperties.cs b/test/TestServerProjects/xml-service/Generated/Models/ContainerProperties.cs index 8fc6b29d38a..8e9b9fb4a9c 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ContainerProperties.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ContainerProperties.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace xml_service.Models @@ -13,6 +14,38 @@ namespace xml_service.Models /// Properties of a container. public partial class ContainerProperties { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// @@ -32,7 +65,8 @@ internal ContainerProperties(DateTimeOffset lastModified, string etag) /// /// /// - internal ContainerProperties(DateTimeOffset lastModified, string etag, LeaseStatusType? leaseStatus, LeaseStateType? leaseState, LeaseDurationType? leaseDuration, PublicAccessType? publicAccess) + /// Keeps track of any properties unknown to the library. + internal ContainerProperties(DateTimeOffset lastModified, string etag, LeaseStatusType? leaseStatus, LeaseStateType? leaseState, LeaseDurationType? leaseDuration, PublicAccessType? publicAccess, IDictionary serializedAdditionalRawData) { LastModified = lastModified; Etag = etag; @@ -40,6 +74,12 @@ internal ContainerProperties(DateTimeOffset lastModified, string etag, LeaseStat LeaseState = leaseState; LeaseDuration = leaseDuration; PublicAccess = publicAccess; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ContainerProperties() + { } /// Gets the last modified. diff --git a/test/TestServerProjects/xml-service/Generated/Models/CorsRule.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/CorsRule.Serialization.cs index d5bd402a63b..e3c59f0ada6 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/CorsRule.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/CorsRule.Serialization.cs @@ -5,15 +5,18 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class CorsRule : IXmlSerializable + public partial class CorsRule : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "CorsRule"); writer.WriteStartElement("AllowedOrigins"); @@ -34,8 +37,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static CorsRule DeserializeCorsRule(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static CorsRule DeserializeCorsRule(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string allowedOrigins = default; string allowedMethods = default; string allowedHeaders = default; @@ -61,7 +68,41 @@ internal static CorsRule DeserializeCorsRule(XElement element) { maxAgeInSeconds = (int)maxAgeInSecondsElement; } - return new CorsRule(allowedOrigins, allowedMethods, allowedHeaders, exposedHeaders, maxAgeInSeconds); + return new CorsRule(allowedOrigins, allowedMethods, allowedHeaders, exposedHeaders, maxAgeInSeconds, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(CorsRule)} does not support '{options.Format}' format."); + } } + + CorsRule IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeCorsRule(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(CorsRule)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/CorsRule.cs b/test/TestServerProjects/xml-service/Generated/Models/CorsRule.cs index e2a3c7d5139..a8ef0660021 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/CorsRule.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/CorsRule.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace xml_service.Models @@ -13,6 +14,38 @@ namespace xml_service.Models /// CORS is an HTTP feature that enables a web application running under one domain to access resources in another domain. Web browsers implement a security restriction known as same-origin policy that prevents a web page from calling APIs in a different domain; CORS provides a secure way to allow one domain (the origin domain) to call APIs in another domain. public partial class CorsRule { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// The origin domains that are permitted to make a request against the storage service via CORS. The origin domain is the domain from which the request originates. Note that the origin must be an exact case-sensitive match with the origin that the user age sends to the service. You can also use the wildcard character '*' to allow all origin domains to make requests via CORS. /// The methods (HTTP request verbs) that the origin domain may use for a CORS request. (comma separated). @@ -34,6 +67,28 @@ public CorsRule(string allowedOrigins, string allowedMethods, string allowedHead MaxAgeInSeconds = maxAgeInSeconds; } + /// Initializes a new instance of . + /// The origin domains that are permitted to make a request against the storage service via CORS. The origin domain is the domain from which the request originates. Note that the origin must be an exact case-sensitive match with the origin that the user age sends to the service. You can also use the wildcard character '*' to allow all origin domains to make requests via CORS. + /// The methods (HTTP request verbs) that the origin domain may use for a CORS request. (comma separated). + /// the request headers that the origin domain may specify on the CORS request. + /// The response headers that may be sent in the response to the CORS request and exposed by the browser to the request issuer. + /// The maximum amount time that a browser should cache the preflight OPTIONS request. + /// Keeps track of any properties unknown to the library. + internal CorsRule(string allowedOrigins, string allowedMethods, string allowedHeaders, string exposedHeaders, int maxAgeInSeconds, IDictionary serializedAdditionalRawData) + { + AllowedOrigins = allowedOrigins; + AllowedMethods = allowedMethods; + AllowedHeaders = allowedHeaders; + ExposedHeaders = exposedHeaders; + MaxAgeInSeconds = maxAgeInSeconds; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal CorsRule() + { + } + /// The origin domains that are permitted to make a request against the storage service via CORS. The origin domain is the domain from which the request originates. Note that the origin must be an exact case-sensitive match with the origin that the user age sends to the service. You can also use the wildcard character '*' to allow all origin domains to make requests via CORS. public string AllowedOrigins { get; set; } /// The methods (HTTP request verbs) that the origin domain may use for a CORS request. (comma separated). diff --git a/test/TestServerProjects/xml-service/Generated/Models/Error.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/Error.Serialization.cs index 63abede3b0a..d22dca0eeff 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Error.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Error.Serialization.cs @@ -5,14 +5,41 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; +using System.Xml; using System.Xml.Linq; +using Azure.Core; namespace xml_service.Models { - internal partial class Error + internal partial class Error : IXmlSerializable, IPersistableModel { - internal static Error DeserializeError(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "Error"); + if (Optional.IsDefined(Status)) + { + writer.WriteStartElement("status"); + writer.WriteValue(Status.Value); + writer.WriteEndElement(); + } + if (Optional.IsDefined(Message)) + { + writer.WriteStartElement("message"); + writer.WriteValue(Message); + writer.WriteEndElement(); + } + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static Error DeserializeError(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + int? status = default; string message = default; if (element.Element("status") is XElement statusElement) @@ -23,7 +50,41 @@ internal static Error DeserializeError(XElement element) { message = (string)messageElement; } - return new Error(status, message); + return new Error(status, message, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } } + + Error IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeError(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(Error)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/Error.cs b/test/TestServerProjects/xml-service/Generated/Models/Error.cs index 03abf0b1a0b..5200c65e0e3 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Error.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Error.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xml_service.Models { /// The Error. internal partial class Error { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Error() { @@ -18,10 +53,12 @@ internal Error() /// Initializes a new instance of . /// /// - internal Error(int? status, string message) + /// Keeps track of any properties unknown to the library. + internal Error(int? status, string message, IDictionary serializedAdditionalRawData) { Status = status; Message = message; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the status. diff --git a/test/TestServerProjects/xml-service/Generated/Models/JsonInput.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/JsonInput.Serialization.cs index a3cec119c38..de86d59d648 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/JsonInput.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/JsonInput.Serialization.cs @@ -5,22 +5,122 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xml_service.Models { - public partial class JsonInput : IUtf8JsonSerializable + public partial class JsonInput : IUtf8JsonSerializable, IJsonModel { - void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(JsonInput)} does not support '{format}' format."); + } + writer.WriteStartObject(); if (Optional.IsDefined(Id)) { writer.WritePropertyName("id"u8); writer.WriteNumberValue(Id.Value); } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } writer.WriteEndObject(); } + + JsonInput IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(JsonInput)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeJsonInput(document.RootElement, options); + } + + internal static JsonInput DeserializeJsonInput(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + Optional id = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); + foreach (var property in element.EnumerateObject()) + { + if (property.NameEquals("id"u8)) + { + if (property.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + id = property.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new JsonInput(Optional.ToNullable(id), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(JsonInput)} does not support '{options.Format}' format."); + } + } + + JsonInput IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeJsonInput(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(JsonInput)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/JsonInput.cs b/test/TestServerProjects/xml-service/Generated/Models/JsonInput.cs index aa2da928281..710c7b0468f 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/JsonInput.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/JsonInput.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xml_service.Models { /// The JsonInput. public partial class JsonInput { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public JsonInput() { @@ -17,9 +52,11 @@ public JsonInput() /// Initializes a new instance of . /// - internal JsonInput(int? id) + /// Keeps track of any properties unknown to the library. + internal JsonInput(int? id, IDictionary serializedAdditionalRawData) { Id = id; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the id. diff --git a/test/TestServerProjects/xml-service/Generated/Models/JsonOutput.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/JsonOutput.Serialization.cs index 1ed7c02780f..d5cfd4955ee 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/JsonOutput.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/JsonOutput.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xml_service.Models { - public partial class JsonOutput + public partial class JsonOutput : IUtf8JsonSerializable, IJsonModel { - internal static JsonOutput DeserializeJsonOutput(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(JsonOutput)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteNumberValue(Id.Value); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + JsonOutput IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(JsonOutput)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeJsonOutput(document.RootElement, options); + } + + internal static JsonOutput DeserializeJsonOutput(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional id = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id"u8)) @@ -30,8 +83,44 @@ internal static JsonOutput DeserializeJsonOutput(JsonElement element) id = property.Value.GetInt32(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new JsonOutput(Optional.ToNullable(id), serializedAdditionalRawData); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(JsonOutput)} does not support '{options.Format}' format."); } - return new JsonOutput(Optional.ToNullable(id)); } + + JsonOutput IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeJsonOutput(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(JsonOutput)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/JsonOutput.cs b/test/TestServerProjects/xml-service/Generated/Models/JsonOutput.cs index 89bb9a5db2a..b1e976925c5 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/JsonOutput.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/JsonOutput.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xml_service.Models { /// The JsonOutput. public partial class JsonOutput { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal JsonOutput() { @@ -17,9 +52,11 @@ internal JsonOutput() /// Initializes a new instance of . /// - internal JsonOutput(int? id) + /// Keeps track of any properties unknown to the library. + internal JsonOutput(int? id, IDictionary serializedAdditionalRawData) { Id = id; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the id. diff --git a/test/TestServerProjects/xml-service/Generated/Models/ListBlobsResponse.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/ListBlobsResponse.Serialization.cs index 808e05693bd..eb8abeef246 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ListBlobsResponse.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ListBlobsResponse.Serialization.cs @@ -5,14 +5,54 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; +using System.Xml; using System.Xml.Linq; +using Azure.Core; namespace xml_service.Models { - public partial class ListBlobsResponse + public partial class ListBlobsResponse : IXmlSerializable, IPersistableModel { - internal static ListBlobsResponse DeserializeListBlobsResponse(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "EnumerationResults"); + if (Optional.IsDefined(ServiceEndpoint)) + { + writer.WriteStartAttribute("ServiceEndpoint"); + writer.WriteValue(ServiceEndpoint); + writer.WriteEndAttribute(); + } + writer.WriteStartAttribute("ContainerName"); + writer.WriteValue(ContainerName); + writer.WriteEndAttribute(); + writer.WriteStartElement("Prefix"); + writer.WriteValue(Prefix); + writer.WriteEndElement(); + writer.WriteStartElement("Marker"); + writer.WriteValue(Marker); + writer.WriteEndElement(); + writer.WriteStartElement("MaxResults"); + writer.WriteValue(MaxResults); + writer.WriteEndElement(); + writer.WriteStartElement("Delimiter"); + writer.WriteValue(Delimiter); + writer.WriteEndElement(); + writer.WriteObjectValue(Blobs, "Blobs"); + writer.WriteStartElement("NextMarker"); + writer.WriteValue(NextMarker); + writer.WriteEndElement(); + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ListBlobsResponse DeserializeListBlobsResponse(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + string serviceEndpoint = default; string containerName = default; string prefix = default; @@ -53,7 +93,41 @@ internal static ListBlobsResponse DeserializeListBlobsResponse(XElement element) { nextMarker = (string)nextMarkerElement; } - return new ListBlobsResponse(serviceEndpoint, containerName, prefix, marker, maxResults, delimiter, blobs, nextMarker); + return new ListBlobsResponse(serviceEndpoint, containerName, prefix, marker, maxResults, delimiter, blobs, nextMarker, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ListBlobsResponse)} does not support '{options.Format}' format."); + } + } + + ListBlobsResponse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeListBlobsResponse(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ListBlobsResponse)} does not support '{options.Format}' format."); + } } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/ListBlobsResponse.cs b/test/TestServerProjects/xml-service/Generated/Models/ListBlobsResponse.cs index 95b1e137353..15c489ff6bb 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ListBlobsResponse.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ListBlobsResponse.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace xml_service.Models @@ -13,6 +14,38 @@ namespace xml_service.Models /// An enumeration of blobs. public partial class ListBlobsResponse { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// @@ -49,7 +82,8 @@ internal ListBlobsResponse(string containerName, string prefix, string marker, i /// /// /// - internal ListBlobsResponse(string serviceEndpoint, string containerName, string prefix, string marker, int maxResults, string delimiter, Blobs blobs, string nextMarker) + /// Keeps track of any properties unknown to the library. + internal ListBlobsResponse(string serviceEndpoint, string containerName, string prefix, string marker, int maxResults, string delimiter, Blobs blobs, string nextMarker, IDictionary serializedAdditionalRawData) { ServiceEndpoint = serviceEndpoint; ContainerName = containerName; @@ -59,6 +93,12 @@ internal ListBlobsResponse(string serviceEndpoint, string containerName, string Delimiter = delimiter; Blobs = blobs; NextMarker = nextMarker; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ListBlobsResponse() + { } /// Gets the service endpoint. diff --git a/test/TestServerProjects/xml-service/Generated/Models/ListContainersResponse.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/ListContainersResponse.Serialization.cs index 61cf19c63ea..736b1ac2a6d 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ListContainersResponse.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ListContainersResponse.Serialization.cs @@ -5,15 +5,57 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; +using System.Xml; using System.Xml.Linq; +using Azure.Core; namespace xml_service.Models { - public partial class ListContainersResponse + public partial class ListContainersResponse : IXmlSerializable, IPersistableModel { - internal static ListContainersResponse DeserializeListContainersResponse(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "EnumerationResults"); + writer.WriteStartAttribute("ServiceEndpoint"); + writer.WriteValue(ServiceEndpoint); + writer.WriteEndAttribute(); + writer.WriteStartElement("Prefix"); + writer.WriteValue(Prefix); + writer.WriteEndElement(); + if (Optional.IsDefined(Marker)) + { + writer.WriteStartElement("Marker"); + writer.WriteValue(Marker); + writer.WriteEndElement(); + } + writer.WriteStartElement("MaxResults"); + writer.WriteValue(MaxResults); + writer.WriteEndElement(); + writer.WriteStartElement("NextMarker"); + writer.WriteValue(NextMarker); + writer.WriteEndElement(); + if (Optional.IsCollectionDefined(Containers)) + { + writer.WriteStartElement("Containers"); + foreach (var item in Containers) + { + writer.WriteObjectValue(item, "Container"); + } + writer.WriteEndElement(); + } + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ListContainersResponse DeserializeListContainersResponse(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + string serviceEndpoint = default; string prefix = default; string marker = default; @@ -49,7 +91,41 @@ internal static ListContainersResponse DeserializeListContainersResponse(XElemen } containers = array; } - return new ListContainersResponse(serviceEndpoint, prefix, marker, maxResults, containers, nextMarker); + return new ListContainersResponse(serviceEndpoint, prefix, marker, maxResults, containers, nextMarker, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ListContainersResponse)} does not support '{options.Format}' format."); + } + } + + ListContainersResponse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeListContainersResponse(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ListContainersResponse)} does not support '{options.Format}' format."); + } } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/ListContainersResponse.cs b/test/TestServerProjects/xml-service/Generated/Models/ListContainersResponse.cs index 2ebd84d6f6a..3076e273eff 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ListContainersResponse.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ListContainersResponse.cs @@ -14,6 +14,38 @@ namespace xml_service.Models /// An enumeration of containers. public partial class ListContainersResponse { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// /// @@ -40,7 +72,8 @@ internal ListContainersResponse(string serviceEndpoint, string prefix, int maxRe /// /// /// - internal ListContainersResponse(string serviceEndpoint, string prefix, string marker, int maxResults, IReadOnlyList containers, string nextMarker) + /// Keeps track of any properties unknown to the library. + internal ListContainersResponse(string serviceEndpoint, string prefix, string marker, int maxResults, IReadOnlyList containers, string nextMarker, IDictionary serializedAdditionalRawData) { ServiceEndpoint = serviceEndpoint; Prefix = prefix; @@ -48,6 +81,12 @@ internal ListContainersResponse(string serviceEndpoint, string prefix, string ma MaxResults = maxResults; Containers = containers; NextMarker = nextMarker; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal ListContainersResponse() + { } /// Gets the service endpoint. diff --git a/test/TestServerProjects/xml-service/Generated/Models/Logging.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/Logging.Serialization.cs index e62f32516ce..275911a12aa 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Logging.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Logging.Serialization.cs @@ -5,15 +5,18 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class Logging : IXmlSerializable + public partial class Logging : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "Logging"); writer.WriteStartElement("Version"); @@ -32,8 +35,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static Logging DeserializeLogging(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static Logging DeserializeLogging(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string version = default; bool delete = default; bool read = default; @@ -59,7 +66,41 @@ internal static Logging DeserializeLogging(XElement element) { retentionPolicy = RetentionPolicy.DeserializeRetentionPolicy(retentionPolicyElement); } - return new Logging(version, delete, read, write, retentionPolicy); + return new Logging(version, delete, read, write, retentionPolicy, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(Logging)} does not support '{options.Format}' format."); + } } + + Logging IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeLogging(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(Logging)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/Logging.cs b/test/TestServerProjects/xml-service/Generated/Models/Logging.cs index 9b9ffa19a65..2cd10d3e4d4 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Logging.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Logging.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace xml_service.Models @@ -13,6 +14,38 @@ namespace xml_service.Models /// Azure Analytics Logging settings. public partial class Logging { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// The version of Storage Analytics to configure. /// Indicates whether all delete requests should be logged. @@ -32,6 +65,28 @@ public Logging(string version, bool delete, bool read, bool write, RetentionPoli RetentionPolicy = retentionPolicy; } + /// Initializes a new instance of . + /// The version of Storage Analytics to configure. + /// Indicates whether all delete requests should be logged. + /// Indicates whether all read requests should be logged. + /// Indicates whether all write requests should be logged. + /// the retention policy. + /// Keeps track of any properties unknown to the library. + internal Logging(string version, bool delete, bool read, bool write, RetentionPolicy retentionPolicy, IDictionary serializedAdditionalRawData) + { + Version = version; + Delete = delete; + Read = read; + Write = write; + RetentionPolicy = retentionPolicy; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Logging() + { + } + /// The version of Storage Analytics to configure. public string Version { get; set; } /// Indicates whether all delete requests should be logged. diff --git a/test/TestServerProjects/xml-service/Generated/Models/Metrics.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/Metrics.Serialization.cs index 6d6c31cfefe..5f72b366859 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Metrics.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Metrics.Serialization.cs @@ -5,15 +5,18 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class Metrics : IXmlSerializable + public partial class Metrics : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "Metrics"); if (Optional.IsDefined(Version)) @@ -38,8 +41,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static Metrics DeserializeMetrics(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static Metrics DeserializeMetrics(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string version = default; bool enabled = default; bool? includeAPIs = default; @@ -60,7 +67,41 @@ internal static Metrics DeserializeMetrics(XElement element) { retentionPolicy = RetentionPolicy.DeserializeRetentionPolicy(retentionPolicyElement); } - return new Metrics(version, enabled, includeAPIs, retentionPolicy); + return new Metrics(version, enabled, includeAPIs, retentionPolicy, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(Metrics)} does not support '{options.Format}' format."); + } } + + Metrics IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeMetrics(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(Metrics)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/Metrics.cs b/test/TestServerProjects/xml-service/Generated/Models/Metrics.cs index 38d6129766c..0389680857b 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Metrics.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Metrics.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xml_service.Models { /// The Metrics. public partial class Metrics { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Indicates whether metrics are enabled for the Blob service. public Metrics(bool enabled) @@ -22,12 +57,19 @@ public Metrics(bool enabled) /// Indicates whether metrics are enabled for the Blob service. /// Indicates whether metrics should generate summary statistics for called API operations. /// the retention policy. - internal Metrics(string version, bool enabled, bool? includeAPIs, RetentionPolicy retentionPolicy) + /// Keeps track of any properties unknown to the library. + internal Metrics(string version, bool enabled, bool? includeAPIs, RetentionPolicy retentionPolicy, IDictionary serializedAdditionalRawData) { Version = version; Enabled = enabled; IncludeAPIs = includeAPIs; RetentionPolicy = retentionPolicy; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal Metrics() + { } /// The version of Storage Analytics to configure. diff --git a/test/TestServerProjects/xml-service/Generated/Models/ModelWithByteProperty.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/ModelWithByteProperty.Serialization.cs index 9f3747d010c..cfbedfe6aaf 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ModelWithByteProperty.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ModelWithByteProperty.Serialization.cs @@ -6,15 +6,17 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class ModelWithByteProperty : IXmlSerializable + public partial class ModelWithByteProperty : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "ModelWithByteProperty"); if (Optional.IsDefined(Bytes)) @@ -26,14 +28,52 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static ModelWithByteProperty DeserializeModelWithByteProperty(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ModelWithByteProperty DeserializeModelWithByteProperty(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + byte[] bytes = default; if (element.Element("Bytes") is XElement bytesElement) { bytes = bytesElement.GetBytesFromBase64Value("D"); } - return new ModelWithByteProperty(bytes); + return new ModelWithByteProperty(bytes, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ModelWithByteProperty)} does not support '{options.Format}' format."); + } } + + ModelWithByteProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeModelWithByteProperty(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ModelWithByteProperty)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/ModelWithByteProperty.cs b/test/TestServerProjects/xml-service/Generated/Models/ModelWithByteProperty.cs index be790694796..fb3b6c7ff78 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ModelWithByteProperty.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ModelWithByteProperty.cs @@ -6,12 +6,45 @@ #nullable disable using System; +using System.Collections.Generic; namespace xml_service.Models { /// The ModelWithByteProperty. public partial class ModelWithByteProperty { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ModelWithByteProperty() { @@ -19,9 +52,11 @@ public ModelWithByteProperty() /// Initializes a new instance of . /// - internal ModelWithByteProperty(byte[] bytes) + /// Keeps track of any properties unknown to the library. + internal ModelWithByteProperty(byte[] bytes, IDictionary serializedAdditionalRawData) { Bytes = bytes; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the bytes. diff --git a/test/TestServerProjects/xml-service/Generated/Models/ModelWithUrlProperty.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/ModelWithUrlProperty.Serialization.cs index 5fc6ea9ced4..300e9d9e672 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ModelWithUrlProperty.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ModelWithUrlProperty.Serialization.cs @@ -6,15 +6,17 @@ #nullable disable using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class ModelWithUrlProperty : IXmlSerializable + public partial class ModelWithUrlProperty : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "ModelWithUrlProperty"); if (Optional.IsDefined(Url)) @@ -26,14 +28,52 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static ModelWithUrlProperty DeserializeModelWithUrlProperty(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ModelWithUrlProperty DeserializeModelWithUrlProperty(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + Uri url = default; if (element.Element("Url") is XElement urlElement) { url = new Uri((string)urlElement); } - return new ModelWithUrlProperty(url); + return new ModelWithUrlProperty(url, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ModelWithUrlProperty)} does not support '{options.Format}' format."); + } } + + ModelWithUrlProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeModelWithUrlProperty(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ModelWithUrlProperty)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/ModelWithUrlProperty.cs b/test/TestServerProjects/xml-service/Generated/Models/ModelWithUrlProperty.cs index 69df33611a3..74add00605e 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ModelWithUrlProperty.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ModelWithUrlProperty.cs @@ -6,12 +6,45 @@ #nullable disable using System; +using System.Collections.Generic; namespace xml_service.Models { /// The ModelWithUrlProperty. public partial class ModelWithUrlProperty { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public ModelWithUrlProperty() { @@ -19,9 +52,11 @@ public ModelWithUrlProperty() /// Initializes a new instance of . /// - internal ModelWithUrlProperty(Uri url) + /// Keeps track of any properties unknown to the library. + internal ModelWithUrlProperty(Uri url, IDictionary serializedAdditionalRawData) { Url = url; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the url. diff --git a/test/TestServerProjects/xml-service/Generated/Models/ObjectWithXMsTextProperty.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/ObjectWithXMsTextProperty.Serialization.cs index 45d6734c89e..95dd44ee49e 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ObjectWithXMsTextProperty.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ObjectWithXMsTextProperty.Serialization.cs @@ -5,14 +5,36 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; +using System.Xml; using System.Xml.Linq; +using Azure.Core; namespace xml_service.Models { - public partial class ObjectWithXMsTextProperty + public partial class ObjectWithXMsTextProperty : IXmlSerializable, IPersistableModel { - internal static ObjectWithXMsTextProperty DeserializeObjectWithXMsTextProperty(XElement element) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { + writer.WriteStartElement(nameHint ?? "Data"); + if (Optional.IsDefined(Language)) + { + writer.WriteStartAttribute("language"); + writer.WriteValue(Language); + writer.WriteEndAttribute(); + } + writer.WriteValue(Content); + writer.WriteEndElement(); + } + + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static ObjectWithXMsTextProperty DeserializeObjectWithXMsTextProperty(XElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + string language = default; string content = default; if (element.Attribute("language") is XAttribute languageAttribute) @@ -20,7 +42,41 @@ internal static ObjectWithXMsTextProperty DeserializeObjectWithXMsTextProperty(X language = (string)languageAttribute; } content = (string)element; - return new ObjectWithXMsTextProperty(language, content); + return new ObjectWithXMsTextProperty(language, content, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(ObjectWithXMsTextProperty)} does not support '{options.Format}' format."); + } + } + + ObjectWithXMsTextProperty IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeObjectWithXMsTextProperty(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(ObjectWithXMsTextProperty)} does not support '{options.Format}' format."); + } } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/ObjectWithXMsTextProperty.cs b/test/TestServerProjects/xml-service/Generated/Models/ObjectWithXMsTextProperty.cs index 83b9ef88895..acc1b941d2b 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/ObjectWithXMsTextProperty.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/ObjectWithXMsTextProperty.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xml_service.Models { /// Contans property. public partial class ObjectWithXMsTextProperty { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal ObjectWithXMsTextProperty() { @@ -18,10 +53,12 @@ internal ObjectWithXMsTextProperty() /// Initializes a new instance of . /// Returned value should be 'english'. /// Returned value should be 'I am text'. - internal ObjectWithXMsTextProperty(string language, string content) + /// Keeps track of any properties unknown to the library. + internal ObjectWithXMsTextProperty(string language, string content, IDictionary serializedAdditionalRawData) { Language = language; Content = content; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Returned value should be 'english'. diff --git a/test/TestServerProjects/xml-service/Generated/Models/RetentionPolicy.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/RetentionPolicy.Serialization.cs index 47c8fcde3d9..20a2df8d531 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/RetentionPolicy.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/RetentionPolicy.Serialization.cs @@ -5,15 +5,18 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class RetentionPolicy : IXmlSerializable + public partial class RetentionPolicy : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "RetentionPolicy"); writer.WriteStartElement("Enabled"); @@ -28,8 +31,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static RetentionPolicy DeserializeRetentionPolicy(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static RetentionPolicy DeserializeRetentionPolicy(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + bool enabled = default; int? days = default; if (element.Element("Enabled") is XElement enabledElement) @@ -40,7 +47,41 @@ internal static RetentionPolicy DeserializeRetentionPolicy(XElement element) { days = (int?)daysElement; } - return new RetentionPolicy(enabled, days); + return new RetentionPolicy(enabled, days, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(RetentionPolicy)} does not support '{options.Format}' format."); + } } + + RetentionPolicy IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeRetentionPolicy(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(RetentionPolicy)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/RetentionPolicy.cs b/test/TestServerProjects/xml-service/Generated/Models/RetentionPolicy.cs index 5f28f463c8b..a8c63da6314 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/RetentionPolicy.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/RetentionPolicy.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xml_service.Models { /// the retention policy. public partial class RetentionPolicy { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// Indicates whether a retention policy is enabled for the storage service. public RetentionPolicy(bool enabled) @@ -20,10 +55,17 @@ public RetentionPolicy(bool enabled) /// Initializes a new instance of . /// Indicates whether a retention policy is enabled for the storage service. /// Indicates the number of days that metrics or logging or soft-deleted data should be retained. All data older than this value will be deleted. - internal RetentionPolicy(bool enabled, int? days) + /// Keeps track of any properties unknown to the library. + internal RetentionPolicy(bool enabled, int? days, IDictionary serializedAdditionalRawData) { Enabled = enabled; Days = days; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal RetentionPolicy() + { } /// Indicates whether a retention policy is enabled for the storage service. diff --git a/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndMeta.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndMeta.Serialization.cs index be139543087..ebf29f86c34 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndMeta.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndMeta.Serialization.cs @@ -5,15 +5,18 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class RootWithRefAndMeta : IXmlSerializable + public partial class RootWithRefAndMeta : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "RootWithRefAndMeta"); if (Optional.IsDefined(RefToModel)) @@ -29,8 +32,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static RootWithRefAndMeta DeserializeRootWithRefAndMeta(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static RootWithRefAndMeta DeserializeRootWithRefAndMeta(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + ComplexTypeWithMeta refToModel = default; string something = default; if (element.Element("XMLComplexTypeWithMeta") is XElement xmlComplexTypeWithMetaElement) @@ -41,7 +48,41 @@ internal static RootWithRefAndMeta DeserializeRootWithRefAndMeta(XElement elemen { something = (string)somethingElement; } - return new RootWithRefAndMeta(refToModel, something); + return new RootWithRefAndMeta(refToModel, something, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(RootWithRefAndMeta)} does not support '{options.Format}' format."); + } } + + RootWithRefAndMeta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeRootWithRefAndMeta(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(RootWithRefAndMeta)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndMeta.cs b/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndMeta.cs index bdc148a4ad1..086a51454e8 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndMeta.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndMeta.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xml_service.Models { /// I am root, and I ref a model WITH meta. public partial class RootWithRefAndMeta { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public RootWithRefAndMeta() { @@ -18,10 +53,12 @@ public RootWithRefAndMeta() /// Initializes a new instance of . /// XML will use XMLComplexTypeWithMeta. /// Something else (just to avoid flattening). - internal RootWithRefAndMeta(ComplexTypeWithMeta refToModel, string something) + /// Keeps track of any properties unknown to the library. + internal RootWithRefAndMeta(ComplexTypeWithMeta refToModel, string something, IDictionary serializedAdditionalRawData) { RefToModel = refToModel; Something = something; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// XML will use XMLComplexTypeWithMeta. diff --git a/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndNoMeta.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndNoMeta.Serialization.cs index 55d8394d871..2c82d67c50c 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndNoMeta.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndNoMeta.Serialization.cs @@ -5,15 +5,18 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class RootWithRefAndNoMeta : IXmlSerializable + public partial class RootWithRefAndNoMeta : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "RootWithRefAndNoMeta"); if (Optional.IsDefined(RefToModel)) @@ -29,8 +32,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static RootWithRefAndNoMeta DeserializeRootWithRefAndNoMeta(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static RootWithRefAndNoMeta DeserializeRootWithRefAndNoMeta(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + ComplexTypeNoMeta refToModel = default; string something = default; if (element.Element("RefToModel") is XElement refToModelElement) @@ -41,7 +48,41 @@ internal static RootWithRefAndNoMeta DeserializeRootWithRefAndNoMeta(XElement el { something = (string)somethingElement; } - return new RootWithRefAndNoMeta(refToModel, something); + return new RootWithRefAndNoMeta(refToModel, something, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(RootWithRefAndNoMeta)} does not support '{options.Format}' format."); + } } + + RootWithRefAndNoMeta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeRootWithRefAndNoMeta(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(RootWithRefAndNoMeta)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndNoMeta.cs b/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndNoMeta.cs index 0d452946446..05416505be1 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndNoMeta.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/RootWithRefAndNoMeta.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xml_service.Models { /// I am root, and I ref a model with no meta. public partial class RootWithRefAndNoMeta { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public RootWithRefAndNoMeta() { @@ -18,10 +53,12 @@ public RootWithRefAndNoMeta() /// Initializes a new instance of . /// XML will use RefToModel. /// Something else (just to avoid flattening). - internal RootWithRefAndNoMeta(ComplexTypeNoMeta refToModel, string something) + /// Keeps track of any properties unknown to the library. + internal RootWithRefAndNoMeta(ComplexTypeNoMeta refToModel, string something, IDictionary serializedAdditionalRawData) { RefToModel = refToModel; Something = something; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// XML will use RefToModel. diff --git a/test/TestServerProjects/xml-service/Generated/Models/SignedIdentifier.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/SignedIdentifier.Serialization.cs index 44d35483fdb..c87ae818107 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/SignedIdentifier.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/SignedIdentifier.Serialization.cs @@ -5,15 +5,18 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class SignedIdentifier : IXmlSerializable + public partial class SignedIdentifier : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "SignedIdentifier"); writer.WriteStartElement("Id"); @@ -23,8 +26,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static SignedIdentifier DeserializeSignedIdentifier(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static SignedIdentifier DeserializeSignedIdentifier(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string id = default; AccessPolicy accessPolicy = default; if (element.Element("Id") is XElement idElement) @@ -35,7 +42,41 @@ internal static SignedIdentifier DeserializeSignedIdentifier(XElement element) { accessPolicy = AccessPolicy.DeserializeAccessPolicy(accessPolicyElement); } - return new SignedIdentifier(id, accessPolicy); + return new SignedIdentifier(id, accessPolicy, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(SignedIdentifier)} does not support '{options.Format}' format."); + } } + + SignedIdentifier IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeSignedIdentifier(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(SignedIdentifier)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/SignedIdentifier.cs b/test/TestServerProjects/xml-service/Generated/Models/SignedIdentifier.cs index c05b88fd98a..44529a5cf5a 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/SignedIdentifier.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/SignedIdentifier.cs @@ -6,6 +6,7 @@ #nullable disable using System; +using System.Collections.Generic; using Azure.Core; namespace xml_service.Models @@ -13,6 +14,38 @@ namespace xml_service.Models /// signed identifier. public partial class SignedIdentifier { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . /// a unique id. /// The access policy. @@ -26,6 +59,22 @@ public SignedIdentifier(string id, AccessPolicy accessPolicy) AccessPolicy = accessPolicy; } + /// Initializes a new instance of . + /// a unique id. + /// The access policy. + /// Keeps track of any properties unknown to the library. + internal SignedIdentifier(string id, AccessPolicy accessPolicy, IDictionary serializedAdditionalRawData) + { + Id = id; + AccessPolicy = accessPolicy; + _serializedAdditionalRawData = serializedAdditionalRawData; + } + + /// Initializes a new instance of for deserialization. + internal SignedIdentifier() + { + } + /// a unique id. public string Id { get; set; } /// The access policy. diff --git a/test/TestServerProjects/xml-service/Generated/Models/Slide.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/Slide.Serialization.cs index f6a9f40b5f5..5b2a4bfdc59 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Slide.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Slide.Serialization.cs @@ -5,16 +5,19 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class Slide : IXmlSerializable + public partial class Slide : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "slide"); if (Optional.IsDefined(Type)) @@ -41,8 +44,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static Slide DeserializeSlide(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static Slide DeserializeSlide(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string type = default; string title = default; IList items = default; @@ -60,7 +67,41 @@ internal static Slide DeserializeSlide(XElement element) array.Add((string)e); } items = array; - return new Slide(type, title, items); + return new Slide(type, title, items, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(Slide)} does not support '{options.Format}' format."); + } } + + Slide IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeSlide(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(Slide)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/Slide.cs b/test/TestServerProjects/xml-service/Generated/Models/Slide.cs index 701b5f7a2ca..09ccb653efe 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Slide.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Slide.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace xml_service.Models /// A slide in a slideshow. public partial class Slide { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Slide() { @@ -23,11 +56,13 @@ public Slide() /// /// /// - internal Slide(string type, string title, IList items) + /// Keeps track of any properties unknown to the library. + internal Slide(string type, string title, IList items, IDictionary serializedAdditionalRawData) { Type = type; Title = title; Items = items; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the type. diff --git a/test/TestServerProjects/xml-service/Generated/Models/Slideshow.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/Slideshow.Serialization.cs index 996c5815797..c83b1018ba5 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Slideshow.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Slideshow.Serialization.cs @@ -5,16 +5,19 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class Slideshow : IXmlSerializable + public partial class Slideshow : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "slideshow"); if (Optional.IsDefined(Title)) @@ -45,8 +48,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static Slideshow DeserializeSlideshow(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static Slideshow DeserializeSlideshow(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + string title = default; string date = default; string author = default; @@ -69,7 +76,41 @@ internal static Slideshow DeserializeSlideshow(XElement element) array.Add(Slide.DeserializeSlide(e)); } slides = array; - return new Slideshow(title, date, author, slides); + return new Slideshow(title, date, author, slides, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(Slideshow)} does not support '{options.Format}' format."); + } } + + Slideshow IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeSlideshow(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(Slideshow)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/Slideshow.cs b/test/TestServerProjects/xml-service/Generated/Models/Slideshow.cs index 6bc6776fbd3..b79fa7becca 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/Slideshow.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/Slideshow.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace xml_service.Models /// Data about a slideshow. public partial class Slideshow { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public Slideshow() { @@ -24,12 +57,14 @@ public Slideshow() /// /// /// - internal Slideshow(string title, string date, string author, IList slides) + /// Keeps track of any properties unknown to the library. + internal Slideshow(string title, string date, string author, IList slides, IDictionary serializedAdditionalRawData) { Title = title; Date = date; Author = author; Slides = slides; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets or sets the title. diff --git a/test/TestServerProjects/xml-service/Generated/Models/StorageServiceProperties.Serialization.cs b/test/TestServerProjects/xml-service/Generated/Models/StorageServiceProperties.Serialization.cs index c1b623ae097..acc74352003 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/StorageServiceProperties.Serialization.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/StorageServiceProperties.Serialization.cs @@ -5,16 +5,19 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.IO; using System.Xml; using System.Xml.Linq; using Azure.Core; namespace xml_service.Models { - public partial class StorageServiceProperties : IXmlSerializable + public partial class StorageServiceProperties : IXmlSerializable, IPersistableModel { - void IXmlSerializable.Write(XmlWriter writer, string nameHint) + private void WriteInternal(XmlWriter writer, string nameHint, ModelReaderWriterOptions options) { writer.WriteStartElement(nameHint ?? "StorageServiceProperties"); if (Optional.IsDefined(Logging)) @@ -51,8 +54,12 @@ void IXmlSerializable.Write(XmlWriter writer, string nameHint) writer.WriteEndElement(); } - internal static StorageServiceProperties DeserializeStorageServiceProperties(XElement element) + void IXmlSerializable.Write(XmlWriter writer, string nameHint) => WriteInternal(writer, nameHint, new ModelReaderWriterOptions("W")); + + internal static StorageServiceProperties DeserializeStorageServiceProperties(XElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + Logging logging = default; Metrics hourMetrics = default; Metrics minuteMetrics = default; @@ -88,7 +95,41 @@ internal static StorageServiceProperties DeserializeStorageServiceProperties(XEl } cors = array; } - return new StorageServiceProperties(logging, hourMetrics, minuteMetrics, cors, defaultServiceVersion, deleteRetentionPolicy); + return new StorageServiceProperties(logging, hourMetrics, minuteMetrics, cors, defaultServiceVersion, deleteRetentionPolicy, serializedAdditionalRawData: null); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + { + using MemoryStream stream = new MemoryStream(); + using XmlWriter writer = XmlWriter.Create(stream); + WriteInternal(writer, null, options); + writer.Flush(); + return new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position)); + } + default: + throw new FormatException($"The model {nameof(StorageServiceProperties)} does not support '{options.Format}' format."); + } } + + StorageServiceProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "X": + return DeserializeStorageServiceProperties(XElement.Load(data.ToStream()), options); + default: + throw new FormatException($"The model {nameof(StorageServiceProperties)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "X"; } } diff --git a/test/TestServerProjects/xml-service/Generated/Models/StorageServiceProperties.cs b/test/TestServerProjects/xml-service/Generated/Models/StorageServiceProperties.cs index 47f8b8202e4..c3c7bb02ce0 100644 --- a/test/TestServerProjects/xml-service/Generated/Models/StorageServiceProperties.cs +++ b/test/TestServerProjects/xml-service/Generated/Models/StorageServiceProperties.cs @@ -5,6 +5,7 @@ #nullable disable +using System; using System.Collections.Generic; using Azure.Core; @@ -13,6 +14,38 @@ namespace xml_service.Models /// Storage Service Properties. public partial class StorageServiceProperties { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . public StorageServiceProperties() { @@ -26,7 +59,8 @@ public StorageServiceProperties() /// The set of CORS rules. /// The default version to use for requests to the Blob service if an incoming request's version is not specified. Possible values include version 2008-10-27 and all more recent versions. /// The Delete Retention Policy for the service. - internal StorageServiceProperties(Logging logging, Metrics hourMetrics, Metrics minuteMetrics, IList cors, string defaultServiceVersion, RetentionPolicy deleteRetentionPolicy) + /// Keeps track of any properties unknown to the library. + internal StorageServiceProperties(Logging logging, Metrics hourMetrics, Metrics minuteMetrics, IList cors, string defaultServiceVersion, RetentionPolicy deleteRetentionPolicy, IDictionary serializedAdditionalRawData) { Logging = logging; HourMetrics = hourMetrics; @@ -34,6 +68,7 @@ internal StorageServiceProperties(Logging logging, Metrics hourMetrics, Metrics Cors = cors; DefaultServiceVersion = defaultServiceVersion; DeleteRetentionPolicy = deleteRetentionPolicy; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Azure Analytics Logging settings. diff --git a/test/TestServerProjects/xml-service/Generated/XmlServiceModelFactory.cs b/test/TestServerProjects/xml-service/Generated/XmlServiceModelFactory.cs index 72c1915de9a..36d50b5a82f 100644 --- a/test/TestServerProjects/xml-service/Generated/XmlServiceModelFactory.cs +++ b/test/TestServerProjects/xml-service/Generated/XmlServiceModelFactory.cs @@ -26,7 +26,7 @@ public static ListContainersResponse ListContainersResponse(string serviceEndpoi { containers ??= new List(); - return new ListContainersResponse(serviceEndpoint, prefix, marker, maxResults, containers?.ToList(), nextMarker); + return new ListContainersResponse(serviceEndpoint, prefix, marker, maxResults, containers?.ToList(), nextMarker, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -38,7 +38,7 @@ public static Container Container(string name = null, ContainerProperties proper { metadata ??= new Dictionary(); - return new Container(name, properties, metadata); + return new Container(name, properties, metadata, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -51,7 +51,7 @@ public static Container Container(string name = null, ContainerProperties proper /// A new instance for mocking. public static ContainerProperties ContainerProperties(DateTimeOffset lastModified = default, string etag = null, LeaseStatusType? leaseStatus = null, LeaseStateType? leaseState = null, LeaseDurationType? leaseDuration = null, PublicAccessType? publicAccess = null) { - return new ContainerProperties(lastModified, etag, leaseStatus, leaseState, leaseDuration, publicAccess); + return new ContainerProperties(lastModified, etag, leaseStatus, leaseState, leaseDuration, publicAccess, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -66,7 +66,7 @@ public static ContainerProperties ContainerProperties(DateTimeOffset lastModifie /// A new instance for mocking. public static ListBlobsResponse ListBlobsResponse(string serviceEndpoint = null, string containerName = null, string prefix = null, string marker = null, int maxResults = default, string delimiter = null, Blobs blobs = null, string nextMarker = null) { - return new ListBlobsResponse(serviceEndpoint, containerName, prefix, marker, maxResults, delimiter, blobs, nextMarker); + return new ListBlobsResponse(serviceEndpoint, containerName, prefix, marker, maxResults, delimiter, blobs, nextMarker, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -78,21 +78,15 @@ public static Blobs Blobs(IEnumerable blobPrefix = null, IEnumerable blobPrefix ??= new List(); blob ??= new List(); - return new Blobs(blobPrefix?.ToList(), blob?.ToList()); + return new Blobs(blobPrefix?.ToList(), blob?.ToList(), serializedAdditionalRawData: null); } /// Initializes a new instance of . /// - /// is null. /// A new instance for mocking. public static BlobPrefix BlobPrefix(string name = null) { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - return new BlobPrefix(name); + return new BlobPrefix(name, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -106,7 +100,7 @@ public static Blob Blob(string name = null, bool deleted = default, string snaps { metadata ??= new Dictionary(); - return new Blob(name, deleted, snapshot, properties, metadata); + return new Blob(name, deleted, snapshot, properties, metadata, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -141,7 +135,7 @@ public static Blob Blob(string name = null, bool deleted = default, string snaps /// A new instance for mocking. public static BlobProperties BlobProperties(DateTimeOffset lastModified = default, string etag = null, long? contentLength = null, string contentType = null, string contentEncoding = null, string contentLanguage = null, string contentMD5 = null, string contentDisposition = null, string cacheControl = null, int? blobSequenceNumber = null, BlobType? blobType = null, LeaseStatusType? leaseStatus = null, LeaseStateType? leaseState = null, LeaseDurationType? leaseDuration = null, string copyId = null, CopyStatusType? copyStatus = null, string copySource = null, string copyProgress = null, DateTimeOffset? copyCompletionTime = null, string copyStatusDescription = null, bool? serverEncrypted = null, bool? incrementalCopy = null, string destinationSnapshot = null, DateTimeOffset? deletedTime = null, int? remainingRetentionDays = null, AccessTier? accessTier = null, bool? accessTierInferred = null, ArchiveStatus? archiveStatus = null) { - return new BlobProperties(lastModified, etag, contentLength, contentType, contentEncoding, contentLanguage, contentMD5, contentDisposition, cacheControl, blobSequenceNumber, blobType, leaseStatus, leaseState, leaseDuration, copyId, copyStatus, copySource, copyProgress, copyCompletionTime, copyStatusDescription, serverEncrypted, incrementalCopy, destinationSnapshot, deletedTime, remainingRetentionDays, accessTier, accessTierInferred, archiveStatus); + return new BlobProperties(lastModified, etag, contentLength, contentType, contentEncoding, contentLanguage, contentMD5, contentDisposition, cacheControl, blobSequenceNumber, blobType, leaseStatus, leaseState, leaseDuration, copyId, copyStatus, copySource, copyProgress, copyCompletionTime, copyStatusDescription, serverEncrypted, incrementalCopy, destinationSnapshot, deletedTime, remainingRetentionDays, accessTier, accessTierInferred, archiveStatus, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -149,7 +143,7 @@ public static BlobProperties BlobProperties(DateTimeOffset lastModified = defaul /// A new instance for mocking. public static JsonOutput JsonOutput(int? id = null) { - return new JsonOutput(id); + return new JsonOutput(id, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -158,7 +152,7 @@ public static JsonOutput JsonOutput(int? id = null) /// A new instance for mocking. public static ObjectWithXMsTextProperty ObjectWithXMsTextProperty(string language = null, string content = null) { - return new ObjectWithXMsTextProperty(language, content); + return new ObjectWithXMsTextProperty(language, content, serializedAdditionalRawData: null); } } } diff --git a/test/TestServerProjects/xml-service/xml_service.csproj b/test/TestServerProjects/xml-service/xml_service.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/xml-service/xml_service.csproj +++ b/test/TestServerProjects/xml-service/xml_service.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjects/xms-error-responses/Generated/Configuration.json b/test/TestServerProjects/xms-error-responses/Generated/Configuration.json index 06d661188f2..2dd9d7dfd0c 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Configuration.json +++ b/test/TestServerProjects/xms-error-responses/Generated/Configuration.json @@ -8,5 +8,6 @@ ], "public-clients": true, "skip-csproj-packagereference": true, - "generation1-convenience-client": true + "generation1-convenience-client": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/Animal.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/Animal.Serialization.cs index c4f3cac274e..deec76929a2 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/Animal.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/Animal.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xms_error_responses.Models { - public partial class Animal + public partial class Animal : IUtf8JsonSerializable, IJsonModel { - internal static Animal DeserializeAnimal(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Animal)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(AniType)) + { + writer.WritePropertyName("aniType"u8); + writer.WriteStringValue(AniType); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Animal IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Animal)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAnimal(document.RootElement, options); + } + + internal static Animal DeserializeAnimal(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional aniType = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("aniType"u8)) @@ -26,8 +79,44 @@ internal static Animal DeserializeAnimal(JsonElement element) aniType = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new Animal(aniType.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Animal(aniType.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Animal)} does not support '{options.Format}' format."); + } + } + + Animal IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeAnimal(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Animal)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/Animal.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/Animal.cs index de058117ac5..61886d7fc15 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/Animal.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/Animal.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// The Animal. public partial class Animal { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal Animal() { @@ -17,9 +52,11 @@ internal Animal() /// Initializes a new instance of . /// - internal Animal(string aniType) + /// Keeps track of any properties unknown to the library. + internal Animal(string aniType, IDictionary serializedAdditionalRawData) { AniType = aniType; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the ani type. diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/AnimalNotFound.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/AnimalNotFound.Serialization.cs index 48c8fc4a3bb..a90aba5f33d 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/AnimalNotFound.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/AnimalNotFound.Serialization.cs @@ -5,15 +5,78 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xms_error_responses.Models { - internal partial class AnimalNotFound + internal partial class AnimalNotFound : IUtf8JsonSerializable, IJsonModel { - internal static AnimalNotFound DeserializeAnimalNotFound(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AnimalNotFound)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + if (Optional.IsDefined(Reason)) + { + writer.WritePropertyName("reason"u8); + writer.WriteStringValue(Reason); + } + writer.WritePropertyName("whatNotFound"u8); + writer.WriteStringValue(WhatNotFound); + if (Optional.IsDefined(SomeBaseProp)) + { + writer.WritePropertyName("someBaseProp"u8); + writer.WriteStringValue(SomeBaseProp); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + AnimalNotFound IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AnimalNotFound)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAnimalNotFound(document.RootElement, options); + } + + internal static AnimalNotFound DeserializeAnimalNotFound(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -22,6 +85,8 @@ internal static AnimalNotFound DeserializeAnimalNotFound(JsonElement element) Optional reason = default; string whatNotFound = default; Optional someBaseProp = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("name"u8)) @@ -44,8 +109,44 @@ internal static AnimalNotFound DeserializeAnimalNotFound(JsonElement element) someBaseProp = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new AnimalNotFound(someBaseProp.Value, reason.Value, whatNotFound, name.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new AnimalNotFound(someBaseProp.Value, serializedAdditionalRawData, reason.Value, whatNotFound, name.Value); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(AnimalNotFound)} does not support '{options.Format}' format."); + } + } + + AnimalNotFound IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeAnimalNotFound(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AnimalNotFound)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/AnimalNotFound.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/AnimalNotFound.cs index e1f70685bdf..62afb8ff912 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/AnimalNotFound.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/AnimalNotFound.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// The AnimalNotFound. @@ -18,10 +21,11 @@ internal AnimalNotFound() /// Initializes a new instance of . /// + /// Keeps track of any properties unknown to the library. /// /// /// - internal AnimalNotFound(string someBaseProp, string reason, string whatNotFound, string name) : base(someBaseProp, reason, whatNotFound) + internal AnimalNotFound(string someBaseProp, IDictionary serializedAdditionalRawData, string reason, string whatNotFound, string name) : base(someBaseProp, serializedAdditionalRawData, reason, whatNotFound) { Name = name; WhatNotFound = whatNotFound ?? "AnimalNotFound"; diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/BaseError.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/BaseError.Serialization.cs index 0ece15b61aa..94c21c7fabe 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/BaseError.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/BaseError.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xms_error_responses.Models { - internal partial class BaseError + internal partial class BaseError : IUtf8JsonSerializable, IJsonModel { - internal static BaseError DeserializeBaseError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseError)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(SomeBaseProp)) + { + writer.WritePropertyName("someBaseProp"u8); + writer.WriteStringValue(SomeBaseProp); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + BaseError IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(BaseError)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeBaseError(document.RootElement, options); + } + + internal static BaseError DeserializeBaseError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional someBaseProp = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("someBaseProp"u8)) @@ -26,8 +79,44 @@ internal static BaseError DeserializeBaseError(JsonElement element) someBaseProp = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new BaseError(someBaseProp.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new BaseError(someBaseProp.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(BaseError)} does not support '{options.Format}' format."); + } + } + + BaseError IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeBaseError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(BaseError)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/BaseError.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/BaseError.cs index afa48c80037..013ff1a800b 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/BaseError.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/BaseError.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// The BaseError. internal partial class BaseError { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal BaseError() { @@ -17,9 +52,11 @@ internal BaseError() /// Initializes a new instance of . /// - internal BaseError(string someBaseProp) + /// Keeps track of any properties unknown to the library. + internal BaseError(string someBaseProp, IDictionary serializedAdditionalRawData) { SomeBaseProp = someBaseProp; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// Gets the some base prop. diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/LinkNotFound.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/LinkNotFound.Serialization.cs index 881ba3dda4b..0241029dbb4 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/LinkNotFound.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/LinkNotFound.Serialization.cs @@ -5,15 +5,78 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xms_error_responses.Models { - internal partial class LinkNotFound + internal partial class LinkNotFound : IUtf8JsonSerializable, IJsonModel { - internal static LinkNotFound DeserializeLinkNotFound(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(LinkNotFound)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(WhatSubAddress)) + { + writer.WritePropertyName("whatSubAddress"u8); + writer.WriteStringValue(WhatSubAddress); + } + if (Optional.IsDefined(Reason)) + { + writer.WritePropertyName("reason"u8); + writer.WriteStringValue(Reason); + } + writer.WritePropertyName("whatNotFound"u8); + writer.WriteStringValue(WhatNotFound); + if (Optional.IsDefined(SomeBaseProp)) + { + writer.WritePropertyName("someBaseProp"u8); + writer.WriteStringValue(SomeBaseProp); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + LinkNotFound IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(LinkNotFound)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeLinkNotFound(document.RootElement, options); + } + + internal static LinkNotFound DeserializeLinkNotFound(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -22,6 +85,8 @@ internal static LinkNotFound DeserializeLinkNotFound(JsonElement element) Optional reason = default; string whatNotFound = default; Optional someBaseProp = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("whatSubAddress"u8)) @@ -44,8 +109,44 @@ internal static LinkNotFound DeserializeLinkNotFound(JsonElement element) someBaseProp = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new LinkNotFound(someBaseProp.Value, reason.Value, whatNotFound, whatSubAddress.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new LinkNotFound(someBaseProp.Value, serializedAdditionalRawData, reason.Value, whatNotFound, whatSubAddress.Value); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(LinkNotFound)} does not support '{options.Format}' format."); + } + } + + LinkNotFound IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeLinkNotFound(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(LinkNotFound)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/LinkNotFound.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/LinkNotFound.cs index 979283401e2..c1b0f5717f2 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/LinkNotFound.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/LinkNotFound.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// The LinkNotFound. @@ -18,10 +21,11 @@ internal LinkNotFound() /// Initializes a new instance of . /// + /// Keeps track of any properties unknown to the library. /// /// /// - internal LinkNotFound(string someBaseProp, string reason, string whatNotFound, string whatSubAddress) : base(someBaseProp, reason, whatNotFound) + internal LinkNotFound(string someBaseProp, IDictionary serializedAdditionalRawData, string reason, string whatNotFound, string whatSubAddress) : base(someBaseProp, serializedAdditionalRawData, reason, whatNotFound) { WhatSubAddress = whatSubAddress; WhatNotFound = whatNotFound ?? "InvalidResourceLink"; diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/NotFoundErrorBase.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/NotFoundErrorBase.Serialization.cs index 96339a8004e..1d1697dd762 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/NotFoundErrorBase.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/NotFoundErrorBase.Serialization.cs @@ -5,14 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; +using Azure.Core; namespace xms_error_responses.Models { - internal partial class NotFoundErrorBase + [PersistableModelProxy(typeof(UnknownNotFoundErrorBase))] + internal partial class NotFoundErrorBase : IUtf8JsonSerializable, IJsonModel { - internal static NotFoundErrorBase DeserializeNotFoundErrorBase(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NotFoundErrorBase)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Reason)) + { + writer.WritePropertyName("reason"u8); + writer.WriteStringValue(Reason); + } + writer.WritePropertyName("whatNotFound"u8); + writer.WriteStringValue(WhatNotFound); + if (Optional.IsDefined(SomeBaseProp)) + { + writer.WritePropertyName("someBaseProp"u8); + writer.WriteStringValue(SomeBaseProp); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + NotFoundErrorBase IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NotFoundErrorBase)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeNotFoundErrorBase(document.RootElement, options); + } + + internal static NotFoundErrorBase DeserializeNotFoundErrorBase(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -27,5 +86,36 @@ internal static NotFoundErrorBase DeserializeNotFoundErrorBase(JsonElement eleme } return UnknownNotFoundErrorBase.DeserializeUnknownNotFoundErrorBase(element); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(NotFoundErrorBase)} does not support '{options.Format}' format."); + } + } + + NotFoundErrorBase IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeNotFoundErrorBase(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(NotFoundErrorBase)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/NotFoundErrorBase.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/NotFoundErrorBase.cs index 3873a0fd245..f92bb397af4 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/NotFoundErrorBase.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/NotFoundErrorBase.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// @@ -21,9 +24,10 @@ protected NotFoundErrorBase() /// Initializes a new instance of . /// + /// Keeps track of any properties unknown to the library. /// /// - internal NotFoundErrorBase(string someBaseProp, string reason, string whatNotFound) : base(someBaseProp) + internal NotFoundErrorBase(string someBaseProp, IDictionary serializedAdditionalRawData, string reason, string whatNotFound) : base(someBaseProp, serializedAdditionalRawData) { Reason = reason; WhatNotFound = whatNotFound; diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/Pet.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/Pet.Serialization.cs index 5502adf2582..a36af73ff38 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/Pet.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/Pet.Serialization.cs @@ -5,21 +5,79 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xms_error_responses.Models { - public partial class Pet + public partial class Pet : IUtf8JsonSerializable, IJsonModel { - internal static Pet DeserializePet(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (options.Format != "W" && Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + if (Optional.IsDefined(AniType)) + { + writer.WritePropertyName("aniType"u8); + writer.WriteStringValue(AniType); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + Pet IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePet(document.RootElement, options); + } + + internal static Pet DeserializePet(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional name = default; Optional aniType = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("name"u8)) @@ -32,8 +90,44 @@ internal static Pet DeserializePet(JsonElement element) aniType = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new Pet(aniType.Value, serializedAdditionalRawData, name.Value); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(Pet)} does not support '{options.Format}' format."); } - return new Pet(aniType.Value, name.Value); } + + Pet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePet(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Pet)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/Pet.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/Pet.cs index fc18b14be23..a594ddff7ff 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/Pet.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/Pet.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// The Pet. @@ -17,8 +20,9 @@ internal Pet() /// Initializes a new instance of . /// + /// Keeps track of any properties unknown to the library. /// Gets the Pet by id. - internal Pet(string aniType, string name) : base(aniType) + internal Pet(string aniType, IDictionary serializedAdditionalRawData, string name) : base(aniType, serializedAdditionalRawData) { Name = name; } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/PetAction.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/PetAction.Serialization.cs index 067af8a0c23..ff8f342519c 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/PetAction.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/PetAction.Serialization.cs @@ -5,20 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xms_error_responses.Models { - public partial class PetAction + public partial class PetAction : IUtf8JsonSerializable, IJsonModel { - internal static PetAction DeserializePetAction(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAction)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(ActionResponse)) + { + writer.WritePropertyName("actionResponse"u8); + writer.WriteStringValue(ActionResponse); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + PetAction IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetAction)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePetAction(document.RootElement, options); + } + + internal static PetAction DeserializePetAction(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; } Optional actionResponse = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("actionResponse"u8)) @@ -26,8 +79,44 @@ internal static PetAction DeserializePetAction(JsonElement element) actionResponse = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new PetAction(actionResponse.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new PetAction(actionResponse.Value, serializedAdditionalRawData); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PetAction)} does not support '{options.Format}' format."); + } + } + + PetAction IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePetAction(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PetAction)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/PetAction.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/PetAction.cs index 2926294fce4..2316f788d28 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/PetAction.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/PetAction.cs @@ -5,11 +5,46 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// The PetAction. public partial class PetAction { + /// + /// Keeps track of any properties unknown to the library. + /// + /// To assign an object to the value of this property use . + /// + /// + /// To assign an already formatted json string to this property use . + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\"") + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }) + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}") + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + private protected IDictionary _serializedAdditionalRawData; + /// Initializes a new instance of . internal PetAction() { @@ -17,9 +52,11 @@ internal PetAction() /// Initializes a new instance of . /// action feedback. - internal PetAction(string actionResponse) + /// Keeps track of any properties unknown to the library. + internal PetAction(string actionResponse, IDictionary serializedAdditionalRawData) { ActionResponse = actionResponse; + _serializedAdditionalRawData = serializedAdditionalRawData; } /// action feedback. diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/PetActionError.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/PetActionError.Serialization.cs index a314d7cdff6..213050eb7ae 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/PetActionError.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/PetActionError.Serialization.cs @@ -5,14 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; using System.Text.Json; +using Azure.Core; namespace xms_error_responses.Models { - public partial class PetActionError + [PersistableModelProxy(typeof(UnknownPetActionError))] + public partial class PetActionError : IUtf8JsonSerializable, IJsonModel { - internal static PetActionError DeserializePetActionError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetActionError)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("errorType"u8); + writer.WriteStringValue(ErrorType); + if (Optional.IsDefined(ErrorMessage)) + { + writer.WritePropertyName("errorMessage"u8); + writer.WriteStringValue(ErrorMessage); + } + if (Optional.IsDefined(ActionResponse)) + { + writer.WritePropertyName("actionResponse"u8); + writer.WriteStringValue(ActionResponse); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + PetActionError IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetActionError)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePetActionError(document.RootElement, options); + } + + internal static PetActionError DeserializePetActionError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -27,5 +86,36 @@ internal static PetActionError DeserializePetActionError(JsonElement element) } return UnknownPetActionError.DeserializeUnknownPetActionError(element); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PetActionError)} does not support '{options.Format}' format."); + } + } + + PetActionError IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePetActionError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PetActionError)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/PetActionError.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/PetActionError.cs index 72828a62876..be09f610065 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/PetActionError.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/PetActionError.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// @@ -21,9 +24,10 @@ protected PetActionError() /// Initializes a new instance of . /// action feedback. + /// Keeps track of any properties unknown to the library. /// /// the error message. - internal PetActionError(string actionResponse, string errorType, string errorMessage) : base(actionResponse) + internal PetActionError(string actionResponse, IDictionary serializedAdditionalRawData, string errorType, string errorMessage) : base(actionResponse, serializedAdditionalRawData) { ErrorType = errorType; ErrorMessage = errorMessage; diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/PetHungryOrThirstyError.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/PetHungryOrThirstyError.Serialization.cs index 70d29357baf..04af34107fd 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/PetHungryOrThirstyError.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/PetHungryOrThirstyError.Serialization.cs @@ -5,15 +5,83 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xms_error_responses.Models { - public partial class PetHungryOrThirstyError + public partial class PetHungryOrThirstyError : IUtf8JsonSerializable, IJsonModel { - internal static PetHungryOrThirstyError DeserializePetHungryOrThirstyError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetHungryOrThirstyError)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(HungryOrThirsty)) + { + writer.WritePropertyName("hungryOrThirsty"u8); + writer.WriteStringValue(HungryOrThirsty); + } + if (Optional.IsDefined(Reason)) + { + writer.WritePropertyName("reason"u8); + writer.WriteStringValue(Reason); + } + writer.WritePropertyName("errorType"u8); + writer.WriteStringValue(ErrorType); + if (Optional.IsDefined(ErrorMessage)) + { + writer.WritePropertyName("errorMessage"u8); + writer.WriteStringValue(ErrorMessage); + } + if (Optional.IsDefined(ActionResponse)) + { + writer.WritePropertyName("actionResponse"u8); + writer.WriteStringValue(ActionResponse); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + PetHungryOrThirstyError IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetHungryOrThirstyError)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePetHungryOrThirstyError(document.RootElement, options); + } + + internal static PetHungryOrThirstyError DeserializePetHungryOrThirstyError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -23,6 +91,8 @@ internal static PetHungryOrThirstyError DeserializePetHungryOrThirstyError(JsonE string errorType = default; Optional errorMessage = default; Optional actionResponse = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("hungryOrThirsty"u8)) @@ -50,8 +120,44 @@ internal static PetHungryOrThirstyError DeserializePetHungryOrThirstyError(JsonE actionResponse = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new PetHungryOrThirstyError(actionResponse.Value, serializedAdditionalRawData, errorType, errorMessage.Value, reason.Value, hungryOrThirsty.Value); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PetHungryOrThirstyError)} does not support '{options.Format}' format."); + } + } + + PetHungryOrThirstyError IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePetHungryOrThirstyError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PetHungryOrThirstyError)} does not support '{options.Format}' format."); } - return new PetHungryOrThirstyError(actionResponse.Value, errorType, errorMessage.Value, reason.Value, hungryOrThirsty.Value); } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/PetHungryOrThirstyError.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/PetHungryOrThirstyError.cs index 38f5bea1455..a0f151118ac 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/PetHungryOrThirstyError.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/PetHungryOrThirstyError.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// The PetHungryOrThirstyError. @@ -18,11 +21,12 @@ internal PetHungryOrThirstyError() /// Initializes a new instance of . /// action feedback. + /// Keeps track of any properties unknown to the library. /// /// the error message. /// why is the pet sad. /// is the pet hungry or thirsty or both. - internal PetHungryOrThirstyError(string actionResponse, string errorType, string errorMessage, string reason, string hungryOrThirsty) : base(actionResponse, errorType, errorMessage, reason) + internal PetHungryOrThirstyError(string actionResponse, IDictionary serializedAdditionalRawData, string errorType, string errorMessage, string reason, string hungryOrThirsty) : base(actionResponse, serializedAdditionalRawData, errorType, errorMessage, reason) { HungryOrThirsty = hungryOrThirsty; ErrorType = errorType ?? "PetHungryOrThirstyError"; diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/PetSadError.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/PetSadError.Serialization.cs index b8503ebcf10..d062ab36796 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/PetSadError.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/PetSadError.Serialization.cs @@ -5,15 +5,78 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xms_error_responses.Models { - public partial class PetSadError + public partial class PetSadError : IUtf8JsonSerializable, IJsonModel { - internal static PetSadError DeserializePetSadError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetSadError)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Reason)) + { + writer.WritePropertyName("reason"u8); + writer.WriteStringValue(Reason); + } + writer.WritePropertyName("errorType"u8); + writer.WriteStringValue(ErrorType); + if (Optional.IsDefined(ErrorMessage)) + { + writer.WritePropertyName("errorMessage"u8); + writer.WriteStringValue(ErrorMessage); + } + if (Optional.IsDefined(ActionResponse)) + { + writer.WritePropertyName("actionResponse"u8); + writer.WriteStringValue(ActionResponse); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + PetSadError IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetSadError)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePetSadError(document.RootElement, options); + } + + internal static PetSadError DeserializePetSadError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -29,6 +92,8 @@ internal static PetSadError DeserializePetSadError(JsonElement element) string errorType = "PetSadError"; Optional errorMessage = default; Optional actionResponse = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("reason"u8)) @@ -51,8 +116,44 @@ internal static PetSadError DeserializePetSadError(JsonElement element) actionResponse = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } } - return new PetSadError(actionResponse.Value, errorType, errorMessage.Value, reason.Value); + serializedAdditionalRawData = additionalPropertiesDictionary; + return new PetSadError(actionResponse.Value, serializedAdditionalRawData, errorType, errorMessage.Value, reason.Value); } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PetSadError)} does not support '{options.Format}' format."); + } + } + + PetSadError IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializePetSadError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PetSadError)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/PetSadError.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/PetSadError.cs index 8b481beba52..3c0a472c03a 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/PetSadError.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/PetSadError.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// @@ -22,10 +25,11 @@ internal PetSadError() /// Initializes a new instance of . /// action feedback. + /// Keeps track of any properties unknown to the library. /// /// the error message. /// why is the pet sad. - internal PetSadError(string actionResponse, string errorType, string errorMessage, string reason) : base(actionResponse, errorType, errorMessage) + internal PetSadError(string actionResponse, IDictionary serializedAdditionalRawData, string errorType, string errorMessage, string reason) : base(actionResponse, serializedAdditionalRawData, errorType, errorMessage) { Reason = reason; ErrorType = errorType ?? "PetSadError"; diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownNotFoundErrorBase.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownNotFoundErrorBase.Serialization.cs index 8f72ecffed9..a99489b3dd1 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownNotFoundErrorBase.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownNotFoundErrorBase.Serialization.cs @@ -5,15 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xms_error_responses.Models { - internal partial class UnknownNotFoundErrorBase + internal partial class UnknownNotFoundErrorBase : IUtf8JsonSerializable, IJsonModel { - internal static UnknownNotFoundErrorBase DeserializeUnknownNotFoundErrorBase(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NotFoundErrorBase)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + if (Optional.IsDefined(Reason)) + { + writer.WritePropertyName("reason"u8); + writer.WriteStringValue(Reason); + } + writer.WritePropertyName("whatNotFound"u8); + writer.WriteStringValue(WhatNotFound); + if (Optional.IsDefined(SomeBaseProp)) + { + writer.WritePropertyName("someBaseProp"u8); + writer.WriteStringValue(SomeBaseProp); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + NotFoundErrorBase IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NotFoundErrorBase)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownNotFoundErrorBase(document.RootElement, options); + } + + internal static UnknownNotFoundErrorBase DeserializeUnknownNotFoundErrorBase(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -21,6 +79,8 @@ internal static UnknownNotFoundErrorBase DeserializeUnknownNotFoundErrorBase(Jso Optional reason = default; string whatNotFound = "Unknown"; Optional someBaseProp = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("reason"u8)) @@ -38,8 +98,44 @@ internal static UnknownNotFoundErrorBase DeserializeUnknownNotFoundErrorBase(Jso someBaseProp = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new UnknownNotFoundErrorBase(someBaseProp.Value, serializedAdditionalRawData, reason.Value, whatNotFound); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(NotFoundErrorBase)} does not support '{options.Format}' format."); } - return new UnknownNotFoundErrorBase(someBaseProp.Value, reason.Value, whatNotFound); } + + NotFoundErrorBase IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownNotFoundErrorBase(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(NotFoundErrorBase)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownNotFoundErrorBase.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownNotFoundErrorBase.cs index 6b45f9011ed..6d5bb628b83 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownNotFoundErrorBase.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownNotFoundErrorBase.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// The UnknownNotFoundErrorBase. @@ -12,9 +15,10 @@ internal partial class UnknownNotFoundErrorBase : NotFoundErrorBase { /// Initializes a new instance of . /// + /// Keeps track of any properties unknown to the library. /// /// - internal UnknownNotFoundErrorBase(string someBaseProp, string reason, string whatNotFound) : base(someBaseProp, reason, whatNotFound) + internal UnknownNotFoundErrorBase(string someBaseProp, IDictionary serializedAdditionalRawData, string reason, string whatNotFound) : base(someBaseProp, serializedAdditionalRawData, reason, whatNotFound) { WhatNotFound = whatNotFound ?? "Unknown"; } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownPetActionError.Serialization.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownPetActionError.Serialization.cs index 8ea7b43a881..bf63ed6fd1d 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownPetActionError.Serialization.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownPetActionError.Serialization.cs @@ -5,15 +5,73 @@ #nullable disable +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Text.Json; using Azure.Core; namespace xms_error_responses.Models { - internal partial class UnknownPetActionError + internal partial class UnknownPetActionError : IUtf8JsonSerializable, IJsonModel { - internal static UnknownPetActionError DeserializeUnknownPetActionError(JsonElement element) + void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, new ModelReaderWriterOptions("W")); + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetActionError)} does not support '{format}' format."); + } + + writer.WriteStartObject(); + writer.WritePropertyName("errorType"u8); + writer.WriteStringValue(ErrorType); + if (Optional.IsDefined(ErrorMessage)) + { + writer.WritePropertyName("errorMessage"u8); + writer.WriteStringValue(ErrorMessage); + } + if (Optional.IsDefined(ActionResponse)) + { + writer.WritePropertyName("actionResponse"u8); + writer.WriteStringValue(ActionResponse); + } + if (options.Format != "W" && _serializedAdditionalRawData != null) + { + foreach (var item in _serializedAdditionalRawData) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + writer.WriteEndObject(); + } + + PetActionError IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(PetActionError)} does not support '{format}' format."); + } + + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeUnknownPetActionError(document.RootElement, options); + } + + internal static UnknownPetActionError DeserializeUnknownPetActionError(JsonElement element, ModelReaderWriterOptions options = null) + { + options ??= new ModelReaderWriterOptions("W"); + if (element.ValueKind == JsonValueKind.Null) { return null; @@ -21,6 +79,8 @@ internal static UnknownPetActionError DeserializeUnknownPetActionError(JsonEleme string errorType = "Unknown"; Optional errorMessage = default; Optional actionResponse = default; + IDictionary serializedAdditionalRawData = default; + Dictionary additionalPropertiesDictionary = new Dictionary(); foreach (var property in element.EnumerateObject()) { if (property.NameEquals("errorType"u8)) @@ -38,8 +98,44 @@ internal static UnknownPetActionError DeserializeUnknownPetActionError(JsonEleme actionResponse = property.Value.GetString(); continue; } + if (options.Format != "W") + { + additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); + } + } + serializedAdditionalRawData = additionalPropertiesDictionary; + return new UnknownPetActionError(actionResponse.Value, serializedAdditionalRawData, errorType, errorMessage.Value); + } + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options); + default: + throw new FormatException($"The model {nameof(PetActionError)} does not support '{options.Format}' format."); } - return new UnknownPetActionError(actionResponse.Value, errorType, errorMessage.Value); } + + PetActionError IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + + switch (format) + { + case "J": + { + using JsonDocument document = JsonDocument.Parse(data); + return DeserializeUnknownPetActionError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(PetActionError)} does not support '{options.Format}' format."); + } + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; } } diff --git a/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownPetActionError.cs b/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownPetActionError.cs index fcc8cc0b585..118c8c1fd6c 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownPetActionError.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/Models/UnknownPetActionError.cs @@ -5,6 +5,9 @@ #nullable disable +using System; +using System.Collections.Generic; + namespace xms_error_responses.Models { /// The UnknownPetActionError. @@ -12,9 +15,10 @@ internal partial class UnknownPetActionError : PetActionError { /// Initializes a new instance of . /// action feedback. + /// Keeps track of any properties unknown to the library. /// /// the error message. - internal UnknownPetActionError(string actionResponse, string errorType, string errorMessage) : base(actionResponse, errorType, errorMessage) + internal UnknownPetActionError(string actionResponse, IDictionary serializedAdditionalRawData, string errorType, string errorMessage) : base(actionResponse, serializedAdditionalRawData, errorType, errorMessage) { ErrorType = errorType ?? "Unknown"; } diff --git a/test/TestServerProjects/xms-error-responses/Generated/XmsErrorResponsesModelFactory.cs b/test/TestServerProjects/xms-error-responses/Generated/XmsErrorResponsesModelFactory.cs index a043560aa70..c45ece19f7f 100644 --- a/test/TestServerProjects/xms-error-responses/Generated/XmsErrorResponsesModelFactory.cs +++ b/test/TestServerProjects/xms-error-responses/Generated/XmsErrorResponsesModelFactory.cs @@ -16,7 +16,7 @@ public static partial class XmsErrorResponsesModelFactory /// A new instance for mocking. public static Pet Pet(string aniType = null, string name = null) { - return new Pet(aniType, name); + return new Pet(aniType, serializedAdditionalRawData: null, name); } /// Initializes a new instance of . @@ -24,7 +24,7 @@ public static Pet Pet(string aniType = null, string name = null) /// A new instance for mocking. public static Animal Animal(string aniType = null) { - return new Animal(aniType); + return new Animal(aniType, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -32,7 +32,7 @@ public static Animal Animal(string aniType = null) /// A new instance for mocking. public static PetAction PetAction(string actionResponse = null) { - return new PetAction(actionResponse); + return new PetAction(actionResponse, serializedAdditionalRawData: null); } /// Initializes a new instance of . @@ -42,7 +42,7 @@ public static PetAction PetAction(string actionResponse = null) /// A new instance for mocking. public static PetActionError PetActionError(string actionResponse = null, string errorType = null, string errorMessage = null) { - return new UnknownPetActionError(actionResponse, errorType, errorMessage); + return new UnknownPetActionError(actionResponse, serializedAdditionalRawData: null, errorType, errorMessage); } /// Initializes a new instance of . @@ -52,7 +52,7 @@ public static PetActionError PetActionError(string actionResponse = null, string /// A new instance for mocking. public static PetSadError PetSadError(string actionResponse = null, string errorMessage = null, string reason = null) { - return new PetSadError(actionResponse, "PetSadError", errorMessage, reason); + return new PetSadError(actionResponse, serializedAdditionalRawData: null, "PetSadError", errorMessage, reason); } /// Initializes a new instance of . @@ -63,7 +63,7 @@ public static PetSadError PetSadError(string actionResponse = null, string error /// A new instance for mocking. public static PetHungryOrThirstyError PetHungryOrThirstyError(string actionResponse = null, string errorMessage = null, string reason = null, string hungryOrThirsty = null) { - return new PetHungryOrThirstyError(actionResponse, "PetHungryOrThirstyError", errorMessage, reason, hungryOrThirsty); + return new PetHungryOrThirstyError(actionResponse, serializedAdditionalRawData: null, "PetHungryOrThirstyError", errorMessage, reason, hungryOrThirsty); } } } diff --git a/test/TestServerProjects/xms-error-responses/xms_error_responses.csproj b/test/TestServerProjects/xms-error-responses/xms_error_responses.csproj index a74a40bfebd..eb270fc3b24 100644 --- a/test/TestServerProjects/xms-error-responses/xms_error_responses.csproj +++ b/test/TestServerProjects/xms-error-responses/xms_error_responses.csproj @@ -7,5 +7,6 @@ + diff --git a/test/TestServerProjectsLowLevel/body-array/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/body-array/src/Generated/Configuration.json index 48edada003c..e48b6bb8b39 100644 --- a/test/TestServerProjectsLowLevel/body-array/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/body-array/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/body-array/src/body_array_LowLevel.csproj b/test/TestServerProjectsLowLevel/body-array/src/body_array_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/body-array/src/body_array_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/body-array/src/body_array_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/body-complex/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/body-complex/src/Generated/Configuration.json index 4cf6815f109..f5cc530120a 100644 --- a/test/TestServerProjectsLowLevel/body-complex/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/body-complex/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/body-complex/src/body_complex_LowLevel.csproj b/test/TestServerProjectsLowLevel/body-complex/src/body_complex_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/body-complex/src/body_complex_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/body-complex/src/body_complex_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/body-file/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/body-file/src/Generated/Configuration.json index b0db1a0cb4b..f7ebd8770f7 100644 --- a/test/TestServerProjectsLowLevel/body-file/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/body-file/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/body-file/src/body_file_LowLevel.csproj b/test/TestServerProjectsLowLevel/body-file/src/body_file_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/body-file/src/body_file_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/body-file/src/body_file_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/body-string/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/body-string/src/Generated/Configuration.json index 310f1ad1865..0d432abff9d 100644 --- a/test/TestServerProjectsLowLevel/body-string/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/body-string/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/body-string/src/body_string_LowLevel.csproj b/test/TestServerProjectsLowLevel/body-string/src/body_string_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/body-string/src/body_string_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/body-string/src/body_string_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/custom-baseUrl-more-options/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/custom-baseUrl-more-options/src/Generated/Configuration.json index ad144f925e8..143ace3e1ff 100644 --- a/test/TestServerProjectsLowLevel/custom-baseUrl-more-options/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/custom-baseUrl-more-options/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/custom-baseUrl-more-options/src/custom_baseUrl_more_options_LowLevel.csproj b/test/TestServerProjectsLowLevel/custom-baseUrl-more-options/src/custom_baseUrl_more_options_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/custom-baseUrl-more-options/src/custom_baseUrl_more_options_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/custom-baseUrl-more-options/src/custom_baseUrl_more_options_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/custom-baseUrl-paging/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/custom-baseUrl-paging/src/Generated/Configuration.json index d4caac5e36d..32080125cfe 100644 --- a/test/TestServerProjectsLowLevel/custom-baseUrl-paging/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/custom-baseUrl-paging/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/custom-baseUrl-paging/src/custom_baseUrl_paging_LowLevel.csproj b/test/TestServerProjectsLowLevel/custom-baseUrl-paging/src/custom_baseUrl_paging_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/custom-baseUrl-paging/src/custom_baseUrl_paging_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/custom-baseUrl-paging/src/custom_baseUrl_paging_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/custom-baseUrl/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/custom-baseUrl/src/Generated/Configuration.json index ee6cfd42417..cf4e43a27e5 100644 --- a/test/TestServerProjectsLowLevel/custom-baseUrl/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/custom-baseUrl/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/custom-baseUrl/src/custom_baseUrl_LowLevel.csproj b/test/TestServerProjectsLowLevel/custom-baseUrl/src/custom_baseUrl_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/custom-baseUrl/src/custom_baseUrl_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/custom-baseUrl/src/custom_baseUrl_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/dpg-customization/src/Customization/DPGClient.cs b/test/TestServerProjectsLowLevel/dpg-customization/src/Customization/DPGClient.cs index 6473e1ef610..5f8ab2b2bca 100644 --- a/test/TestServerProjectsLowLevel/dpg-customization/src/Customization/DPGClient.cs +++ b/test/TestServerProjectsLowLevel/dpg-customization/src/Customization/DPGClient.cs @@ -146,7 +146,7 @@ public virtual AsyncPageable GetPageValuesAsync(string mode, Cancellati ( _ => CreateGetPagesRequest(mode, requestContext), (_, nextLink) => CreateGetPagesNextPageRequest(nextLink, mode, requestContext), - Product.DeserializeProduct, + e => Product.DeserializeProduct(e), ClientDiagnostics, Pipeline, "DPGClient.GetPagesValues", @@ -169,7 +169,7 @@ public virtual Pageable GetPageValues(string mode, CancellationToken ca ( _ => CreateGetPagesRequest(mode, requestContext), (_, nextLink) => CreateGetPagesNextPageRequest(nextLink, mode, requestContext), - Product.DeserializeProduct, + e => Product.DeserializeProduct(e), ClientDiagnostics, Pipeline, "DPGClient.GetPagesValues", diff --git a/test/TestServerProjectsLowLevel/dpg-customization/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/dpg-customization/src/Generated/Configuration.json index c9f5ad34098..77872bfb670 100644 --- a/test/TestServerProjectsLowLevel/dpg-customization/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/dpg-customization/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/dpg-customization/src/Models/Product.Serialization.cs b/test/TestServerProjectsLowLevel/dpg-customization/src/Models/Product.Serialization.cs index 1bc17f9c96d..c9025bf4774 100644 --- a/test/TestServerProjectsLowLevel/dpg-customization/src/Models/Product.Serialization.cs +++ b/test/TestServerProjectsLowLevel/dpg-customization/src/Models/Product.Serialization.cs @@ -3,6 +3,7 @@ #nullable disable +using System.ClientModel.Primitives; using System.Text.Json; using Azure; @@ -10,8 +11,10 @@ namespace dpg_customization_LowLevel.Models { public partial class Product { - internal static Product DeserializeProduct(JsonElement element) + internal static Product DeserializeProduct(JsonElement element, ModelReaderWriterOptions options = null) { + options ??= new ModelReaderWriterOptions("W"); + ProductReceived received = default; foreach (var property in element.EnumerateObject()) { diff --git a/test/TestServerProjectsLowLevel/dpg-customization/src/dpg_customization_LowLevel.csproj b/test/TestServerProjectsLowLevel/dpg-customization/src/dpg_customization_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/dpg-customization/src/dpg_customization_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/dpg-customization/src/dpg_customization_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/dpg-initial/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/dpg-initial/src/Generated/Configuration.json index 37a07baf568..69d760a72e9 100644 --- a/test/TestServerProjectsLowLevel/dpg-initial/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/dpg-initial/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/dpg-initial/src/dpg_initial_LowLevel.csproj b/test/TestServerProjectsLowLevel/dpg-initial/src/dpg_initial_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/dpg-initial/src/dpg_initial_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/dpg-initial/src/dpg_initial_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/dpg-update1/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/dpg-update1/src/Generated/Configuration.json index 9818f55374a..e0d8297b343 100644 --- a/test/TestServerProjectsLowLevel/dpg-update1/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/dpg-update1/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/dpg-update1/src/dpg_update1_LowLevel.csproj b/test/TestServerProjectsLowLevel/dpg-update1/src/dpg_update1_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/dpg-update1/src/dpg_update1_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/dpg-update1/src/dpg_update1_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/head/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/head/src/Generated/Configuration.json index 65570534470..c05a50238b3 100644 --- a/test/TestServerProjectsLowLevel/head/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/head/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/head/src/head_LowLevel.csproj b/test/TestServerProjectsLowLevel/head/src/head_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/head/src/head_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/head/src/head_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/header/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/header/src/Generated/Configuration.json index f32bb5281e8..3558df559d3 100644 --- a/test/TestServerProjectsLowLevel/header/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/header/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/header/src/header_LowLevel.csproj b/test/TestServerProjectsLowLevel/header/src/header_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/header/src/header_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/header/src/header_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/httpInfrastructure/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/httpInfrastructure/src/Generated/Configuration.json index 007828bf30e..453fb15c6c7 100644 --- a/test/TestServerProjectsLowLevel/httpInfrastructure/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/httpInfrastructure/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/httpInfrastructure/src/httpInfrastructure_LowLevel.csproj b/test/TestServerProjectsLowLevel/httpInfrastructure/src/httpInfrastructure_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/httpInfrastructure/src/httpInfrastructure_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/httpInfrastructure/src/httpInfrastructure_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/lro/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/lro/src/Generated/Configuration.json index 006944a7dde..e00214cd5d1 100644 --- a/test/TestServerProjectsLowLevel/lro/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/lro/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/lro/src/lro_LowLevel.csproj b/test/TestServerProjectsLowLevel/lro/src/lro_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/lro/src/lro_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/lro/src/lro_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/media_types/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/media_types/src/Generated/Configuration.json index 3f15d7397e0..5cc36534850 100644 --- a/test/TestServerProjectsLowLevel/media_types/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/media_types/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/media_types/src/media_types_LowLevel.csproj b/test/TestServerProjectsLowLevel/media_types/src/media_types_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/media_types/src/media_types_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/media_types/src/media_types_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/paging/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/paging/src/Generated/Configuration.json index da9e53e944f..60f72025aa4 100644 --- a/test/TestServerProjectsLowLevel/paging/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/paging/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/paging/src/paging_LowLevel.csproj b/test/TestServerProjectsLowLevel/paging/src/paging_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/paging/src/paging_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/paging/src/paging_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/security-aad/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/security-aad/src/Generated/Configuration.json index f95723f4a64..a3372a8f69d 100644 --- a/test/TestServerProjectsLowLevel/security-aad/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/security-aad/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/security-aad/src/security_aad_LowLevel.csproj b/test/TestServerProjectsLowLevel/security-aad/src/security_aad_LowLevel.csproj index 9114ac608e0..569ad399cd5 100644 --- a/test/TestServerProjectsLowLevel/security-aad/src/security_aad_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/security-aad/src/security_aad_LowLevel.csproj @@ -9,5 +9,6 @@ + diff --git a/test/TestServerProjectsLowLevel/security-key/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/security-key/src/Generated/Configuration.json index 7e4c9cf269f..cb4b1a5c0d4 100644 --- a/test/TestServerProjectsLowLevel/security-key/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/security-key/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/security-key/src/security_key_LowLevel.csproj b/test/TestServerProjectsLowLevel/security-key/src/security_key_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/security-key/src/security_key_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/security-key/src/security_key_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/url-multi-collectionFormat/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/url-multi-collectionFormat/src/Generated/Configuration.json index 775a5176944..e515381dd70 100644 --- a/test/TestServerProjectsLowLevel/url-multi-collectionFormat/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/url-multi-collectionFormat/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/url-multi-collectionFormat/src/url_multi_collectionFormat_LowLevel.csproj b/test/TestServerProjectsLowLevel/url-multi-collectionFormat/src/url_multi_collectionFormat_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/url-multi-collectionFormat/src/url_multi_collectionFormat_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/url-multi-collectionFormat/src/url_multi_collectionFormat_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/TestServerProjectsLowLevel/url/src/Generated/Configuration.json b/test/TestServerProjectsLowLevel/url/src/Generated/Configuration.json index 02595b7b4c2..da864d2b754 100644 --- a/test/TestServerProjectsLowLevel/url/src/Generated/Configuration.json +++ b/test/TestServerProjectsLowLevel/url/src/Generated/Configuration.json @@ -7,5 +7,6 @@ "..\\..\\..\\..\\..\\artifacts\\bin\\AutoRest.CSharp\\Debug\\net7.0\\Azure.Core.Shared" ], "public-clients": true, - "skip-csproj-packagereference": true + "skip-csproj-packagereference": true, + "use-model-reader-writer": true } \ No newline at end of file diff --git a/test/TestServerProjectsLowLevel/url/src/url_LowLevel.csproj b/test/TestServerProjectsLowLevel/url/src/url_LowLevel.csproj index 2c819590e9f..3e06a36e26e 100644 --- a/test/TestServerProjectsLowLevel/url/src/url_LowLevel.csproj +++ b/test/TestServerProjectsLowLevel/url/src/url_LowLevel.csproj @@ -13,5 +13,6 @@ + diff --git a/test/UnbrandedProjects.Tests/UnbrandedProjects.Tests.csproj b/test/UnbrandedProjects.Tests/UnbrandedProjects.Tests.csproj index 1ffbcc68ce3..6982a09244c 100644 --- a/test/UnbrandedProjects.Tests/UnbrandedProjects.Tests.csproj +++ b/test/UnbrandedProjects.Tests/UnbrandedProjects.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/Models/Thing.Serialization.cs b/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/Models/Thing.Serialization.cs index cd8d655e645..156f239a9d3 100644 --- a/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/Models/Thing.Serialization.cs +++ b/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/Models/Thing.Serialization.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; using System.Text.Json; namespace NoTestTypeSpec.Models diff --git a/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/Models/Thing.cs b/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/Models/Thing.cs index 778de10108a..a0fec49be0d 100644 --- a/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/Models/Thing.cs +++ b/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/Models/Thing.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace NoTestTypeSpec.Models { diff --git a/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/NoTestTypeSpecClient.cs b/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/NoTestTypeSpecClient.cs index 2753711a1f5..1d52d2b72cc 100644 --- a/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/NoTestTypeSpecClient.cs +++ b/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/NoTestTypeSpecClient.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using NoTestTypeSpec.Models; diff --git a/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/NoTestTypeSpecClientOptions.cs b/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/NoTestTypeSpecClientOptions.cs index f08885a2d4b..495123861da 100644 --- a/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/NoTestTypeSpecClientOptions.cs +++ b/test/UnbrandedProjects/NoTest-TypeSpec/src/Generated/NoTestTypeSpecClientOptions.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel; +using System.ClientModel; namespace NoTestTypeSpec { diff --git a/test/UnbrandedProjects/NoTest-TypeSpec/src/NoTestTypeSpec.csproj b/test/UnbrandedProjects/NoTest-TypeSpec/src/NoTestTypeSpec.csproj index 67145903490..dd4ff8c46f3 100644 --- a/test/UnbrandedProjects/NoTest-TypeSpec/src/NoTestTypeSpec.csproj +++ b/test/UnbrandedProjects/NoTest-TypeSpec/src/NoTestTypeSpec.csproj @@ -10,7 +10,7 @@ - + diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Audio.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Audio.cs index f9652f4fbf1..48aa5f13f03 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Audio.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Audio.cs @@ -3,9 +3,9 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; namespace OpenAI diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/AudioTranscriptions.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/AudioTranscriptions.cs index 6768f540d55..98b00ae0898 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/AudioTranscriptions.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/AudioTranscriptions.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/AudioTranslations.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/AudioTranslations.cs index a2ba0024b95..70b1cc6582d 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/AudioTranslations.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/AudioTranslations.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Chat.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Chat.cs index 283a91f4f91..cdfd3db10df 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Chat.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Chat.cs @@ -3,9 +3,9 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; namespace OpenAI diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/ChatCompletions.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/ChatCompletions.cs index cc2d1c4677b..f16a5bb354a 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/ChatCompletions.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/ChatCompletions.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Completions.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Completions.cs index 12bab291b1d..d4d2dd5c93c 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Completions.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Completions.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Edits.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Edits.cs index 3cddf4b703a..569b8fda17d 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Edits.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Edits.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Embeddings.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Embeddings.cs index 7386073c37f..27170b2fd10 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Embeddings.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Embeddings.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Files.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Files.cs index 62ef130860e..0e45510a240 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Files.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Files.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTunes.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTunes.cs index 2c603c0ee4f..811f81f1277 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTunes.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTunes.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTuning.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTuning.cs index f80aeea4e32..40f208a6e4e 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTuning.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTuning.cs @@ -3,9 +3,9 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; namespace OpenAI diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTuningJobs.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTuningJobs.cs index eae754a94bb..cbfc67d5a04 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTuningJobs.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/FineTuningJobs.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Images.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Images.cs index 1d75b76066d..5fc0cfd8e82 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Images.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Images.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionCallOption.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionCallOption.Serialization.cs index 2de535520fd..5c0d5dad8c8 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionCallOption.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionCallOption.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionCallOption.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionCallOption.cs index b37fcb785dc..85d7129c323 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionCallOption.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionCallOption.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionParameters.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionParameters.Serialization.cs index 9bfc82aed6c..9ce2ed67eb6 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionParameters.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionParameters.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionParameters.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionParameters.cs index 56d54d2faf7..82940a29b45 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionParameters.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctionParameters.cs @@ -3,8 +3,8 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctions.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctions.Serialization.cs index d159ae15713..3ea0452007a 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctions.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctions.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctions.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctions.cs index 5dad7b23d24..9fe0bedcf7c 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctions.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionFunctions.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionRequestMessage.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionRequestMessage.Serialization.cs index 3cbd690414c..90899c54304 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionRequestMessage.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionRequestMessage.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionResponseMessage.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionResponseMessage.Serialization.cs index 5958efda5e6..4c4c63ed8cf 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionResponseMessage.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ChatCompletionResponseMessage.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CompletionUsage.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CompletionUsage.Serialization.cs index a61eb73391d..2dbcc28941d 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CompletionUsage.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CompletionUsage.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCategories.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCategories.Serialization.cs index e9d00739731..c44e33c779a 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCategories.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCategories.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCategoryScores.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCategoryScores.Serialization.cs index bfde0a8551b..b64f5ede881 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCategoryScores.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCategoryScores.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionRequest.Serialization.cs index b17896fbc0f..c16648d61d5 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionRequest.cs index 34208cfee0e..ed98c3dddc1 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionRequest.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponse.Serialization.cs index c11f362279c..b68c8486929 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponse.Serialization.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponse.cs index eaae258bfef..1f4eb8f6909 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponseFunctionCall.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponseFunctionCall.Serialization.cs index 3e63f70ab7d..d46a7c81b3e 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponseFunctionCall.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponseFunctionCall.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponseFunctionCall.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponseFunctionCall.cs index acd4968ce24..fa262e3ab44 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponseFunctionCall.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChatCompletionResponseFunctionCall.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChoice.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChoice.Serialization.cs index 35406c3fa08..97ec7802bf8 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChoice.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChoice.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChoice.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChoice.cs index 25bfbd900cb..5fccdb84ad5 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChoice.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateChoice.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionRequest.Serialization.cs index 61569bec961..1fd50dd1392 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionRequest.cs index d8daf0f0cf0..457b7827900 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionRequest.cs @@ -3,8 +3,8 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponse.Serialization.cs index 881bafdbc0a..64cc0b39967 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponse.Serialization.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponse.cs index 76656d54696..756c521a613 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponseChoice.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponseChoice.Serialization.cs index 29e2c7734e6..625b096eadc 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponseChoice.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponseChoice.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponseChoice.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponseChoice.cs index e4b730f58ba..954fcb4f45b 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponseChoice.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateCompletionResponseChoice.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditRequest.Serialization.cs index c69b3b44945..b33518144d5 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditRequest.cs index d478c05e08a..2308c5fa0c3 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditRequest.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponse.Serialization.cs index d9c7ef6c6ce..ab408152dcf 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponse.Serialization.cs @@ -3,8 +3,8 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponse.cs index 6fb61d9e3ca..95bd9d17e44 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponseChoice.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponseChoice.Serialization.cs index f328491b56d..d0a0cb7f906 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponseChoice.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponseChoice.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponseChoice.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponseChoice.cs index 84161f5d70f..2a6dbb3b725 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponseChoice.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEditResponseChoice.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingRequest.Serialization.cs index 26a68b79af4..370b7e3fe15 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingRequest.cs index d733ba803e8..bfdd4091248 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingRequest.cs @@ -3,8 +3,8 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingResponse.Serialization.cs index 872418b99db..3430039c20b 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingResponse.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingResponse.cs index c74bb8ba328..ccfecfee529 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateEmbeddingResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFileRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFileRequest.Serialization.cs index b8414e2fa5b..df0ecbd2813 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFileRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFileRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFileRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFileRequest.cs index d5fb5aa5509..9dc6fe6a967 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFileRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFileRequest.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuneRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuneRequest.Serialization.cs index d36ff72b432..61b1a550e3f 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuneRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuneRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuneRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuneRequest.cs index 386f9572e52..269ab38b3bf 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuneRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuneRequest.cs @@ -3,8 +3,8 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuningJobRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuningJobRequest.Serialization.cs index 995b781e037..1dfea1acbda 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuningJobRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuningJobRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuningJobRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuningJobRequest.cs index 9db89055f7e..b7ef2b1c38a 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuningJobRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFineTuningJobRequest.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFunctionCall.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFunctionCall.Serialization.cs index ec1fb2df6d3..3172067b2aa 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFunctionCall.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFunctionCall.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFunctionCall.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFunctionCall.cs index f5e9b5a214b..a9333519a11 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFunctionCall.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateFunctionCall.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateHyperparameters.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateHyperparameters.Serialization.cs index 0f26ee1d28a..4c8a275825a 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateHyperparameters.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateHyperparameters.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageEditRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageEditRequest.Serialization.cs index e1973ab458a..865e3f045ec 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageEditRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageEditRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageEditRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageEditRequest.cs index 598db29ba08..8a6907479a4 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageEditRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageEditRequest.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageRequest.Serialization.cs index 44da59955b9..8687f02804a 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageRequest.cs index 97212af1438..d8aa16cda03 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageRequest.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageVariationRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageVariationRequest.Serialization.cs index 75354782d1d..5675d35e285 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageVariationRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageVariationRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageVariationRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageVariationRequest.cs index 90ba0fb695f..f742dc426dc 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageVariationRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateImageVariationRequest.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateLogprobs.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateLogprobs.Serialization.cs index fb178c32c51..0241d5c24db 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateLogprobs.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateLogprobs.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateLogprobs.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateLogprobs.cs index 3a876aaf9eb..0f8b0716ebf 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateLogprobs.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateLogprobs.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationRequest.Serialization.cs index 77402c2815a..19df92aeb23 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationRequest.cs index be095e06116..93a204113d4 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationRequest.cs @@ -3,8 +3,8 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationResponse.Serialization.cs index bb8fb8b6abb..72f544addf1 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationResponse.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationResponse.cs index 385c0da385b..88a813f8d19 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateModerationResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateResult.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateResult.Serialization.cs index ae8c21b8722..14c019979f0 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateResult.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateResult.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateResult.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateResult.cs index 261deae23d4..845a253a33c 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateResult.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateResult.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionRequest.Serialization.cs index bcfe449192b..d882bb9d5f2 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionRequest.cs index a1a06c6119f..d4db43dc34b 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionRequest.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionResponse.Serialization.cs index da3c2e20457..d571883a603 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionResponse.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionResponse.cs index 71a4e51428c..23001d0891a 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranscriptionResponse.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationRequest.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationRequest.Serialization.cs index 4c403e15daa..2b080f5305b 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationRequest.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationRequest.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationRequest.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationRequest.cs index b2982bb727a..d1fb0131b79 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationRequest.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationRequest.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationResponse.Serialization.cs index 69679df65e5..b8f40bb74ba 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationResponse.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationResponse.cs index 5857ee46078..342d887fa84 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateTranslationResponse.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateUsage.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateUsage.Serialization.cs index dd0c4d0bf1d..09741645e3f 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateUsage.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/CreateUsage.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteFileResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteFileResponse.Serialization.cs index d10ba1578fb..6e9d64c224e 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteFileResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteFileResponse.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteFileResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteFileResponse.cs index 734983f805f..c0e62405a9c 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteFileResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteFileResponse.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteModelResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteModelResponse.Serialization.cs index 2b1e416d5d1..34984437d30 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteModelResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteModelResponse.Serialization.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteModelResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteModelResponse.cs index 49c90ef5461..c0b245a7424 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteModelResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/DeleteModelResponse.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Embedding.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Embedding.Serialization.cs index 68225b09f5d..242d5d8e407 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Embedding.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Embedding.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Embedding.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Embedding.cs index 8f43e5a39db..c7594a8f624 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Embedding.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Embedding.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTune.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTune.Serialization.cs index 67e9be53605..f3d5da0c8dd 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTune.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTune.Serialization.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTune.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTune.cs index e9d38c3136a..9a44284a751 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTune.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTune.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneEvent.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneEvent.Serialization.cs index b0f018ede3d..c7044b736ae 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneEvent.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneEvent.Serialization.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneEvent.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneEvent.cs index 4d5605a37b2..d89a8f2ad59 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneEvent.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneEvent.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneHyperparams.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneHyperparams.Serialization.cs index da27a59d01d..581841a5f37 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneHyperparams.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuneHyperparams.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJob.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJob.Serialization.cs index c5fd02c8c6f..1492ff4abc8 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJob.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJob.Serialization.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJob.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJob.cs index ba8ee3df011..049d0ce7bf6 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJob.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJob.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobError.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobError.Serialization.cs index 7975f256574..d2d542a077a 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobError.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobError.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobEvent.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobEvent.Serialization.cs index 8b112bc0de5..81ac199a73e 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobEvent.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobEvent.Serialization.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobEvent.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobEvent.cs index ce9296b8e94..c16e0a55dfb 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobEvent.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobEvent.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobHyperparameters.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobHyperparameters.Serialization.cs index 632923e0687..b11f77380f5 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobHyperparameters.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/FineTuningJobHyperparameters.Serialization.cs @@ -3,8 +3,8 @@ #nullable disable using System; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Image.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Image.Serialization.cs index 50580229dc3..424808a8185 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Image.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Image.Serialization.cs @@ -3,8 +3,8 @@ #nullable disable using System; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ImagesResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ImagesResponse.Serialization.cs index cb376c5efa5..8ac53d05aa2 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ImagesResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ImagesResponse.Serialization.cs @@ -3,8 +3,8 @@ #nullable disable using System; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ImagesResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ImagesResponse.cs index af6186d0598..510ab07ef59 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ImagesResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ImagesResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFilesResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFilesResponse.Serialization.cs index 9e41d73a2f1..fe5431c370f 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFilesResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFilesResponse.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFilesResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFilesResponse.cs index beca5b68ef4..4bbc77dfa20 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFilesResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFilesResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuneEventsResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuneEventsResponse.Serialization.cs index 35a51dbc7d4..1e88785182c 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuneEventsResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuneEventsResponse.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuneEventsResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuneEventsResponse.cs index b289845db3f..7e4d03a09e6 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuneEventsResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuneEventsResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTunesResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTunesResponse.Serialization.cs index 7bdad8d7f23..fe5e823b1ef 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTunesResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTunesResponse.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTunesResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTunesResponse.cs index 2f23db6a89f..e7a30be8599 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTunesResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTunesResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuningJobEventsResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuningJobEventsResponse.Serialization.cs index 1567574ecae..5cfbf38d85a 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuningJobEventsResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuningJobEventsResponse.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuningJobEventsResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuningJobEventsResponse.cs index 5bc1d827686..3f9b2b817f1 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuningJobEventsResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListFineTuningJobEventsResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListModelsResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListModelsResponse.Serialization.cs index d965bbc9d49..5068b6ad6bf 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListModelsResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListModelsResponse.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListModelsResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListModelsResponse.cs index 2ccaea83a0f..f4d436c55c8 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListModelsResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListModelsResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListPaginatedFineTuningJobsResponse.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListPaginatedFineTuningJobsResponse.Serialization.cs index 01b4a526a05..406c3a75c95 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListPaginatedFineTuningJobsResponse.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListPaginatedFineTuningJobsResponse.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListPaginatedFineTuningJobsResponse.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListPaginatedFineTuningJobsResponse.cs index 4292d1c692d..54538f52697 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListPaginatedFineTuningJobsResponse.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/ListPaginatedFineTuningJobsResponse.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Model.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Model.Serialization.cs index b5c281e2977..1cc98e44489 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Model.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Model.Serialization.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Core; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Model.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Model.cs index 7832dc4feac..4bee7817cc9 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Model.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/Model.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/OpenAIFile.Serialization.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/OpenAIFile.Serialization.cs index b5560e560cf..dc18819dc1e 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/OpenAIFile.Serialization.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/OpenAIFile.Serialization.cs @@ -3,8 +3,8 @@ #nullable disable using System; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace OpenAI.Models diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/OpenAIFile.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/OpenAIFile.cs index c25b1e96a5f..01c766006b7 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/OpenAIFile.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Models/OpenAIFile.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace OpenAI.Models { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/ModelsOps.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/ModelsOps.cs index d128af3bd29..5b944292037 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/ModelsOps.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/ModelsOps.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Moderations.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Moderations.cs index 194f48a5890..49c1d18a3a9 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Moderations.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/Moderations.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using OpenAI.Models; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/OpenAIClient.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/OpenAIClient.cs index 56ec59370aa..77668579da5 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/OpenAIClient.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/OpenAIClient.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; namespace OpenAI diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/OpenAIClientOptions.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/OpenAIClientOptions.cs index f13c275baa0..5b661878a84 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/OpenAIClientOptions.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/Generated/OpenAIClientOptions.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel; +using System.ClientModel; namespace OpenAI { diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/OpenAI.csproj b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/OpenAI.csproj index 06e8e02cc5f..c07146eafef 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/OpenAI.csproj +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/src/OpenAI.csproj @@ -10,7 +10,7 @@ - + diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/AudioTranscriptionsTests.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/AudioTranscriptionsTests.cs index a0ea4d631ee..7cce5584522 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/AudioTranscriptionsTests.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/AudioTranscriptionsTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using OpenAI; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/AudioTranslationsTests.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/AudioTranslationsTests.cs index 45c493ea04a..e6412312b11 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/AudioTranslationsTests.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/AudioTranslationsTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using OpenAI; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ChatCompletionsTests.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ChatCompletionsTests.cs index 2ac49b36091..a8c2ae1a416 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ChatCompletionsTests.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ChatCompletionsTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using OpenAI; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/CompletionsTests.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/CompletionsTests.cs index 39525b43df6..3a069540348 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/CompletionsTests.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/CompletionsTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using OpenAI; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/EmbeddingsTests.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/EmbeddingsTests.cs index bae4a48669e..8a6052960d6 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/EmbeddingsTests.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/EmbeddingsTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using OpenAI; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/FilesTests.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/FilesTests.cs index de0ce933eb1..9372d75f4ef 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/FilesTests.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/FilesTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using OpenAI; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/FineTuningJobsTests.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/FineTuningJobsTests.cs index 1d80a40a10c..ea1fc2ad233 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/FineTuningJobsTests.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/FineTuningJobsTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using OpenAI; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ImagesTests.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ImagesTests.cs index 48865269456..a487952293c 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ImagesTests.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ImagesTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using OpenAI; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ModelsOpsTests.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ModelsOpsTests.cs index f25a385f6de..24c9896c04b 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ModelsOpsTests.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ModelsOpsTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using OpenAI; diff --git a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ModerationsTests.cs b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ModerationsTests.cs index 568b7423eba..138b487d306 100644 --- a/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ModerationsTests.cs +++ b/test/UnbrandedProjects/Platform-OpenAI-TypeSpec/tests/Generated/ModerationsTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using OpenAI; diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Friend.Serialization.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Friend.Serialization.cs index 3b96cb9eb16..42cf7384026 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Friend.Serialization.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Friend.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace UnbrandedTypeSpec.Models diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Friend.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Friend.cs index 3e28d9d08ad..470918420ba 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Friend.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Friend.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace UnbrandedTypeSpec.Models { diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.Serialization.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.Serialization.cs index f0aa588dade..2ee53e5d377 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.Serialization.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace UnbrandedTypeSpec.Models diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.cs index dd79afbe088..baebd07ab4c 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithFormat.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace UnbrandedTypeSpec.Models { diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs index 5a9197a65cf..fa8e4666031 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace UnbrandedTypeSpec.Models diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.Serialization.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.Serialization.cs index 95cba97a963..3a5eacf07ff 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.Serialization.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.Serialization.cs @@ -2,8 +2,8 @@ #nullable disable -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Text.Json; namespace UnbrandedTypeSpec.Models diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.cs index 24015207557..e8b297abdf8 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/ProjectedModel.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel.Internal; +using System.ClientModel.Internal; namespace UnbrandedTypeSpec.Models { diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs index 0cedef114f1..4acd028b0f5 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.Serialization.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; using System.Text.Json; namespace UnbrandedTypeSpec.Models diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.cs index 5b51c3afc0a..e8caa3a243f 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/RoundTripModel.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace UnbrandedTypeSpec.Models { diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Thing.Serialization.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Thing.Serialization.cs index c370519cf0e..a84895388c7 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Thing.Serialization.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Thing.Serialization.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Internal; using System.Text.Json; namespace UnbrandedTypeSpec.Models diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Thing.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Thing.cs index 280ef1a3caf..2d1aac4009e 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Thing.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/Models/Thing.cs @@ -3,9 +3,9 @@ #nullable disable using System; +using System.ClientModel.Internal; using System.Collections.Generic; using System.Linq; -using System.Net.ClientModel.Internal; namespace UnbrandedTypeSpec.Models { diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClient.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClient.cs index 995545ec366..007abf794b6 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClient.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClient.cs @@ -3,10 +3,10 @@ #nullable disable using System; -using System.Net.ClientModel; -using System.Net.ClientModel.Core; -using System.Net.ClientModel.Core.Pipeline; -using System.Net.ClientModel.Internal; +using System.ClientModel; +using System.ClientModel.Internal; +using System.ClientModel.Primitives; +using System.ClientModel.Primitives.Pipeline; using System.Threading; using System.Threading.Tasks; using UnbrandedTypeSpec.Models; diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClientOptions.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClientOptions.cs index 17372b04ce5..18179e67947 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClientOptions.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/Generated/UnbrandedTypeSpecClientOptions.cs @@ -2,7 +2,7 @@ #nullable disable -using System.Net.ClientModel; +using System.ClientModel; namespace UnbrandedTypeSpec { diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/src/UnbrandedTypeSpec.csproj b/test/UnbrandedProjects/Unbranded-TypeSpec/src/UnbrandedTypeSpec.csproj index 3c8d00f4a9f..fb5efe5e89a 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/src/UnbrandedTypeSpec.csproj +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/src/UnbrandedTypeSpec.csproj @@ -10,7 +10,7 @@ - + diff --git a/test/UnbrandedProjects/Unbranded-TypeSpec/tests/Generated/UnbrandedTypeSpecClientTests.cs b/test/UnbrandedProjects/Unbranded-TypeSpec/tests/Generated/UnbrandedTypeSpecClientTests.cs index 74ec696164f..03f634206ed 100644 --- a/test/UnbrandedProjects/Unbranded-TypeSpec/tests/Generated/UnbrandedTypeSpecClientTests.cs +++ b/test/UnbrandedProjects/Unbranded-TypeSpec/tests/Generated/UnbrandedTypeSpecClientTests.cs @@ -3,7 +3,7 @@ #nullable disable using System; -using System.Net.ClientModel; +using System.ClientModel; using NUnit.Framework; using UnbrandedTypeSpec;