From b4f5cd7d6da74d859ccbf8b86cd5598edc32d426 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Wed, 22 Oct 2025 10:39:56 -0700 Subject: [PATCH 1/8] minor: added long path support to prerequisite --- packages/http-client-csharp/CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/http-client-csharp/CONTRIBUTING.md b/packages/http-client-csharp/CONTRIBUTING.md index d32813e3357..53518283b9c 100644 --- a/packages/http-client-csharp/CONTRIBUTING.md +++ b/packages/http-client-csharp/CONTRIBUTING.md @@ -22,6 +22,7 @@ Before you begin, ensure you have the following installed: - [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - [Git](https://git-scm.com/) - [PowerShell](https://docs.microsoft.com/powershell/scripting/install/installing-powershell) (version 7.0 or higher, for advanced testing and code generation scenarios) +- [Long Path Support](https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=powershell#registry-setting-to-enable-long-paths) (Windows only required to avoid path length limitations during development) ## Getting Started From f7c7cb63184c95e0ce3e88fdcd765f76c38d7130 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 1 Dec 2025 12:53:40 -0800 Subject: [PATCH 2/8] minor: protected constructor modification --- .../src/Providers/ModelProvider.cs | 67 +++++++++++++++++-- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs index 3738e2ca938..7d1a7a04dae 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs @@ -729,20 +729,67 @@ private IEnumerable GetAllBaseFieldsForConstructorInitialization( { if (baseParameters.Count > 0) { - // Check if base model has dual constructor pattern and we should call private protected constructor - if (isInitializationConstructor && BaseModelProvider._isMultiLevelDiscriminator) + // Check if current model has dual constructor pattern and we should call private protected constructor + if (isInitializationConstructor && _isMultiLevelDiscriminator) { // Call base model's private protected constructor with discriminator value var args = new List(); - args.Add(Literal(_inputModel.DiscriminatorValue ?? "")); + + // For multi-level inheritance: pass through discriminator if available, otherwise use own value + if (includeDiscriminatorParameter) + { + var discriminatorProperty = BaseModelProvider?.CanonicalView.Properties.FirstOrDefault(p => p.IsDiscriminator); + + if (discriminatorProperty != null) + { + var baseDiscriminatorParam = baseParameters.FirstOrDefault(p => p.Property?.IsDiscriminator == true); + + if (baseDiscriminatorParam != null) + { + args.Add(baseDiscriminatorParam); + } + else + { + // Fallback: create variable expression + var discriminatorParamName = discriminatorProperty.Name.ToVariableName(); // should be "kind" + var discriminatorParam = new VariableExpression(typeof(string), discriminatorParamName); + args.Add(discriminatorParam); + } + } + else + { + // Fallback: use our own discriminator value + args.Add(Literal(_inputModel.DiscriminatorValue ?? "")); + } + } + else + { + // For public constructor: use our own discriminator value + args.Add(Literal(_inputModel.DiscriminatorValue ?? "")); + } + var filteredParams = baseParameters.Where(p => p.Property is null || !p.Property.IsDiscriminator).ToList(); args.AddRange(filteredParams.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))); constructorInitializer = new ConstructorInitializer(true, args); } else { - // Standard base constructor call - constructorInitializer = new ConstructorInitializer(true, [.. baseParameters.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))]); + // Check if base model has multi-level discriminator and we should call its protected constructor + if (isInitializationConstructor && BaseModelProvider?._isMultiLevelDiscriminator == true) + { + // Call base model's private protected constructor with our discriminator value + var args = new List(); + args.Add(Literal(_inputModel.DiscriminatorValue ?? "")); + + var filteredParams = baseParameters.Where(p => p.Property is null || !p.Property.IsDiscriminator).ToList(); + args.AddRange(filteredParams.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))); + constructorInitializer = new ConstructorInitializer(true, args); + } + else + { + // Standard base constructor call + constructorInitializer = new ConstructorInitializer(true, [.. baseParameters.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))]); + } } } else @@ -842,7 +889,15 @@ private ValueExpression GetExpressionForCtor(ParameterProvider parameter, HashSe { if (isPrimaryConstructor) { - return DiscriminatorValueExpression ?? throw new InvalidOperationException($"invalid discriminator {_inputModel.DiscriminatorValue} for property {parameter.Property.Name}"); + // For multi-level discriminators, check if we should pass through the parameter instead of using our discriminator value + if (_isMultiLevelDiscriminator && parameter.Name != parameter.Property.Name.ToVariableName()) + { + return parameter; + } + else + { + return DiscriminatorValueExpression ?? throw new InvalidOperationException($"invalid discriminator {_inputModel.DiscriminatorValue} for property {parameter.Property.Name}"); + } } else if (IsUnknownDiscriminatorModel) { From 81f5c3cde208e52ebae6e3ea07e059ba602c6411 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 1 Dec 2025 14:34:47 -0800 Subject: [PATCH 3/8] minor:private mem added --- .../src/Providers/ModelProvider.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs index 7d1a7a04dae..e273dfe686e 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs @@ -62,6 +62,7 @@ protected override FormattableString BuildDescription() private ModelProvider? _baseModelProvider; private ConstructorProvider? _fullConstructor; internal PropertyProvider? DiscriminatorProperty { get; private set; } + private ValueExpression DiscriminatorLiteral => Literal(_inputModel.DiscriminatorValue ?? ""); public ModelProvider(InputModelType inputModel) : base(inputModel) { @@ -735,7 +736,7 @@ private IEnumerable GetAllBaseFieldsForConstructorInitialization( // Call base model's private protected constructor with discriminator value var args = new List(); - // For multi-level inheritance: pass through discriminator if available, otherwise use own value + // For multi-level inheritance: pass through discriminator parameter if available, otherwise use own value if (includeDiscriminatorParameter) { var discriminatorProperty = BaseModelProvider?.CanonicalView.Properties.FirstOrDefault(p => p.IsDiscriminator); @@ -759,13 +760,13 @@ private IEnumerable GetAllBaseFieldsForConstructorInitialization( else { // Fallback: use our own discriminator value - args.Add(Literal(_inputModel.DiscriminatorValue ?? "")); + args.Add(DiscriminatorLiteral); } } else { // For public constructor: use our own discriminator value - args.Add(Literal(_inputModel.DiscriminatorValue ?? "")); + args.Add(DiscriminatorLiteral); } var filteredParams = baseParameters.Where(p => p.Property is null || !p.Property.IsDiscriminator).ToList(); @@ -779,7 +780,7 @@ private IEnumerable GetAllBaseFieldsForConstructorInitialization( { // Call base model's private protected constructor with our discriminator value var args = new List(); - args.Add(Literal(_inputModel.DiscriminatorValue ?? "")); + args.Add(DiscriminatorLiteral); var filteredParams = baseParameters.Where(p => p.Property is null || !p.Property.IsDiscriminator).ToList(); args.AddRange(filteredParams.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))); @@ -877,7 +878,7 @@ p.Property is null } // fallback to the default value - return Literal(_inputModel.DiscriminatorValue); + return DiscriminatorLiteral; } } return null; @@ -925,7 +926,7 @@ private ValueExpression GetExpressionForCtor(ParameterProvider parameter, HashSe if (type.IsStruct) { /* kind != default ? kind : "unknown" */ - return new TernaryConditionalExpression(discriminatorExpression.NotEqual(Default), discriminatorExpression, Literal(_inputModel.DiscriminatorValue)); + return new TernaryConditionalExpression(discriminatorExpression.NotEqual(Default), discriminatorExpression, DiscriminatorLiteral); } else { @@ -935,7 +936,7 @@ private ValueExpression GetExpressionForCtor(ParameterProvider parameter, HashSe else { /* kind ?? "unknown" */ - return discriminatorExpression.NullCoalesce(Literal(_inputModel.DiscriminatorValue)); + return discriminatorExpression.NullCoalesce(DiscriminatorLiteral); } } From 5a3c0887d49f82b376b96ddb4652c34b4aae615c Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Mon, 1 Dec 2025 14:41:00 -0800 Subject: [PATCH 4/8] added consolidated discriminator logic --- .../src/Providers/ModelProvider.cs | 61 +++++++++---------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs index e273dfe686e..24c2dea7c58 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs @@ -622,6 +622,33 @@ private ConstructorProvider BuildProtectedInheritanceConstructor() this); } + /// + /// Gets the appropriate discriminator value expression for calling base constructor. + /// + /// Whether to use discriminator parameter if available + /// Base constructor parameters to search for discriminator + /// Expression representing the discriminator value to pass to base constructor + private ValueExpression GetDiscriminatorForBaseConstructor(bool includeDiscriminatorParameter, IReadOnlyList baseParameters) + { + if (includeDiscriminatorParameter) + { + var discriminatorProperty = BaseModelProvider?.CanonicalView.Properties.FirstOrDefault(p => p.IsDiscriminator); + if (discriminatorProperty != null) + { + var baseDiscriminatorParam = baseParameters.FirstOrDefault(p => p.Property?.IsDiscriminator == true); + if (baseDiscriminatorParam != null) + { + return baseDiscriminatorParam; + } + // Fallback: create variable expression + var discriminatorParamName = discriminatorProperty.Name.ToVariableName(); + return new VariableExpression(typeof(string), discriminatorParamName); + } + } + + return DiscriminatorLiteral; + } + /// /// Builds the internal constructor for the model which contains all public properties /// as parameters. @@ -737,37 +764,7 @@ private IEnumerable GetAllBaseFieldsForConstructorInitialization( var args = new List(); // For multi-level inheritance: pass through discriminator parameter if available, otherwise use own value - if (includeDiscriminatorParameter) - { - var discriminatorProperty = BaseModelProvider?.CanonicalView.Properties.FirstOrDefault(p => p.IsDiscriminator); - - if (discriminatorProperty != null) - { - var baseDiscriminatorParam = baseParameters.FirstOrDefault(p => p.Property?.IsDiscriminator == true); - - if (baseDiscriminatorParam != null) - { - args.Add(baseDiscriminatorParam); - } - else - { - // Fallback: create variable expression - var discriminatorParamName = discriminatorProperty.Name.ToVariableName(); // should be "kind" - var discriminatorParam = new VariableExpression(typeof(string), discriminatorParamName); - args.Add(discriminatorParam); - } - } - else - { - // Fallback: use our own discriminator value - args.Add(DiscriminatorLiteral); - } - } - else - { - // For public constructor: use our own discriminator value - args.Add(DiscriminatorLiteral); - } + args.Add(GetDiscriminatorForBaseConstructor(includeDiscriminatorParameter, baseParameters)); var filteredParams = baseParameters.Where(p => p.Property is null || !p.Property.IsDiscriminator).ToList(); args.AddRange(filteredParams.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))); @@ -780,7 +777,7 @@ private IEnumerable GetAllBaseFieldsForConstructorInitialization( { // Call base model's private protected constructor with our discriminator value var args = new List(); - args.Add(DiscriminatorLiteral); + args.Add(GetDiscriminatorForBaseConstructor(false, baseParameters)); var filteredParams = baseParameters.Where(p => p.Property is null || !p.Property.IsDiscriminator).ToList(); args.AddRange(filteredParams.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))); From 2afdf43e95f8fed26199211d46d72539e81b577f Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Tue, 2 Dec 2025 06:50:25 -0800 Subject: [PATCH 5/8] added unit test --- .../src/Providers/ModelProvider.cs | 118 +++++++++--------- .../ModelProviders/ModelProviderTests.cs | 69 ++++++++++ 2 files changed, 131 insertions(+), 56 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs index 24c2dea7c58..d8e857bd5cb 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs @@ -622,27 +622,49 @@ private ConstructorProvider BuildProtectedInheritanceConstructor() this); } + /// + /// Builds a multi-level discriminator constructor initializer. + /// + private ConstructorInitializer BuildMultiLevelDiscriminatorInitializer( + IReadOnlyList baseParameters, + HashSet overriddenProperties, + bool isInitializationConstructor, + bool includeDiscriminatorParameter, + IReadOnlyList currentParameters) + { + var args = new List(); + + // Only add discriminator if base model has discriminator or is multi-level discriminator + if (BaseModelProvider?._isMultiLevelDiscriminator == true || baseParameters.Any(p => p.Property?.IsDiscriminator == true)) + { + args.Add(GetDiscriminatorForBaseConstructor(includeDiscriminatorParameter, baseParameters, currentParameters)); + } + + var filteredParams = baseParameters.Where(p => p.Property is null || !p.Property.IsDiscriminator).ToList(); + args.AddRange(filteredParams.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))); + + return new ConstructorInitializer(true, args); + } + /// /// Gets the appropriate discriminator value expression for calling base constructor. /// - /// Whether to use discriminator parameter if available - /// Base constructor parameters to search for discriminator - /// Expression representing the discriminator value to pass to base constructor - private ValueExpression GetDiscriminatorForBaseConstructor(bool includeDiscriminatorParameter, IReadOnlyList baseParameters) + private ValueExpression GetDiscriminatorForBaseConstructor(bool includeDiscriminatorParameter, IReadOnlyList baseParameters, IReadOnlyList? currentParameters = null) { - if (includeDiscriminatorParameter) + var discriminatorProperty = BaseModelProvider?.CanonicalView.Properties.FirstOrDefault(p => p.IsDiscriminator); + if (discriminatorProperty != null) { - var discriminatorProperty = BaseModelProvider?.CanonicalView.Properties.FirstOrDefault(p => p.IsDiscriminator); - if (discriminatorProperty != null) + var baseDiscriminatorParam = baseParameters.FirstOrDefault(p => p.Property?.IsDiscriminator == true); + + if (baseDiscriminatorParam != null && includeDiscriminatorParameter) { - var baseDiscriminatorParam = baseParameters.FirstOrDefault(p => p.Property?.IsDiscriminator == true); - if (baseDiscriminatorParam != null) + var discriminatorParam = currentParameters?.FirstOrDefault(p => p.Property?.IsDiscriminator == true) + ?? baseParameters.FirstOrDefault(p => p.Property?.IsDiscriminator == true); + + if (discriminatorParam != null) { - return baseDiscriminatorParam; + return discriminatorParam; } - // Fallback: create variable expression - var discriminatorParamName = discriminatorProperty.Name.ToVariableName(); - return new VariableExpression(typeof(string), discriminatorParamName); } } @@ -751,43 +773,43 @@ private IEnumerable GetAllBaseFieldsForConstructorInitialization( AddInitializationParameterForCtor(baseParameters, Type.IsStruct, isInitializationConstructor, field: field); } + // Build constructor parameters first so we can use them for initializer + foreach (var property in CanonicalView.Properties) + { + AddInitializationParameterForCtor(constructorParameters, Type.IsStruct, isInitializationConstructor, property); + } + + foreach (var field in CanonicalView.Fields) + { + AddInitializationParameterForCtor(constructorParameters, Type.IsStruct, isInitializationConstructor, field: field); + } + + constructorParameters.InsertRange(0, _inputModel.IsUnknownDiscriminatorModel + ? baseParameters + : baseParameters.Where(p => + p.Property is null + || (!overriddenProperties.Contains(p.Property!) && (!p.Property.IsDiscriminator || !isInitializationConstructor || includeDiscriminatorParameter)))); + // construct the initializer using the parameters from base signature ConstructorInitializer? constructorInitializer = null; if (BaseModelProvider != null) { if (baseParameters.Count > 0) { - // Check if current model has dual constructor pattern and we should call private protected constructor - if (isInitializationConstructor && _isMultiLevelDiscriminator) + // Check if we should call multi-level discriminator constructor + if (isInitializationConstructor && (_isMultiLevelDiscriminator || BaseModelProvider?._isMultiLevelDiscriminator == true)) { - // Call base model's private protected constructor with discriminator value - var args = new List(); - - // For multi-level inheritance: pass through discriminator parameter if available, otherwise use own value - args.Add(GetDiscriminatorForBaseConstructor(includeDiscriminatorParameter, baseParameters)); - - var filteredParams = baseParameters.Where(p => p.Property is null || !p.Property.IsDiscriminator).ToList(); - args.AddRange(filteredParams.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))); - constructorInitializer = new ConstructorInitializer(true, args); + constructorInitializer = BuildMultiLevelDiscriminatorInitializer( + baseParameters, + overriddenProperties, + isInitializationConstructor, + includeDiscriminatorParameter, + constructorParameters); } else { - // Check if base model has multi-level discriminator and we should call its protected constructor - if (isInitializationConstructor && BaseModelProvider?._isMultiLevelDiscriminator == true) - { - // Call base model's private protected constructor with our discriminator value - var args = new List(); - args.Add(GetDiscriminatorForBaseConstructor(false, baseParameters)); - - var filteredParams = baseParameters.Where(p => p.Property is null || !p.Property.IsDiscriminator).ToList(); - args.AddRange(filteredParams.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))); - constructorInitializer = new ConstructorInitializer(true, args); - } - else - { - // Standard base constructor call - constructorInitializer = new ConstructorInitializer(true, [.. baseParameters.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))]); - } + // Standard base constructor call + constructorInitializer = new ConstructorInitializer(true, [.. baseParameters.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))]); } } else @@ -797,22 +819,6 @@ private IEnumerable GetAllBaseFieldsForConstructorInitialization( } } - foreach (var property in CanonicalView.Properties) - { - AddInitializationParameterForCtor(constructorParameters, Type.IsStruct, isInitializationConstructor, property); - } - - foreach (var field in CanonicalView.Fields) - { - AddInitializationParameterForCtor(constructorParameters, Type.IsStruct, isInitializationConstructor, field: field); - } - - constructorParameters.InsertRange(0, _inputModel.IsUnknownDiscriminatorModel - ? baseParameters - : baseParameters.Where(p => - p.Property is null - || (!overriddenProperties.Contains(p.Property!) && (!p.Property.IsDiscriminator || !isInitializationConstructor || includeDiscriminatorParameter)))); - if (!isInitializationConstructor) { foreach (var property in AdditionalPropertyProperties) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs index 234654be7eb..b23436d0002 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs @@ -1542,5 +1542,74 @@ public void TestMultiLayerDiscriminator_ThreeLayers() Assert.AreEqual("name", catProtectedParams[2].Name); Assert.AreEqual("meows", catProtectedParams[3].Name); } + + [Test] + public void TestMultiLevelDiscriminatorConstructorParameterPassthrough() + { + // Create a three-level discriminator hierarchy: base → intermediate → derived + var derivedInputModel = InputFactory.Model( + "derived", + discriminatedKind: "derived", + properties: [ + InputFactory.Property("kind", InputPrimitiveType.String, isRequired: true, isDiscriminator: true), + InputFactory.Property("derivedProperty", InputPrimitiveType.String, isRequired: true) + ]); + + var intermediateInputModel = InputFactory.Model( + "intermediate", + discriminatedKind: "intermediate", + properties: [ + InputFactory.Property("kind", InputPrimitiveType.String, isRequired: true, isDiscriminator: true), + InputFactory.Property("intermediateProperty", InputPrimitiveType.Boolean, isRequired: true) + ], + discriminatedModels: new Dictionary() { { "derived", derivedInputModel } }); + + var baseInputModel = InputFactory.Model( + "base", + properties: [ + InputFactory.Property("kind", InputPrimitiveType.String, isRequired: true, isDiscriminator: true), + InputFactory.Property("baseProperty", InputPrimitiveType.String, isRequired: true) + ], + discriminatedModels: new Dictionary() { { "intermediate", intermediateInputModel } }); + + MockHelpers.LoadMockGenerator(inputModelTypes: [baseInputModel, intermediateInputModel, derivedInputModel]); + + var intermediateProvider = new ModelProvider(intermediateInputModel); + var derivedProvider = new ModelProvider(derivedInputModel); + + Assert.IsNotNull(intermediateProvider); + Assert.IsNotNull(derivedProvider); + + // Verify intermediate model has expected constructor count + Assert.AreEqual(3, intermediateProvider.Constructors.Count); + + // Get the protected constructor for intermediate model + var intermediateProtectedCtor = intermediateProvider.Constructors.FirstOrDefault(c => + c.Signature.Modifiers.HasFlag(MethodSignatureModifiers.Private) && + c.Signature.Modifiers.HasFlag(MethodSignatureModifiers.Protected)); + + Assert.IsNotNull(intermediateProtectedCtor, "Intermediate model should have a protected constructor for multi-level discriminator"); + + // Verify the base constructor call uses the discriminator parameter, not hardcoded literal + var initializer = intermediateProtectedCtor!.Signature.Initializer; + Assert.IsNotNull(initializer, "Protected constructor should have base initializer"); + Assert.IsTrue(initializer!.IsBase, "Initializer should call base constructor"); + + // Key validation: first argument should be the discriminator parameter, not hardcoded value + var kindArgument = initializer!.Arguments[0].ToDisplayString(); + Assert.AreEqual("kind", kindArgument, "Intermediate protected constructor should pass discriminator parameter to base, not hardcode literal"); + + // Verify derived model constructor passes discriminator correctly to intermediate + var derivedCtor = derivedProvider.Constructors.FirstOrDefault(c => c.Signature.Modifiers.HasFlag(MethodSignatureModifiers.Public)); + Assert.IsNotNull(derivedCtor, "Derived model should have a public constructor"); + + var derivedInitializer = derivedCtor!.Signature.Initializer; + Assert.IsNotNull(derivedInitializer, "Derived constructor should have base initializer"); + Assert.IsTrue(derivedInitializer!.IsBase, "Derived initializer should call base constructor"); + + // Derived should pass its discriminator value to intermediate constructor + var derivedKindArgument = derivedInitializer!.Arguments[0].ToDisplayString(); + Assert.AreEqual("\"derived\"", derivedKindArgument, "Derived should pass its discriminator value to intermediate constructor"); + } } } From 2fc58640b5963fe947cf6491d9c6ef13bf3e908d Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Wed, 3 Dec 2025 00:06:05 -0800 Subject: [PATCH 6/8] refactored code and removed redundant filter --- .../src/Providers/ModelProvider.cs | 81 +++++-------------- 1 file changed, 20 insertions(+), 61 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs index d8e857bd5cb..d1b6e172bad 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs @@ -622,55 +622,6 @@ private ConstructorProvider BuildProtectedInheritanceConstructor() this); } - /// - /// Builds a multi-level discriminator constructor initializer. - /// - private ConstructorInitializer BuildMultiLevelDiscriminatorInitializer( - IReadOnlyList baseParameters, - HashSet overriddenProperties, - bool isInitializationConstructor, - bool includeDiscriminatorParameter, - IReadOnlyList currentParameters) - { - var args = new List(); - - // Only add discriminator if base model has discriminator or is multi-level discriminator - if (BaseModelProvider?._isMultiLevelDiscriminator == true || baseParameters.Any(p => p.Property?.IsDiscriminator == true)) - { - args.Add(GetDiscriminatorForBaseConstructor(includeDiscriminatorParameter, baseParameters, currentParameters)); - } - - var filteredParams = baseParameters.Where(p => p.Property is null || !p.Property.IsDiscriminator).ToList(); - args.AddRange(filteredParams.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))); - - return new ConstructorInitializer(true, args); - } - - /// - /// Gets the appropriate discriminator value expression for calling base constructor. - /// - private ValueExpression GetDiscriminatorForBaseConstructor(bool includeDiscriminatorParameter, IReadOnlyList baseParameters, IReadOnlyList? currentParameters = null) - { - var discriminatorProperty = BaseModelProvider?.CanonicalView.Properties.FirstOrDefault(p => p.IsDiscriminator); - if (discriminatorProperty != null) - { - var baseDiscriminatorParam = baseParameters.FirstOrDefault(p => p.Property?.IsDiscriminator == true); - - if (baseDiscriminatorParam != null && includeDiscriminatorParameter) - { - var discriminatorParam = currentParameters?.FirstOrDefault(p => p.Property?.IsDiscriminator == true) - ?? baseParameters.FirstOrDefault(p => p.Property?.IsDiscriminator == true); - - if (discriminatorParam != null) - { - return discriminatorParam; - } - } - } - - return DiscriminatorLiteral; - } - /// /// Builds the internal constructor for the model which contains all public properties /// as parameters. @@ -788,7 +739,7 @@ private IEnumerable GetAllBaseFieldsForConstructorInitialization( ? baseParameters : baseParameters.Where(p => p.Property is null - || (!overriddenProperties.Contains(p.Property!) && (!p.Property.IsDiscriminator || !isInitializationConstructor || includeDiscriminatorParameter)))); + || (!overriddenProperties.Contains(p.Property!) && (!p.Property.IsDiscriminator || !isInitializationConstructor || (includeDiscriminatorParameter && _isMultiLevelDiscriminator))))); // construct the initializer using the parameters from base signature ConstructorInitializer? constructorInitializer = null; @@ -797,19 +748,24 @@ p.Property is null if (baseParameters.Count > 0) { // Check if we should call multi-level discriminator constructor - if (isInitializationConstructor && (_isMultiLevelDiscriminator || BaseModelProvider?._isMultiLevelDiscriminator == true)) + if (isInitializationConstructor && (_isMultiLevelDiscriminator || BaseModelProvider._isMultiLevelDiscriminator)) { - constructorInitializer = BuildMultiLevelDiscriminatorInitializer( - baseParameters, - overriddenProperties, - isInitializationConstructor, - includeDiscriminatorParameter, - constructorParameters); + var baseDiscriminatorParam = baseParameters.FirstOrDefault(p => p.Property?.IsDiscriminator == true); + var hasDiscriminatorProperty = BaseModelProvider.CanonicalView.Properties.Any(p => p.IsDiscriminator); + + ValueExpression discriminatorExpression = (hasDiscriminatorProperty && baseDiscriminatorParam is not null && includeDiscriminatorParameter) + ? constructorParameters.FirstOrDefault(p => p.Property?.IsDiscriminator == true) ?? baseDiscriminatorParam + : DiscriminatorLiteral; + + var args = baseParameters.Where(p => p.Property?.IsDiscriminator != true) + .Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor, includeDiscriminatorParameter: false)); + + constructorInitializer = new ConstructorInitializer(true, [discriminatorExpression, .. args]); } else { // Standard base constructor call - constructorInitializer = new ConstructorInitializer(true, [.. baseParameters.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))]); + constructorInitializer = new ConstructorInitializer(true, [.. baseParameters.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor, includeDiscriminatorParameter: false))]); } } else @@ -887,14 +843,13 @@ p.Property is null return null; } - private ValueExpression GetExpressionForCtor(ParameterProvider parameter, HashSet overriddenProperties, bool isPrimaryConstructor) + private ValueExpression GetExpressionForCtor(ParameterProvider parameter, HashSet overriddenProperties, bool isPrimaryConstructor, bool includeDiscriminatorParameter = false) { if (parameter.Property is not null && parameter.Property.IsDiscriminator && _inputModel.DiscriminatorValue != null) { if (isPrimaryConstructor) { - // For multi-level discriminators, check if we should pass through the parameter instead of using our discriminator value - if (_isMultiLevelDiscriminator && parameter.Name != parameter.Property.Name.ToVariableName()) + if (includeDiscriminatorParameter && _isMultiLevelDiscriminator) { return parameter; } @@ -907,6 +862,10 @@ private ValueExpression GetExpressionForCtor(ParameterProvider parameter, HashSe { return GetUnknownDiscriminatorExpression(parameter.Property) ?? throw new InvalidOperationException($"invalid discriminator {_inputModel.DiscriminatorValue} for property {parameter.Property.Name}"); } + else + { + return parameter; + } } var paramToUse = parameter.Property is not null && overriddenProperties.Contains(parameter.Property) ? Properties.First(p => p.Name == parameter.Property.Name).AsParameter : parameter; From e924cc56ffd6a4c8ae142af01b22abc4b305c018 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Wed, 3 Dec 2025 10:19:32 -0800 Subject: [PATCH 7/8] added decorator to main.tsp and local test --- .../Generated/AnimalOperations.RestClient.cs | 45 + .../src/Generated/AnimalOperations.cs | 275 ++ .../src/Generated/DogOperations.RestClient.cs | 31 + .../src/Generated/DogOperations.cs | 155 + .../Generated/Models/Animal.Serialization.cs | 159 + .../src/Generated/Models/Animal.cs | 45 + .../src/Generated/Models/Dog.Serialization.cs | 162 + .../SampleClient/src/Generated/Models/Dog.cs | 40 + .../src/Generated/Models/Pet.Serialization.cs | 129 + .../SampleClient/src/Generated/Models/Pet.cs | 37 + .../Generated/Models/SampleTypeSpecContext.cs | 5 + .../Models/UnknownAnimal.Serialization.cs | 128 + .../src/Generated/Models/UnknownAnimal.cs | 20 + .../Models/UnknownPet.Serialization.cs | 134 + .../src/Generated/Models/UnknownPet.cs | 21 + .../src/Generated/PetOperations.RestClient.cs | 45 + .../src/Generated/PetOperations.cs | 275 ++ .../src/Generated/SampleTypeSpecClient.cs | 21 + .../Generated/SampleTypeSpecModelFactory.cs | 31 + .../client/csharp/SampleService/main.tsp | 68 + .../Local.Tests/HierarchyBuildingTests.cs | 223 ++ .../Generated/AnimalOperations.RestClient.cs | 48 + .../src/Generated/AnimalOperations.cs | 174 + .../src/Generated/DogOperations.RestClient.cs | 34 + .../src/Generated/DogOperations.cs | 106 + .../Generated/Models/Animal.Serialization.cs | 162 + .../src/Generated/Models/Animal.cs | 48 + .../src/Generated/Models/Dog.Serialization.cs | 165 + .../src/Generated/Models/Dog.cs | 43 + .../src/Generated/Models/Pet.Serialization.cs | 132 + .../src/Generated/Models/Pet.cs | 49 + .../Generated/Models/SampleTypeSpecContext.cs | 5 + .../Models/UnknownAnimal.Serialization.cs | 131 + .../src/Generated/Models/UnknownAnimal.cs | 23 + .../Models/UnknownPet.Serialization.cs | 137 + .../src/Generated/Models/UnknownPet.cs | 24 + .../src/Generated/PetOperations.RestClient.cs | 48 + .../src/Generated/PetOperations.cs | 174 + .../src/Generated/SampleTypeSpecClient.cs | 21 + .../Generated/SampleTypeSpecModelFactory.cs | 31 + .../Local/Sample-TypeSpec/tspCodeModel.json | 2818 ++++++++++++----- 41 files changed, 5676 insertions(+), 746 deletions(-) create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/AnimalOperations.RestClient.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/AnimalOperations.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/DogOperations.RestClient.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/DogOperations.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Animal.Serialization.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Animal.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Dog.Serialization.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Dog.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Pet.Serialization.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Pet.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownAnimal.Serialization.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownAnimal.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownPet.Serialization.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownPet.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/PetOperations.RestClient.cs create mode 100644 docs/samples/client/csharp/SampleService/SampleClient/src/Generated/PetOperations.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local.Tests/HierarchyBuildingTests.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/AnimalOperations.RestClient.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/AnimalOperations.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DogOperations.RestClient.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DogOperations.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownAnimal.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownAnimal.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownPet.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownPet.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/PetOperations.RestClient.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/PetOperations.cs diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/AnimalOperations.RestClient.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/AnimalOperations.RestClient.cs new file mode 100644 index 00000000000..5798e0deb91 --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/AnimalOperations.RestClient.cs @@ -0,0 +1,45 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace SampleTypeSpec +{ + /// + public partial class AnimalOperations + { + private static PipelineMessageClassifier _pipelineMessageClassifier200; + + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 = PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); + + internal PipelineMessage CreateUpdatePetAsAnimalRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/animals/pet/as-animal", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "PUT", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateUpdateDogAsAnimalRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/animals/dog/as-animal", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "PUT", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/AnimalOperations.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/AnimalOperations.cs new file mode 100644 index 00000000000..39ba0f88e01 --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/AnimalOperations.cs @@ -0,0 +1,275 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading; +using System.Threading.Tasks; + +namespace SampleTypeSpec +{ + /// The AnimalOperations sub-client. + public partial class AnimalOperations + { + private readonly Uri _endpoint; + + /// Initializes a new instance of AnimalOperations for mocking. + protected AnimalOperations() + { + } + + /// Initializes a new instance of AnimalOperations. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// Service endpoint. + internal AnimalOperations(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } + + /// + /// [Protocol Method] Update a pet as an animal + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult UpdatePetAsAnimal(BinaryContent content, RequestOptions options = null) + { + try + { + System.Console.WriteLine("Entering method UpdatePetAsAnimal."); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdatePetAsAnimalRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdatePetAsAnimal: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdatePetAsAnimal."); + } + } + + /// + /// [Protocol Method] Update a pet as an animal + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task UpdatePetAsAnimalAsync(BinaryContent content, RequestOptions options = null) + { + try + { + System.Console.WriteLine("Entering method UpdatePetAsAnimalAsync."); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdatePetAsAnimalRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdatePetAsAnimalAsync: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdatePetAsAnimalAsync."); + } + } + + /// Update a pet as an animal. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult UpdatePetAsAnimal(Animal animal, CancellationToken cancellationToken = default) + { + try + { + System.Console.WriteLine("Entering method UpdatePetAsAnimal."); + Argument.AssertNotNull(animal, nameof(animal)); + + ClientResult result = UpdatePetAsAnimal(animal, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return ClientResult.FromValue((Animal)result, result.GetRawResponse()); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdatePetAsAnimal: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdatePetAsAnimal."); + } + } + + /// Update a pet as an animal. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> UpdatePetAsAnimalAsync(Animal animal, CancellationToken cancellationToken = default) + { + try + { + System.Console.WriteLine("Entering method UpdatePetAsAnimalAsync."); + Argument.AssertNotNull(animal, nameof(animal)); + + ClientResult result = await UpdatePetAsAnimalAsync(animal, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return ClientResult.FromValue((Animal)result, result.GetRawResponse()); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdatePetAsAnimalAsync: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdatePetAsAnimalAsync."); + } + } + + /// + /// [Protocol Method] Update a dog as an animal + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult UpdateDogAsAnimal(BinaryContent content, RequestOptions options = null) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsAnimal."); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsAnimalRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsAnimal: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsAnimal."); + } + } + + /// + /// [Protocol Method] Update a dog as an animal + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task UpdateDogAsAnimalAsync(BinaryContent content, RequestOptions options = null) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsAnimalAsync."); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsAnimalRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsAnimalAsync: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsAnimalAsync."); + } + } + + /// Update a dog as an animal. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult UpdateDogAsAnimal(Animal animal, CancellationToken cancellationToken = default) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsAnimal."); + Argument.AssertNotNull(animal, nameof(animal)); + + ClientResult result = UpdateDogAsAnimal(animal, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return ClientResult.FromValue((Animal)result, result.GetRawResponse()); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsAnimal: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsAnimal."); + } + } + + /// Update a dog as an animal. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> UpdateDogAsAnimalAsync(Animal animal, CancellationToken cancellationToken = default) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsAnimalAsync."); + Argument.AssertNotNull(animal, nameof(animal)); + + ClientResult result = await UpdateDogAsAnimalAsync(animal, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return ClientResult.FromValue((Animal)result, result.GetRawResponse()); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsAnimalAsync: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsAnimalAsync."); + } + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/DogOperations.RestClient.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/DogOperations.RestClient.cs new file mode 100644 index 00000000000..3b628c186da --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/DogOperations.RestClient.cs @@ -0,0 +1,31 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace SampleTypeSpec +{ + /// + public partial class DogOperations + { + private static PipelineMessageClassifier _pipelineMessageClassifier200; + + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 = PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); + + internal PipelineMessage CreateUpdateDogAsDogRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/dogs/dog/as-dog", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "PUT", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/DogOperations.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/DogOperations.cs new file mode 100644 index 00000000000..553adb576a1 --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/DogOperations.cs @@ -0,0 +1,155 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading; +using System.Threading.Tasks; + +namespace SampleTypeSpec +{ + /// The DogOperations sub-client. + public partial class DogOperations + { + private readonly Uri _endpoint; + + /// Initializes a new instance of DogOperations for mocking. + protected DogOperations() + { + } + + /// Initializes a new instance of DogOperations. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// Service endpoint. + internal DogOperations(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } + + /// + /// [Protocol Method] Update a dog as a dog + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult UpdateDogAsDog(BinaryContent content, RequestOptions options = null) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsDog."); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsDogRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsDog: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsDog."); + } + } + + /// + /// [Protocol Method] Update a dog as a dog + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task UpdateDogAsDogAsync(BinaryContent content, RequestOptions options = null) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsDogAsync."); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsDogRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsDogAsync: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsDogAsync."); + } + } + + /// Update a dog as a dog. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult UpdateDogAsDog(Dog dog, CancellationToken cancellationToken = default) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsDog."); + Argument.AssertNotNull(dog, nameof(dog)); + + ClientResult result = UpdateDogAsDog(dog, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return ClientResult.FromValue((Dog)result, result.GetRawResponse()); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsDog: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsDog."); + } + } + + /// Update a dog as a dog. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> UpdateDogAsDogAsync(Dog dog, CancellationToken cancellationToken = default) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsDogAsync."); + Argument.AssertNotNull(dog, nameof(dog)); + + ClientResult result = await UpdateDogAsDogAsync(dog, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return ClientResult.FromValue((Dog)result, result.GetRawResponse()); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsDogAsync: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsDogAsync."); + } + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Animal.Serialization.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Animal.Serialization.cs new file mode 100644 index 00000000000..4b8a05c0640 --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Animal.Serialization.cs @@ -0,0 +1,159 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace SampleTypeSpec +{ + /// + /// Base animal with discriminator + /// Please note this is the abstract base class. The derived classes available for instantiation are: and . + /// + [PersistableModelProxy(typeof(UnknownAnimal))] + public abstract partial class Animal : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal Animal() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Animal)} does not support writing '{format}' format."); + } + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind); + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + 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 + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + Animal IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual Animal JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Animal)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAnimal(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static Animal DeserializeAnimal(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("kind"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "pet": + return Pet.DeserializePet(element, options); + case "dog": + return Dog.DeserializeDog(element, options); + } + } + return UnknownAnimal.DeserializeUnknownAnimal(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default); + default: + throw new FormatException($"The model {nameof(Animal)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + Animal IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string 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 reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// The to serialize into . + public static implicit operator BinaryContent(Animal animal) + { + if (animal == null) + { + return null; + } + return BinaryContent.Create(animal, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator Animal(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeAnimal(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Animal.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Animal.cs new file mode 100644 index 00000000000..95a223d3cac --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Animal.cs @@ -0,0 +1,45 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + /// + /// Base animal with discriminator + /// Please note this is the abstract base class. The derived classes available for instantiation are: and . + /// + public abstract partial class Animal + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + private protected Animal(string kind, string name) + { + Kind = kind; + Name = name; + } + + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Keeps track of any properties unknown to the library. + internal Animal(string kind, string name, IDictionary additionalBinaryDataProperties) + { + Kind = kind; + Name = name; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The kind of animal. + internal string Kind { get; set; } + + /// Name of the animal. + public string Name { get; set; } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Dog.Serialization.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Dog.Serialization.cs new file mode 100644 index 00000000000..7d2e62bb48a --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Dog.Serialization.cs @@ -0,0 +1,162 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace SampleTypeSpec +{ + /// Dog is a specific type of pet with hierarchy building. + public partial class Dog : Pet, IJsonModel + { + /// Initializes a new instance of for deserialization. + internal Dog() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Dog)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("breed"u8); + writer.WriteStringValue(Breed); + } + + /// The JSON reader. + /// The client options for reading and writing models. + Dog IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (Dog)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override Animal JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Dog)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDog(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static Dog DeserializeDog(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string kind = "dog"; + string name = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + bool trained = default; + string breed = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("kind"u8)) + { + kind = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("trained"u8)) + { + trained = prop.Value.GetBoolean(); + continue; + } + if (prop.NameEquals("breed"u8)) + { + breed = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new Dog(kind, name, additionalBinaryDataProperties, trained, breed); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default); + default: + throw new FormatException($"The model {nameof(Dog)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + Dog IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (Dog)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string 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 reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// The to serialize into . + public static implicit operator BinaryContent(Dog dog) + { + if (dog == null) + { + return null; + } + return BinaryContent.Create(dog, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator Dog(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeDog(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Dog.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Dog.cs new file mode 100644 index 00000000000..29fc705738f --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Dog.cs @@ -0,0 +1,40 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + /// Dog is a specific type of pet with hierarchy building. + public partial class Dog : Pet + { + /// Initializes a new instance of . + /// Name of the animal. + /// Whether the pet is trained. + /// The breed of the dog. + /// or is null. + public Dog(string name, bool trained, string breed) : base(name, trained) + { + Argument.AssertNotNull(name, nameof(name)); + Argument.AssertNotNull(breed, nameof(breed)); + + Breed = breed; + } + + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Keeps track of any properties unknown to the library. + /// Whether the pet is trained. + /// The breed of the dog. + internal Dog(string kind, string name, IDictionary additionalBinaryDataProperties, bool trained, string breed) : base(kind, name, additionalBinaryDataProperties, trained) + { + Breed = breed; + } + + /// The breed of the dog. + public string Breed { get; set; } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Pet.Serialization.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Pet.Serialization.cs new file mode 100644 index 00000000000..1102daad746 --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Pet.Serialization.cs @@ -0,0 +1,129 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace SampleTypeSpec +{ + /// Pet is a discriminated animal. + public partial class Pet : Animal, IJsonModel + { + /// Initializes a new instance of for deserialization. + internal Pet() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("trained"u8); + writer.WriteBooleanValue(Trained); + } + + /// The JSON reader. + /// The client options for reading and writing models. + Pet IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (Pet)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override Animal JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePet(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static Pet DeserializePet(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + return UnknownPet.DeserializeUnknownPet(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default); + default: + throw new FormatException($"The model {nameof(Pet)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + Pet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (Pet)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string 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 reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// The to serialize into . + public static implicit operator BinaryContent(Pet pet) + { + if (pet == null) + { + return null; + } + return BinaryContent.Create(pet, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator Pet(ClientResult result) + { + using PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializePet(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Pet.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Pet.cs new file mode 100644 index 00000000000..fd7e8130718 --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/Pet.cs @@ -0,0 +1,37 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + /// Pet is a discriminated animal. + public partial class Pet : Animal + { + /// Initializes a new instance of . + /// Name of the animal. + /// Whether the pet is trained. + /// is null. + public Pet(string name, bool trained) : base("pet", name) + { + Argument.AssertNotNull(name, nameof(name)); + + Trained = trained; + } + + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Keeps track of any properties unknown to the library. + /// Whether the pet is trained. + internal Pet(string kind, string name, IDictionary additionalBinaryDataProperties, bool trained) : base(kind, name, additionalBinaryDataProperties) + { + Trained = trained; + } + + /// Whether the pet is trained. + public bool Trained { get; set; } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/SampleTypeSpecContext.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/SampleTypeSpecContext.cs index ca0a9f6991a..acbd82d2f33 100644 --- a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/SampleTypeSpecContext.cs +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/SampleTypeSpecContext.cs @@ -10,7 +10,9 @@ namespace SampleTypeSpec /// Context class which will be filled in by the System.ClientModel.SourceGeneration. /// For more information /// + [ModelReaderWriterBuildable(typeof(Animal))] [ModelReaderWriterBuildable(typeof(AnotherDynamicModel))] + [ModelReaderWriterBuildable(typeof(Dog))] [ModelReaderWriterBuildable(typeof(DynamicModel))] [ModelReaderWriterBuildable(typeof(Friend))] [ModelReaderWriterBuildable(typeof(GetWidgetMetricsResponse))] @@ -21,10 +23,13 @@ namespace SampleTypeSpec [ModelReaderWriterBuildable(typeof(ModelWithEmbeddedNonBodyParameters))] [ModelReaderWriterBuildable(typeof(ModelWithRequiredNullableProperties))] [ModelReaderWriterBuildable(typeof(PageThing))] + [ModelReaderWriterBuildable(typeof(Pet))] [ModelReaderWriterBuildable(typeof(RenamedModel))] [ModelReaderWriterBuildable(typeof(ReturnsAnonymousModelResponse))] [ModelReaderWriterBuildable(typeof(RoundTripModel))] [ModelReaderWriterBuildable(typeof(Thing))] + [ModelReaderWriterBuildable(typeof(UnknownAnimal))] + [ModelReaderWriterBuildable(typeof(UnknownPet))] public partial class SampleTypeSpecContext : ModelReaderWriterContext { } diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownAnimal.Serialization.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownAnimal.Serialization.cs new file mode 100644 index 00000000000..e00de335fb2 --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownAnimal.Serialization.cs @@ -0,0 +1,128 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace SampleTypeSpec +{ + internal partial class UnknownAnimal : Animal, IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownAnimal() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Animal)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + Animal IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override Animal JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Animal)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAnimal(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownAnimal DeserializeUnknownAnimal(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string kind = "unknown"; + string name = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("kind"u8)) + { + kind = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownAnimal(kind, name, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default); + default: + throw new FormatException($"The model {nameof(Animal)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + Animal IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string 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 reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownAnimal.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownAnimal.cs new file mode 100644 index 00000000000..6b283549666 --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownAnimal.cs @@ -0,0 +1,20 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + internal partial class UnknownAnimal : Animal + { + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Keeps track of any properties unknown to the library. + internal UnknownAnimal(string kind, string name, IDictionary additionalBinaryDataProperties) : base(kind ?? "unknown", name, additionalBinaryDataProperties) + { + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownPet.Serialization.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownPet.Serialization.cs new file mode 100644 index 00000000000..59f22d181dc --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownPet.Serialization.cs @@ -0,0 +1,134 @@ +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace SampleTypeSpec +{ + internal partial class UnknownPet : Pet, IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownPet() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + Pet IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (UnknownPet)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override Animal JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePet(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownPet DeserializeUnknownPet(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string kind = "unknown"; + string name = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + bool trained = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("kind"u8)) + { + kind = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("trained"u8)) + { + trained = prop.Value.GetBoolean(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownPet(kind, name, additionalBinaryDataProperties, trained); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default); + default: + throw new FormatException($"The model {nameof(Pet)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + Pet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (UnknownPet)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string 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 reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownPet.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownPet.cs new file mode 100644 index 00000000000..d0cd927230b --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/UnknownPet.cs @@ -0,0 +1,21 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + internal partial class UnknownPet : Pet + { + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Keeps track of any properties unknown to the library. + /// Whether the pet is trained. + internal UnknownPet(string kind, string name, IDictionary additionalBinaryDataProperties, bool trained) : base(kind ?? "unknown", name, additionalBinaryDataProperties, trained) + { + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/PetOperations.RestClient.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/PetOperations.RestClient.cs new file mode 100644 index 00000000000..e39efd2c1cf --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/PetOperations.RestClient.cs @@ -0,0 +1,45 @@ +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace SampleTypeSpec +{ + /// + public partial class PetOperations + { + private static PipelineMessageClassifier _pipelineMessageClassifier200; + + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 = PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); + + internal PipelineMessage CreateUpdatePetAsPetRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/pets/pet/as-pet", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "PUT", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateUpdateDogAsPetRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/pets/dog/as-pet", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "PUT", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/PetOperations.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/PetOperations.cs new file mode 100644 index 00000000000..2a60348d6b5 --- /dev/null +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/PetOperations.cs @@ -0,0 +1,275 @@ +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading; +using System.Threading.Tasks; + +namespace SampleTypeSpec +{ + /// The PetOperations sub-client. + public partial class PetOperations + { + private readonly Uri _endpoint; + + /// Initializes a new instance of PetOperations for mocking. + protected PetOperations() + { + } + + /// Initializes a new instance of PetOperations. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// Service endpoint. + internal PetOperations(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } + + /// + /// [Protocol Method] Update a pet as a pet + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult UpdatePetAsPet(BinaryContent content, RequestOptions options = null) + { + try + { + System.Console.WriteLine("Entering method UpdatePetAsPet."); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdatePetAsPetRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdatePetAsPet: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdatePetAsPet."); + } + } + + /// + /// [Protocol Method] Update a pet as a pet + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task UpdatePetAsPetAsync(BinaryContent content, RequestOptions options = null) + { + try + { + System.Console.WriteLine("Entering method UpdatePetAsPetAsync."); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdatePetAsPetRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdatePetAsPetAsync: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdatePetAsPetAsync."); + } + } + + /// Update a pet as a pet. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult UpdatePetAsPet(Pet pet, CancellationToken cancellationToken = default) + { + try + { + System.Console.WriteLine("Entering method UpdatePetAsPet."); + Argument.AssertNotNull(pet, nameof(pet)); + + ClientResult result = UpdatePetAsPet(pet, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return ClientResult.FromValue((Pet)result, result.GetRawResponse()); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdatePetAsPet: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdatePetAsPet."); + } + } + + /// Update a pet as a pet. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> UpdatePetAsPetAsync(Pet pet, CancellationToken cancellationToken = default) + { + try + { + System.Console.WriteLine("Entering method UpdatePetAsPetAsync."); + Argument.AssertNotNull(pet, nameof(pet)); + + ClientResult result = await UpdatePetAsPetAsync(pet, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return ClientResult.FromValue((Pet)result, result.GetRawResponse()); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdatePetAsPetAsync: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdatePetAsPetAsync."); + } + } + + /// + /// [Protocol Method] Update a dog as a pet + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult UpdateDogAsPet(BinaryContent content, RequestOptions options = null) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsPet."); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsPetRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsPet: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsPet."); + } + } + + /// + /// [Protocol Method] Update a dog as a pet + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task UpdateDogAsPetAsync(BinaryContent content, RequestOptions options = null) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsPetAsync."); + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsPetRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsPetAsync: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsPetAsync."); + } + } + + /// Update a dog as a pet. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult UpdateDogAsPet(Pet pet, CancellationToken cancellationToken = default) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsPet."); + Argument.AssertNotNull(pet, nameof(pet)); + + ClientResult result = UpdateDogAsPet(pet, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null); + return ClientResult.FromValue((Pet)result, result.GetRawResponse()); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsPet: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsPet."); + } + } + + /// Update a dog as a pet. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> UpdateDogAsPetAsync(Pet pet, CancellationToken cancellationToken = default) + { + try + { + System.Console.WriteLine("Entering method UpdateDogAsPetAsync."); + Argument.AssertNotNull(pet, nameof(pet)); + + ClientResult result = await UpdateDogAsPetAsync(pet, cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return ClientResult.FromValue((Pet)result, result.GetRawResponse()); + } + catch (Exception ex) + { + System.Console.WriteLine($"An exception was thrown in method UpdateDogAsPetAsync: {ex}"); + throw; + } + finally + { + System.Console.WriteLine("Exiting method UpdateDogAsPetAsync."); + } + } + } +} diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.cs index 243a0d06d09..812e2900259 100644 --- a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.cs +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.cs @@ -32,6 +32,9 @@ public partial class SampleTypeSpecClient } }; private readonly string _apiVersion; + private AnimalOperations _cachedAnimalOperations; + private PetOperations _cachedPetOperations; + private DogOperations _cachedDogOperations; private Metrics _cachedMetrics; /// Initializes a new instance of SampleTypeSpecClient for mocking. @@ -3008,6 +3011,24 @@ public virtual async Task DynamicModelOperationAsync(DynamicModel } } + /// Initializes a new instance of AnimalOperations. + public virtual AnimalOperations GetAnimalOperationsClient() + { + return Volatile.Read(ref _cachedAnimalOperations) ?? Interlocked.CompareExchange(ref _cachedAnimalOperations, new AnimalOperations(Pipeline, _endpoint), null) ?? _cachedAnimalOperations; + } + + /// Initializes a new instance of PetOperations. + public virtual PetOperations GetPetOperationsClient() + { + return Volatile.Read(ref _cachedPetOperations) ?? Interlocked.CompareExchange(ref _cachedPetOperations, new PetOperations(Pipeline, _endpoint), null) ?? _cachedPetOperations; + } + + /// Initializes a new instance of DogOperations. + public virtual DogOperations GetDogOperationsClient() + { + return Volatile.Read(ref _cachedDogOperations) ?? Interlocked.CompareExchange(ref _cachedDogOperations, new DogOperations(Pipeline, _endpoint), null) ?? _cachedDogOperations; + } + /// Initializes a new instance of Metrics. public virtual Metrics GetMetricsClient() { diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecModelFactory.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecModelFactory.cs index 2d1f276ad6d..370465cb29d 100644 --- a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecModelFactory.cs +++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecModelFactory.cs @@ -230,6 +230,37 @@ public static AnotherDynamicModel AnotherDynamicModel(string bar = default) return new AnotherDynamicModel(bar, additionalBinaryDataProperties: null); } + /// + /// Base animal with discriminator + /// Please note this is the abstract base class. The derived classes available for instantiation are: and . + /// + /// The kind of animal. + /// Name of the animal. + /// A new instance for mocking. + public static Animal Animal(string kind = default, string name = default) + { + return new UnknownAnimal(kind, name, additionalBinaryDataProperties: null); + } + + /// Pet is a discriminated animal. + /// Name of the animal. + /// Whether the pet is trained. + /// A new instance for mocking. + public static Pet Pet(string name = default, bool trained = default) + { + return new Pet("pet", name, additionalBinaryDataProperties: null, trained); + } + + /// Dog is a specific type of pet with hierarchy building. + /// Name of the animal. + /// Whether the pet is trained. + /// The breed of the dog. + /// A new instance for mocking. + public static Dog Dog(string name = default, bool trained = default, string breed = default) + { + return new Dog("pet", name, additionalBinaryDataProperties: null, trained, breed); + } + /// The GetWidgetMetricsResponse. /// /// diff --git a/docs/samples/client/csharp/SampleService/main.tsp b/docs/samples/client/csharp/SampleService/main.tsp index 6352a85e816..3a6a1e6e254 100644 --- a/docs/samples/client/csharp/SampleService/main.tsp +++ b/docs/samples/client/csharp/SampleService/main.tsp @@ -502,6 +502,74 @@ op EmbeddedParameters(@bodyRoot body: ModelWithEmbeddedNonBodyParameters): void; @post op DynamicModelOperation(@body body: DynamicModel): void; +@doc("Base animal with discriminator") +@discriminator("kind") +model Animal { + @doc("The kind of animal") + kind: string; + + @doc("Name of the animal") + name: string; +} + +alias PetContent = { + @doc("Whether the pet is trained") + trained: boolean; +}; + +@doc("Pet is a discriminated animal") +model Pet extends Animal { + kind: "pet"; + ...PetContent; +} + +alias DogContent = { + @doc("The breed of the dog") + breed: string; +}; + +@doc("Dog is a specific type of pet with hierarchy building") +@Legacy.hierarchyBuilding(Pet) +model Dog extends Animal { + kind: "dog"; + ...PetContent; + ...DogContent; +} + +@route("/animals") +interface AnimalOperations { + @doc("Update a pet as an animal") + @put + @route("/pet/as-animal") + updatePetAsAnimal(@body animal: Animal): Animal; + + @doc("Update a dog as an animal") + @put + @route("/dog/as-animal") + updateDogAsAnimal(@body animal: Animal): Animal; +} + +@route("/pets") +interface PetOperations { + @doc("Update a pet as a pet") + @put + @route("/pet/as-pet") + updatePetAsPet(@body pet: Pet): Pet; + + @doc("Update a dog as a pet") + @put + @route("/dog/as-pet") + updateDogAsPet(@body pet: Pet): Pet; +} + +@route("/dogs") +interface DogOperations { + @doc("Update a dog as a dog") + @put + @route("/dog/as-dog") + updateDogAsDog(@body dog: Dog): Dog; +} + @clientInitialization({ initializedBy: InitializedBy.individually | InitializedBy.parent, }) diff --git a/packages/http-client-csharp/generator/TestProjects/Local.Tests/HierarchyBuildingTests.cs b/packages/http-client-csharp/generator/TestProjects/Local.Tests/HierarchyBuildingTests.cs new file mode 100644 index 00000000000..4caacf9d9a4 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local.Tests/HierarchyBuildingTests.cs @@ -0,0 +1,223 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Linq; +using System.Reflection; +using NUnit.Framework; +using SampleTypeSpec; + +namespace TestProjects.Local.Tests +{ + public class HierarchyBuildingTests + { + [Test] + public void DogExtendsIntermediatePetModel() + { + // Verify that Dog extends Pet (not Animal directly) due to @Legacy.hierarchyBuilding(Pet) + var dogType = typeof(Dog); + var baseType = dogType.BaseType; + + Assert.IsNotNull(baseType); + Assert.AreEqual("Pet", baseType!.Name); + } + + [Test] + public void DogHasPropertiesFromBothAnimalAndPet() + { + // Verify Dog has all properties from the hierarchy + var dogType = typeof(Dog); + + // From Animal (public) + var nameProperty = dogType.GetProperty("Name", BindingFlags.Public | BindingFlags.Instance); + + // From Pet (intermediate) + var trainedProperty = dogType.GetProperty("Trained", BindingFlags.Public | BindingFlags.Instance); + + // From Dog + var breedProperty = dogType.GetProperty("Breed", BindingFlags.Public | BindingFlags.Instance); + + Assert.IsNotNull(nameProperty, "Dog should have Name property from Animal"); + Assert.IsNotNull(trainedProperty, "Dog should have Trained property from Pet"); + Assert.IsNotNull(breedProperty, "Dog should have Breed property"); + } + + [Test] + public void PetExtendsAnimal() + { + // Verify that Pet extends Animal (normal inheritance) + var petType = typeof(Pet); + var baseType = petType.BaseType; + + Assert.IsNotNull(baseType); + Assert.AreEqual("Animal", baseType!.Name); + } + + [Test] + public void AnimalIsAbstractBaseClass() + { + // Verify Animal is the abstract discriminated base + var animalType = typeof(Animal); + + Assert.IsTrue(animalType.IsAbstract, "Animal should be abstract"); + Assert.IsTrue(animalType.IsClass, "Animal should be a class"); + } + + [Test] + public void DogInheritsFromPetNotAnimalDirectly() + { + // This is the key test for hierarchy building - Dog -> Pet -> Animal + var dogType = typeof(Dog); + var petType = typeof(Pet); + var animalType = typeof(Animal); + + // Dog's immediate base should be Pet + Assert.AreEqual(petType, dogType.BaseType, "Dog should directly extend Pet"); + + // Pet's immediate base should be Animal + Assert.AreEqual(animalType, petType.BaseType, "Pet should directly extend Animal"); + + // Dog should be assignable to both Pet and Animal + Assert.IsTrue(petType.IsAssignableFrom(dogType), "Dog should be assignable to Pet"); + Assert.IsTrue(animalType.IsAssignableFrom(dogType), "Dog should be assignable to Animal"); + } + + [Test] + public void AnimalOperationsClientExists() + { + // Verify AnimalOperations client is generated + var clientType = typeof(SampleTypeSpecClient); + var getAnimalOpsMethod = clientType.GetMethod("GetAnimalOperationsClient"); + + Assert.IsNotNull(getAnimalOpsMethod, "Client should have GetAnimalOperationsClient() method"); + Assert.AreEqual("AnimalOperations", getAnimalOpsMethod!.ReturnType.Name); + } + + [Test] + public void PetOperationsClientExists() + { + // Verify PetOperations client is generated + var clientType = typeof(SampleTypeSpecClient); + var getPetOpsMethod = clientType.GetMethod("GetPetOperationsClient"); + + Assert.IsNotNull(getPetOpsMethod, "Client should have GetPetOperationsClient() method"); + Assert.AreEqual("PetOperations", getPetOpsMethod!.ReturnType.Name); + } + + [Test] + public void DogOperationsClientExists() + { + // Verify DogOperations client is generated + var clientType = typeof(SampleTypeSpecClient); + var getDogOpsMethod = clientType.GetMethod("GetDogOperationsClient"); + + Assert.IsNotNull(getDogOpsMethod, "Client should have GetDogOperationsClient() method"); + Assert.AreEqual("DogOperations", getDogOpsMethod!.ReturnType.Name); + } + + [Test] + public void UpdateDogAsAnimalOperationExists() + { + // Verify UpdateDogAsAnimal operation exists and accepts Animal parameter + var animalOpsType = typeof(SampleTypeSpecClient).Assembly.GetType("SampleTypeSpec.AnimalOperations"); + Assert.IsNotNull(animalOpsType, "AnimalOperations type should exist"); + + var updateDogMethod = animalOpsType!.GetMethods() + .FirstOrDefault(m => m.Name == "UpdateDogAsAnimal" || m.Name == "UpdateDogAsAnimalAsync"); + + Assert.IsNotNull(updateDogMethod, "UpdateDogAsAnimal operation should exist"); + } + + [Test] + public void UpdatePetAsAnimalOperationExists() + { + // Verify UpdatePetAsAnimal operation exists and accepts Animal parameter + var animalOpsType = typeof(SampleTypeSpecClient).Assembly.GetType("SampleTypeSpec.AnimalOperations"); + Assert.IsNotNull(animalOpsType, "AnimalOperations type should exist"); + + var updatePetMethod = animalOpsType!.GetMethods() + .FirstOrDefault(m => m.Name == "UpdatePetAsAnimal" || m.Name == "UpdatePetAsAnimalAsync"); + + Assert.IsNotNull(updatePetMethod, "UpdatePetAsAnimal operation should exist"); + } + + [Test] + public void UpdateDogAsPetOperationExists() + { + // Verify UpdateDogAsPet operation exists in PetOperations + var petOpsType = typeof(SampleTypeSpecClient).Assembly.GetType("SampleTypeSpec.PetOperations"); + Assert.IsNotNull(petOpsType, "PetOperations type should exist"); + + var updateDogMethod = petOpsType!.GetMethods() + .FirstOrDefault(m => m.Name == "UpdateDogAsPet" || m.Name == "UpdateDogAsPetAsync"); + + Assert.IsNotNull(updateDogMethod, "UpdateDogAsPet operation should exist"); + } + + [Test] + public void UpdateDogAsDogOperationExists() + { + // Verify UpdateDogAsDog operation exists in DogOperations + var dogOpsType = typeof(SampleTypeSpecClient).Assembly.GetType("SampleTypeSpec.DogOperations"); + Assert.IsNotNull(dogOpsType, "DogOperations type should exist"); + + var updateDogMethod = dogOpsType!.GetMethods() + .FirstOrDefault(m => m.Name == "UpdateDogAsDog" || m.Name == "UpdateDogAsDogAsync"); + + Assert.IsNotNull(updateDogMethod, "UpdateDogAsDog operation should exist"); + } + + [Test] + public void DogCanBePassedToAnimalOperation() + { + // Verify Dog instance can be used where Animal is expected (polymorphism) + Dog dog = new Dog("Rex", true, "German Shepherd"); + Animal animal = dog; // This should compile + + Assert.IsNotNull(animal); + Assert.AreEqual("Rex", animal.Name); + + // Verify the dog can be cast back + Dog? castBack = animal as Dog; + Assert.IsNotNull(castBack); + Assert.AreEqual("German Shepherd", castBack!.Breed); + } + + [Test] + public void DogCanBePassedToPetOperation() + { + // Verify Dog instance can be used where Pet is expected (polymorphism) + Dog dog = new Dog("Rex", true, "German Shepherd"); + Pet pet = dog; + + Assert.IsNotNull(pet); + Assert.AreEqual("Rex", pet.Name); + Assert.IsTrue(pet.Trained); + + // Verify the dog can be cast back + Dog? castBack = pet as Dog; + Assert.IsNotNull(castBack); + Assert.AreEqual("German Shepherd", castBack!.Breed); + } + + [Test] + public void AllHierarchyLevelsHaveCorrectProperties() + { + // Create a dog and verify all properties through the hierarchy are accessible + Dog dog = new Dog("Rex", true, "German Shepherd"); + + // Access as Dog + Assert.AreEqual("Rex", dog.Name); + Assert.AreEqual("German Shepherd", dog.Breed); + Assert.IsTrue(dog.Trained); + + // Access as Pet + Pet pet = dog; + Assert.AreEqual("Rex", pet.Name); + Assert.IsTrue(pet.Trained); + + // Access as Animal + Animal animal = dog; + Assert.AreEqual("Rex", animal.Name); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/AnimalOperations.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/AnimalOperations.RestClient.cs new file mode 100644 index 00000000000..8d8d8ffdd75 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/AnimalOperations.RestClient.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace SampleTypeSpec +{ + /// + public partial class AnimalOperations + { + private static PipelineMessageClassifier _pipelineMessageClassifier200; + + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 = PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); + + internal PipelineMessage CreateUpdatePetAsAnimalRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/animals/pet/as-animal", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "PUT", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateUpdateDogAsAnimalRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/animals/dog/as-animal", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "PUT", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/AnimalOperations.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/AnimalOperations.cs new file mode 100644 index 00000000000..10d3b31fe97 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/AnimalOperations.cs @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading; +using System.Threading.Tasks; + +namespace SampleTypeSpec +{ + /// The AnimalOperations sub-client. + public partial class AnimalOperations + { + private readonly Uri _endpoint; + + /// Initializes a new instance of AnimalOperations for mocking. + protected AnimalOperations() + { + } + + /// Initializes a new instance of AnimalOperations. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// Service endpoint. + internal AnimalOperations(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } + + /// + /// [Protocol Method] Update a pet as an animal + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult UpdatePetAsAnimal(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdatePetAsAnimalRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + /// + /// [Protocol Method] Update a pet as an animal + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task UpdatePetAsAnimalAsync(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdatePetAsAnimalRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + /// Update a pet as an animal. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult UpdatePetAsAnimal(Animal animal, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(animal, nameof(animal)); + + ClientResult result = UpdatePetAsAnimal(animal, cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((Animal)result, result.GetRawResponse()); + } + + /// Update a pet as an animal. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> UpdatePetAsAnimalAsync(Animal animal, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(animal, nameof(animal)); + + ClientResult result = await UpdatePetAsAnimalAsync(animal, cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((Animal)result, result.GetRawResponse()); + } + + /// + /// [Protocol Method] Update a dog as an animal + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult UpdateDogAsAnimal(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsAnimalRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + /// + /// [Protocol Method] Update a dog as an animal + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task UpdateDogAsAnimalAsync(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsAnimalRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + /// Update a dog as an animal. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult UpdateDogAsAnimal(Animal animal, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(animal, nameof(animal)); + + ClientResult result = UpdateDogAsAnimal(animal, cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((Animal)result, result.GetRawResponse()); + } + + /// Update a dog as an animal. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> UpdateDogAsAnimalAsync(Animal animal, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(animal, nameof(animal)); + + ClientResult result = await UpdateDogAsAnimalAsync(animal, cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((Animal)result, result.GetRawResponse()); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DogOperations.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DogOperations.RestClient.cs new file mode 100644 index 00000000000..ce03fb07b17 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DogOperations.RestClient.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace SampleTypeSpec +{ + /// + public partial class DogOperations + { + private static PipelineMessageClassifier _pipelineMessageClassifier200; + + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 = PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); + + internal PipelineMessage CreateUpdateDogAsDogRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/dogs/dog/as-dog", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "PUT", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DogOperations.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DogOperations.cs new file mode 100644 index 00000000000..a45d14cb50f --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DogOperations.cs @@ -0,0 +1,106 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading; +using System.Threading.Tasks; + +namespace SampleTypeSpec +{ + /// The DogOperations sub-client. + public partial class DogOperations + { + private readonly Uri _endpoint; + + /// Initializes a new instance of DogOperations for mocking. + protected DogOperations() + { + } + + /// Initializes a new instance of DogOperations. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// Service endpoint. + internal DogOperations(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } + + /// + /// [Protocol Method] Update a dog as a dog + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult UpdateDogAsDog(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsDogRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + /// + /// [Protocol Method] Update a dog as a dog + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task UpdateDogAsDogAsync(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsDogRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + /// Update a dog as a dog. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult UpdateDogAsDog(Dog dog, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(dog, nameof(dog)); + + ClientResult result = UpdateDogAsDog(dog, cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((Dog)result, result.GetRawResponse()); + } + + /// Update a dog as a dog. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> UpdateDogAsDogAsync(Dog dog, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(dog, nameof(dog)); + + ClientResult result = await UpdateDogAsDogAsync(dog, cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((Dog)result, result.GetRawResponse()); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs new file mode 100644 index 00000000000..36d704a717f --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs @@ -0,0 +1,162 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace SampleTypeSpec +{ + /// + /// Base animal with discriminator + /// Please note this is the abstract base class. The derived classes available for instantiation are: and . + /// + [PersistableModelProxy(typeof(UnknownAnimal))] + public abstract partial class Animal : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal Animal() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Animal)} does not support writing '{format}' format."); + } + writer.WritePropertyName("kind"u8); + writer.WriteStringValue(Kind); + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + 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 + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + Animal IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual Animal JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Animal)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAnimal(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static Animal DeserializeAnimal(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("kind"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "pet": + return Pet.DeserializePet(element, options); + case "dog": + return Dog.DeserializeDog(element, options); + } + } + return UnknownAnimal.DeserializeUnknownAnimal(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default); + default: + throw new FormatException($"The model {nameof(Animal)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + Animal IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) + { + return DeserializeAnimal(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Animal)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// The to serialize into . + public static implicit operator BinaryContent(Animal animal) + { + if (animal == null) + { + return null; + } + return BinaryContent.Create(animal, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator Animal(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); + return DeserializeAnimal(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.cs new file mode 100644 index 00000000000..9843416b0e4 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + /// + /// Base animal with discriminator + /// Please note this is the abstract base class. The derived classes available for instantiation are: and . + /// + public abstract partial class Animal + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + private protected Animal(string kind, string name) + { + Kind = kind; + Name = name; + } + + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Keeps track of any properties unknown to the library. + internal Animal(string kind, string name, IDictionary additionalBinaryDataProperties) + { + Kind = kind; + Name = name; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The kind of animal. + internal string Kind { get; set; } + + /// Name of the animal. + public string Name { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.Serialization.cs new file mode 100644 index 00000000000..470450f2c6e --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.Serialization.cs @@ -0,0 +1,165 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace SampleTypeSpec +{ + /// Dog is a specific type of pet with hierarchy building. + public partial class Dog : Pet, IJsonModel + { + /// Initializes a new instance of for deserialization. + internal Dog() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Dog)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("breed"u8); + writer.WriteStringValue(Breed); + } + + /// The JSON reader. + /// The client options for reading and writing models. + Dog IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (Dog)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override Animal JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Dog)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeDog(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static Dog DeserializeDog(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string kind = "dog"; + string name = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + bool trained = default; + string breed = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("kind"u8)) + { + kind = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("trained"u8)) + { + trained = prop.Value.GetBoolean(); + continue; + } + if (prop.NameEquals("breed"u8)) + { + breed = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new Dog(kind, name, additionalBinaryDataProperties, trained, breed); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default); + default: + throw new FormatException($"The model {nameof(Dog)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + Dog IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (Dog)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) + { + return DeserializeDog(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Dog)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// The to serialize into . + public static implicit operator BinaryContent(Dog dog) + { + if (dog == null) + { + return null; + } + return BinaryContent.Create(dog, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator Dog(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); + return DeserializeDog(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.cs new file mode 100644 index 00000000000..d421fa5094d --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + /// Dog is a specific type of pet with hierarchy building. + public partial class Dog : Pet + { + /// Initializes a new instance of . + /// Name of the animal. + /// Whether the pet is trained. + /// The breed of the dog. + /// or is null. + public Dog(string name, bool trained, string breed) : base("dog", name, trained) + { + Argument.AssertNotNull(name, nameof(name)); + Argument.AssertNotNull(breed, nameof(breed)); + + Breed = breed; + } + + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Keeps track of any properties unknown to the library. + /// Whether the pet is trained. + /// The breed of the dog. + internal Dog(string kind, string name, IDictionary additionalBinaryDataProperties, bool trained, string breed) : base(kind, name, additionalBinaryDataProperties, trained) + { + Breed = breed; + } + + /// The breed of the dog. + public string Breed { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.Serialization.cs new file mode 100644 index 00000000000..d6002edfbc6 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.Serialization.cs @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace SampleTypeSpec +{ + /// Pet is a discriminated animal. + public partial class Pet : Animal, IJsonModel + { + /// Initializes a new instance of for deserialization. + internal Pet() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("trained"u8); + writer.WriteBooleanValue(Trained); + } + + /// The JSON reader. + /// The client options for reading and writing models. + Pet IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (Pet)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override Animal JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePet(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static Pet DeserializePet(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + return UnknownPet.DeserializeUnknownPet(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default); + default: + throw new FormatException($"The model {nameof(Pet)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + Pet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (Pet)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) + { + return DeserializePet(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Pet)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// The to serialize into . + public static implicit operator BinaryContent(Pet pet) + { + if (pet == null) + { + return null; + } + return BinaryContent.Create(pet, ModelSerializationExtensions.WireOptions); + } + + /// The to deserialize the from. + public static explicit operator Pet(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); + return DeserializePet(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.cs new file mode 100644 index 00000000000..b91fc297ad0 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + /// Pet is a discriminated animal. + public partial class Pet : Animal + { + /// Initializes a new instance of . + /// Name of the animal. + /// Whether the pet is trained. + /// is null. + public Pet(string name, bool trained) : base("pet", name) + { + Argument.AssertNotNull(name, nameof(name)); + + Trained = trained; + } + + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Keeps track of any properties unknown to the library. + /// Whether the pet is trained. + internal Pet(string kind, string name, IDictionary additionalBinaryDataProperties, bool trained) : base(kind, name, additionalBinaryDataProperties) + { + Trained = trained; + } + + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Whether the pet is trained. + private protected Pet(string kind, string name, bool trained) : base(kind, name) + { + Trained = trained; + } + + /// Whether the pet is trained. + public bool Trained { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/SampleTypeSpecContext.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/SampleTypeSpecContext.cs index 3d2c3e12a48..2a2fe6a977f 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/SampleTypeSpecContext.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/SampleTypeSpecContext.cs @@ -14,7 +14,9 @@ namespace SampleTypeSpec /// Context class which will be filled in by the System.ClientModel.SourceGeneration. /// For more information /// + [ModelReaderWriterBuildable(typeof(Animal))] [ModelReaderWriterBuildable(typeof(AnotherDynamicModel))] + [ModelReaderWriterBuildable(typeof(Dog))] [ModelReaderWriterBuildable(typeof(DynamicModel))] [ModelReaderWriterBuildable(typeof(Friend))] [ModelReaderWriterBuildable(typeof(GetWidgetMetricsResponse))] @@ -25,10 +27,13 @@ namespace SampleTypeSpec [ModelReaderWriterBuildable(typeof(ModelWithEmbeddedNonBodyParameters))] [ModelReaderWriterBuildable(typeof(ModelWithRequiredNullableProperties))] [ModelReaderWriterBuildable(typeof(PageThing))] + [ModelReaderWriterBuildable(typeof(Pet))] [ModelReaderWriterBuildable(typeof(RenamedModelCustom))] [ModelReaderWriterBuildable(typeof(ReturnsAnonymousModelResponse))] [ModelReaderWriterBuildable(typeof(RoundTripModel))] [ModelReaderWriterBuildable(typeof(Thing))] + [ModelReaderWriterBuildable(typeof(UnknownAnimal))] + [ModelReaderWriterBuildable(typeof(UnknownPet))] public partial class SampleTypeSpecContext : ModelReaderWriterContext { } diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownAnimal.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownAnimal.Serialization.cs new file mode 100644 index 00000000000..535dd928e85 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownAnimal.Serialization.cs @@ -0,0 +1,131 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace SampleTypeSpec +{ + internal partial class UnknownAnimal : Animal, IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownAnimal() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Animal)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + Animal IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override Animal JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Animal)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAnimal(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownAnimal DeserializeUnknownAnimal(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string kind = "unknown"; + string name = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("kind"u8)) + { + kind = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownAnimal(kind, name, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default); + default: + throw new FormatException($"The model {nameof(Animal)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + Animal IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) + { + return DeserializeAnimal(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Animal)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownAnimal.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownAnimal.cs new file mode 100644 index 00000000000..11b9d39207e --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownAnimal.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + internal partial class UnknownAnimal : Animal + { + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Keeps track of any properties unknown to the library. + internal UnknownAnimal(string kind, string name, IDictionary additionalBinaryDataProperties) : base(kind ?? "unknown", name, additionalBinaryDataProperties) + { + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownPet.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownPet.Serialization.cs new file mode 100644 index 00000000000..b0074ad04b3 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownPet.Serialization.cs @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace SampleTypeSpec +{ + internal partial class UnknownPet : Pet, IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownPet() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + Pet IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (UnknownPet)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override Animal JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(Pet)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializePet(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownPet DeserializeUnknownPet(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string kind = "unknown"; + string name = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + bool trained = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("kind"u8)) + { + kind = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("trained"u8)) + { + trained = prop.Value.GetBoolean(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownPet(kind, name, additionalBinaryDataProperties, trained); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default); + default: + throw new FormatException($"The model {nameof(Pet)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + Pet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (UnknownPet)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions)) + { + return DeserializePet(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(Pet)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownPet.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownPet.cs new file mode 100644 index 00000000000..a318bf4fd07 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/UnknownPet.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + internal partial class UnknownPet : Pet + { + /// Initializes a new instance of . + /// The kind of animal. + /// Name of the animal. + /// Keeps track of any properties unknown to the library. + /// Whether the pet is trained. + internal UnknownPet(string kind, string name, IDictionary additionalBinaryDataProperties, bool trained) : base(kind ?? "unknown", name, additionalBinaryDataProperties, trained) + { + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/PetOperations.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/PetOperations.RestClient.cs new file mode 100644 index 00000000000..6681f9e7d79 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/PetOperations.RestClient.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.ClientModel; +using System.ClientModel.Primitives; + +namespace SampleTypeSpec +{ + /// + public partial class PetOperations + { + private static PipelineMessageClassifier _pipelineMessageClassifier200; + + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 = PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); + + internal PipelineMessage CreateUpdatePetAsPetRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/pets/pet/as-pet", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "PUT", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + + internal PipelineMessage CreateUpdateDogAsPetRequest(BinaryContent content, RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/pets/dog/as-pet", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "PUT", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Content-Type", "application/json"); + request.Headers.Set("Accept", "application/json"); + request.Content = content; + message.Apply(options); + return message; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/PetOperations.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/PetOperations.cs new file mode 100644 index 00000000000..7f7531baa9d --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/PetOperations.cs @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading; +using System.Threading.Tasks; + +namespace SampleTypeSpec +{ + /// The PetOperations sub-client. + public partial class PetOperations + { + private readonly Uri _endpoint; + + /// Initializes a new instance of PetOperations for mocking. + protected PetOperations() + { + } + + /// Initializes a new instance of PetOperations. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// Service endpoint. + internal PetOperations(ClientPipeline pipeline, Uri endpoint) + { + _endpoint = endpoint; + Pipeline = pipeline; + } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public ClientPipeline Pipeline { get; } + + /// + /// [Protocol Method] Update a pet as a pet + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult UpdatePetAsPet(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdatePetAsPetRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + /// + /// [Protocol Method] Update a pet as a pet + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task UpdatePetAsPetAsync(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdatePetAsPetRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + /// Update a pet as a pet. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult UpdatePetAsPet(Pet pet, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(pet, nameof(pet)); + + ClientResult result = UpdatePetAsPet(pet, cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((Pet)result, result.GetRawResponse()); + } + + /// Update a pet as a pet. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> UpdatePetAsPetAsync(Pet pet, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(pet, nameof(pet)); + + ClientResult result = await UpdatePetAsPetAsync(pet, cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((Pet)result, result.GetRawResponse()); + } + + /// + /// [Protocol Method] Update a dog as a pet + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult UpdateDogAsPet(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsPetRequest(content, options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + /// + /// [Protocol Method] Update a dog as a pet + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// is null. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task UpdateDogAsPetAsync(BinaryContent content, RequestOptions options = null) + { + Argument.AssertNotNull(content, nameof(content)); + + using PipelineMessage message = CreateUpdateDogAsPetRequest(content, options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + /// Update a dog as a pet. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual ClientResult UpdateDogAsPet(Pet pet, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(pet, nameof(pet)); + + ClientResult result = UpdateDogAsPet(pet, cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((Pet)result, result.GetRawResponse()); + } + + /// Update a dog as a pet. + /// + /// The cancellation token that can be used to cancel the operation. + /// is null. + /// Service returned a non-success status code. + public virtual async Task> UpdateDogAsPetAsync(Pet pet, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(pet, nameof(pet)); + + ClientResult result = await UpdateDogAsPetAsync(pet, cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((Pet)result, result.GetRawResponse()); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecClient.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecClient.cs index c03b2d8da99..fe4644f654f 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecClient.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecClient.cs @@ -36,6 +36,9 @@ public partial class SampleTypeSpecClient } }; private readonly string _apiVersion; + private AnimalOperations _cachedAnimalOperations; + private PetOperations _cachedPetOperations; + private DogOperations _cachedDogOperations; private Metrics _cachedMetrics; /// Initializes a new instance of SampleTypeSpecClient for mocking. @@ -1720,6 +1723,24 @@ public virtual async Task DynamicModelOperationAsync(DynamicModel return await DynamicModelOperationAsync(body, cancellationToken.ToRequestOptions()).ConfigureAwait(false); } + /// Initializes a new instance of AnimalOperations. + public virtual AnimalOperations GetAnimalOperationsClient() + { + return Volatile.Read(ref _cachedAnimalOperations) ?? Interlocked.CompareExchange(ref _cachedAnimalOperations, new AnimalOperations(Pipeline, _endpoint), null) ?? _cachedAnimalOperations; + } + + /// Initializes a new instance of PetOperations. + public virtual PetOperations GetPetOperationsClient() + { + return Volatile.Read(ref _cachedPetOperations) ?? Interlocked.CompareExchange(ref _cachedPetOperations, new PetOperations(Pipeline, _endpoint), null) ?? _cachedPetOperations; + } + + /// Initializes a new instance of DogOperations. + public virtual DogOperations GetDogOperationsClient() + { + return Volatile.Read(ref _cachedDogOperations) ?? Interlocked.CompareExchange(ref _cachedDogOperations, new DogOperations(Pipeline, _endpoint), null) ?? _cachedDogOperations; + } + /// Initializes a new instance of Metrics. public virtual Metrics GetMetricsClient() { diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecModelFactory.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecModelFactory.cs index 1bee9ea6640..f16d669f0d6 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecModelFactory.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecModelFactory.cs @@ -231,6 +231,37 @@ public static AnotherDynamicModel AnotherDynamicModel(string bar = default) return new AnotherDynamicModel(bar, default); } + /// + /// Base animal with discriminator + /// Please note this is the abstract base class. The derived classes available for instantiation are: and . + /// + /// The kind of animal. + /// Name of the animal. + /// A new instance for mocking. + public static Animal Animal(string kind = default, string name = default) + { + return new UnknownAnimal(kind, name, additionalBinaryDataProperties: null); + } + + /// Pet is a discriminated animal. + /// Name of the animal. + /// Whether the pet is trained. + /// A new instance for mocking. + public static Pet Pet(string name = default, bool trained = default) + { + return new Pet("pet", name, additionalBinaryDataProperties: null, trained); + } + + /// Dog is a specific type of pet with hierarchy building. + /// Name of the animal. + /// Whether the pet is trained. + /// The breed of the dog. + /// A new instance for mocking. + public static Dog Dog(string name = default, bool trained = default, string breed = default) + { + return new Dog("pet", name, additionalBinaryDataProperties: null, trained, breed); + } + /// The GetWidgetMetricsResponse. /// /// diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/tspCodeModel.json b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/tspCodeModel.json index 84c243dbc7c..e92b37559b9 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/tspCodeModel.json +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/tspCodeModel.json @@ -879,9 +879,9 @@ { "$id": "80", "kind": "constant", - "name": "sayHiContentType", - "namespace": "", - "usage": "None", + "name": "PetKind", + "namespace": "SampleTypeSpec", + "usage": "Input,Output,Json", "valueType": { "$id": "81", "kind": "string", @@ -889,15 +889,15 @@ "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, - "value": "application/json", + "value": "pet", "decorators": [] }, { "$id": "82", "kind": "constant", - "name": "HelloAgainRequestContentType", - "namespace": "", - "usage": "None", + "name": "DogKind", + "namespace": "SampleTypeSpec", + "usage": "Input,Output,Json", "valueType": { "$id": "83", "kind": "string", @@ -905,13 +905,13 @@ "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, - "value": "text/plain", + "value": "dog", "decorators": [] }, { "$id": "84", "kind": "constant", - "name": "helloAgainContentType", + "name": "sayHiContentType", "namespace": "", "usage": "None", "valueType": { @@ -927,7 +927,7 @@ { "$id": "86", "kind": "constant", - "name": "HelloAgainRequestContentType1", + "name": "HelloAgainRequestContentType", "namespace": "", "usage": "None", "valueType": { @@ -943,7 +943,7 @@ { "$id": "88", "kind": "constant", - "name": "noContentTypeContentType", + "name": "helloAgainContentType", "namespace": "", "usage": "None", "valueType": { @@ -959,7 +959,7 @@ { "$id": "90", "kind": "constant", - "name": "noContentTypeContentType1", + "name": "HelloAgainRequestContentType1", "namespace": "", "usage": "None", "valueType": { @@ -969,13 +969,13 @@ "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, - "value": "application/json", + "value": "text/plain", "decorators": [] }, { "$id": "92", "kind": "constant", - "name": "helloDemo2ContentType", + "name": "noContentTypeContentType", "namespace": "", "usage": "None", "valueType": { @@ -991,7 +991,7 @@ { "$id": "94", "kind": "constant", - "name": "createLiteralContentType", + "name": "noContentTypeContentType1", "namespace": "", "usage": "None", "valueType": { @@ -1007,7 +1007,7 @@ { "$id": "96", "kind": "constant", - "name": "createLiteralContentType1", + "name": "helloDemo2ContentType", "namespace": "", "usage": "None", "valueType": { @@ -1023,7 +1023,7 @@ { "$id": "98", "kind": "constant", - "name": "HelloLiteralRequestP1", + "name": "createLiteralContentType", "namespace": "", "usage": "None", "valueType": { @@ -1033,17 +1033,49 @@ "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, - "value": "test", + "value": "application/json", "decorators": [] }, { "$id": "100", "kind": "constant", - "name": "ThingRequiredLiteralInt1", + "name": "createLiteralContentType1", "namespace": "", "usage": "None", "valueType": { "$id": "101", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + { + "$id": "102", + "kind": "constant", + "name": "HelloLiteralRequestP1", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "103", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "test", + "decorators": [] + }, + { + "$id": "104", + "kind": "constant", + "name": "ThingRequiredLiteralInt1", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "105", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -1053,13 +1085,13 @@ "decorators": [] }, { - "$id": "102", + "$id": "106", "kind": "constant", "name": "ThingOptionalLiteralBool1", "namespace": "", "usage": "None", "valueType": { - "$id": "103", + "$id": "107", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -1069,13 +1101,13 @@ "decorators": [] }, { - "$id": "104", + "$id": "108", "kind": "constant", "name": "helloLiteralContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "105", + "$id": "109", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1085,13 +1117,13 @@ "decorators": [] }, { - "$id": "106", + "$id": "110", "kind": "constant", "name": "HelloLiteralRequestP11", "namespace": "", "usage": "None", "valueType": { - "$id": "107", + "$id": "111", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1101,13 +1133,13 @@ "decorators": [] }, { - "$id": "108", + "$id": "112", "kind": "constant", "name": "ThingRequiredLiteralInt2", "namespace": "", "usage": "None", "valueType": { - "$id": "109", + "$id": "113", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -1117,13 +1149,13 @@ "decorators": [] }, { - "$id": "110", + "$id": "114", "kind": "constant", "name": "ThingOptionalLiteralBool2", "namespace": "", "usage": "None", "valueType": { - "$id": "111", + "$id": "115", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -1133,13 +1165,13 @@ "decorators": [] }, { - "$id": "112", + "$id": "116", "kind": "constant", "name": "topActionContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "113", + "$id": "117", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1149,13 +1181,13 @@ "decorators": [] }, { - "$id": "114", + "$id": "118", "kind": "constant", "name": "topAction2ContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "115", + "$id": "119", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1165,13 +1197,13 @@ "decorators": [] }, { - "$id": "116", + "$id": "120", "kind": "constant", "name": "patchActionContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "117", + "$id": "121", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1181,13 +1213,13 @@ "decorators": [] }, { - "$id": "118", + "$id": "122", "kind": "constant", "name": "patchActionContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "119", + "$id": "123", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1197,13 +1229,13 @@ "decorators": [] }, { - "$id": "120", + "$id": "124", "kind": "constant", "name": "AnonymousBodyRequestRequiredQueryParam", "namespace": "", "usage": "None", "valueType": { - "$id": "121", + "$id": "125", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1213,13 +1245,13 @@ "decorators": [] }, { - "$id": "122", + "$id": "126", "kind": "constant", "name": "AnonymousBodyRequestRequiredHeader", "namespace": "", "usage": "None", "valueType": { - "$id": "123", + "$id": "127", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1229,13 +1261,13 @@ "decorators": [] }, { - "$id": "124", + "$id": "128", "kind": "constant", "name": "anonymousBodyContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "125", + "$id": "129", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1245,13 +1277,13 @@ "decorators": [] }, { - "$id": "126", + "$id": "130", "kind": "constant", "name": "anonymousBodyContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "127", + "$id": "131", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1261,13 +1293,13 @@ "decorators": [] }, { - "$id": "128", + "$id": "132", "kind": "constant", "name": "ThingRequiredLiteralString1", "namespace": "", "usage": "None", "valueType": { - "$id": "129", + "$id": "133", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1277,13 +1309,13 @@ "decorators": [] }, { - "$id": "130", + "$id": "134", "kind": "constant", "name": "ThingRequiredLiteralInt3", "namespace": "", "usage": "None", "valueType": { - "$id": "131", + "$id": "135", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -1293,13 +1325,13 @@ "decorators": [] }, { - "$id": "132", + "$id": "136", "kind": "constant", "name": "ThingRequiredLiteralFloat1", "namespace": "", "usage": "None", "valueType": { - "$id": "133", + "$id": "137", "kind": "float32", "name": "float32", "crossLanguageDefinitionId": "TypeSpec.float32", @@ -1309,13 +1341,13 @@ "decorators": [] }, { - "$id": "134", + "$id": "138", "kind": "constant", "name": "ThingRequiredLiteralBool1", "namespace": "", "usage": "None", "valueType": { - "$id": "135", + "$id": "139", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -1325,13 +1357,13 @@ "decorators": [] }, { - "$id": "136", + "$id": "140", "kind": "constant", "name": "ThingOptionalLiteralBool3", "namespace": "", "usage": "None", "valueType": { - "$id": "137", + "$id": "141", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -1341,13 +1373,13 @@ "decorators": [] }, { - "$id": "138", + "$id": "142", "kind": "constant", "name": "AnonymousBodyRequestRequiredQueryParam1", "namespace": "", "usage": "None", "valueType": { - "$id": "139", + "$id": "143", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1357,13 +1389,13 @@ "decorators": [] }, { - "$id": "140", + "$id": "144", "kind": "constant", "name": "AnonymousBodyRequestRequiredHeader1", "namespace": "", "usage": "None", "valueType": { - "$id": "141", + "$id": "145", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1373,13 +1405,13 @@ "decorators": [] }, { - "$id": "142", + "$id": "146", "kind": "constant", "name": "friendlyModelContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "143", + "$id": "147", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1389,13 +1421,13 @@ "decorators": [] }, { - "$id": "144", + "$id": "148", "kind": "constant", "name": "friendlyModelContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "145", + "$id": "149", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1405,13 +1437,13 @@ "decorators": [] }, { - "$id": "146", + "$id": "150", "kind": "constant", "name": "projectedNameModelContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "147", + "$id": "151", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1421,13 +1453,13 @@ "decorators": [] }, { - "$id": "148", + "$id": "152", "kind": "constant", "name": "projectedNameModelContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "149", + "$id": "153", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1437,13 +1469,13 @@ "decorators": [] }, { - "$id": "150", + "$id": "154", "kind": "constant", "name": "returnsAnonymousModelContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "151", + "$id": "155", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1453,13 +1485,13 @@ "decorators": [] }, { - "$id": "152", + "$id": "156", "kind": "constant", "name": "internalProtocolContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "153", + "$id": "157", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1469,13 +1501,13 @@ "decorators": [] }, { - "$id": "154", + "$id": "158", "kind": "constant", "name": "internalProtocolContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "155", + "$id": "159", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1485,13 +1517,13 @@ "decorators": [] }, { - "$id": "156", + "$id": "160", "kind": "constant", "name": "ListWithNextLinkContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "157", + "$id": "161", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1501,13 +1533,13 @@ "decorators": [] }, { - "$id": "158", + "$id": "162", "kind": "constant", "name": "ListWithStringNextLinkContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "159", + "$id": "163", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1517,13 +1549,13 @@ "decorators": [] }, { - "$id": "160", + "$id": "164", "kind": "constant", "name": "ListWithContinuationTokenContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "161", + "$id": "165", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1533,13 +1565,13 @@ "decorators": [] }, { - "$id": "162", + "$id": "166", "kind": "constant", "name": "ListWithContinuationTokenHeaderResponseContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "163", + "$id": "167", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1549,13 +1581,13 @@ "decorators": [] }, { - "$id": "164", + "$id": "168", "kind": "constant", "name": "ListWithPagingContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "165", + "$id": "169", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1565,13 +1597,13 @@ "decorators": [] }, { - "$id": "166", + "$id": "170", "kind": "constant", "name": "EmbeddedParametersContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "167", + "$id": "171", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1581,13 +1613,13 @@ "decorators": [] }, { - "$id": "168", + "$id": "172", "kind": "constant", "name": "DynamicModelOperationContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "169", + "$id": "173", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1597,13 +1629,13 @@ "decorators": [] }, { - "$id": "170", + "$id": "174", "kind": "constant", - "name": "getWidgetMetricsContentType", + "name": "updatePetAsAnimalContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "171", + "$id": "175", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1611,69 +1643,229 @@ }, "value": "application/json", "decorators": [] - } - ], - "models": [ + }, { - "$id": "172", - "kind": "model", - "name": "Thing", - "namespace": "SampleTypeSpec", - "crossLanguageDefinitionId": "SampleTypeSpec.Thing", - "usage": "Input,Output,Spread,Json", - "doc": "A model with a few properties of literal types", - "decorators": [], - "properties": [ - { - "$id": "173", - "kind": "property", - "name": "name", - "serializedName": "name", - "doc": "name of the Thing", - "type": { - "$id": "174", - "kind": "string", - "name": "string", - "crossLanguageDefinitionId": "TypeSpec.string", - "decorators": [] - }, - "optional": false, - "readOnly": false, - "discriminator": false, - "flatten": false, - "decorators": [], - "crossLanguageDefinitionId": "SampleTypeSpec.Thing.name", - "serializationOptions": { - "json": { - "name": "name" - } - }, - "isHttpMetadata": false - }, - { - "$id": "175", - "kind": "property", - "name": "requiredUnion", - "serializedName": "requiredUnion", - "doc": "required Union", - "type": { - "$id": "176", - "kind": "union", - "name": "ThingRequiredUnion", - "variantTypes": [ - { - "$id": "177", - "kind": "string", - "name": "string", - "crossLanguageDefinitionId": "TypeSpec.string", - "decorators": [] - }, + "$id": "176", + "kind": "constant", + "name": "updatePetAsAnimalContentType1", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "177", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + { + "$id": "178", + "kind": "constant", + "name": "updateDogAsAnimalContentType", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "179", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + { + "$id": "180", + "kind": "constant", + "name": "updateDogAsAnimalContentType1", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "181", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + { + "$id": "182", + "kind": "constant", + "name": "updatePetAsPetContentType", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "183", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + { + "$id": "184", + "kind": "constant", + "name": "updatePetAsPetContentType1", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "185", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + { + "$id": "186", + "kind": "constant", + "name": "updateDogAsPetContentType", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "187", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + { + "$id": "188", + "kind": "constant", + "name": "updateDogAsPetContentType1", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "189", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + { + "$id": "190", + "kind": "constant", + "name": "updateDogAsDogContentType", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "191", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + { + "$id": "192", + "kind": "constant", + "name": "updateDogAsDogContentType1", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "193", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + }, + { + "$id": "194", + "kind": "constant", + "name": "getWidgetMetricsContentType", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "195", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [] + } + ], + "models": [ + { + "$id": "196", + "kind": "model", + "name": "Thing", + "namespace": "SampleTypeSpec", + "crossLanguageDefinitionId": "SampleTypeSpec.Thing", + "usage": "Input,Output,Spread,Json", + "doc": "A model with a few properties of literal types", + "decorators": [], + "properties": [ + { + "$id": "197", + "kind": "property", + "name": "name", + "serializedName": "name", + "doc": "name of the Thing", + "type": { + "$id": "198", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "optional": false, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.Thing.name", + "serializationOptions": { + "json": { + "name": "name" + } + }, + "isHttpMetadata": false + }, + { + "$id": "199", + "kind": "property", + "name": "requiredUnion", + "serializedName": "requiredUnion", + "doc": "required Union", + "type": { + "$id": "200", + "kind": "union", + "name": "ThingRequiredUnion", + "variantTypes": [ + { + "$id": "201", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, { - "$id": "178", + "$id": "202", "kind": "array", "name": "Array", "valueType": { - "$id": "179", + "$id": "203", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1683,7 +1875,7 @@ "decorators": [] }, { - "$id": "180", + "$id": "204", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -1707,7 +1899,7 @@ "isHttpMetadata": false }, { - "$id": "181", + "$id": "205", "kind": "property", "name": "requiredLiteralString", "serializedName": "requiredLiteralString", @@ -1729,16 +1921,16 @@ "isHttpMetadata": false }, { - "$id": "182", + "$id": "206", "kind": "property", "name": "requiredNullableString", "serializedName": "requiredNullableString", "doc": "required nullable string", "type": { - "$id": "183", + "$id": "207", "kind": "nullable", "type": { - "$id": "184", + "$id": "208", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1760,16 +1952,16 @@ "isHttpMetadata": false }, { - "$id": "185", + "$id": "209", "kind": "property", "name": "optionalNullableString", "serializedName": "optionalNullableString", "doc": "required optional string", "type": { - "$id": "186", + "$id": "210", "kind": "nullable", "type": { - "$id": "187", + "$id": "211", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1791,7 +1983,7 @@ "isHttpMetadata": false }, { - "$id": "188", + "$id": "212", "kind": "property", "name": "requiredLiteralInt", "serializedName": "requiredLiteralInt", @@ -1813,7 +2005,7 @@ "isHttpMetadata": false }, { - "$id": "189", + "$id": "213", "kind": "property", "name": "requiredLiteralFloat", "serializedName": "requiredLiteralFloat", @@ -1835,7 +2027,7 @@ "isHttpMetadata": false }, { - "$id": "190", + "$id": "214", "kind": "property", "name": "requiredLiteralBool", "serializedName": "requiredLiteralBool", @@ -1857,7 +2049,7 @@ "isHttpMetadata": false }, { - "$id": "191", + "$id": "215", "kind": "property", "name": "optionalLiteralString", "serializedName": "optionalLiteralString", @@ -1879,13 +2071,13 @@ "isHttpMetadata": false }, { - "$id": "192", + "$id": "216", "kind": "property", "name": "requiredNullableLiteralString", "serializedName": "requiredNullableLiteralString", "doc": "required nullable literal string", "type": { - "$id": "193", + "$id": "217", "kind": "nullable", "type": { "$ref": "5" @@ -1906,7 +2098,7 @@ "isHttpMetadata": false }, { - "$id": "194", + "$id": "218", "kind": "property", "name": "optionalLiteralInt", "serializedName": "optionalLiteralInt", @@ -1928,7 +2120,7 @@ "isHttpMetadata": false }, { - "$id": "195", + "$id": "219", "kind": "property", "name": "optionalLiteralFloat", "serializedName": "optionalLiteralFloat", @@ -1950,7 +2142,7 @@ "isHttpMetadata": false }, { - "$id": "196", + "$id": "220", "kind": "property", "name": "optionalLiteralBool", "serializedName": "optionalLiteralBool", @@ -1972,13 +2164,13 @@ "isHttpMetadata": false }, { - "$id": "197", + "$id": "221", "kind": "property", "name": "requiredBadDescription", "serializedName": "requiredBadDescription", "doc": "description with xml <|endoftext|>", "type": { - "$id": "198", + "$id": "222", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1998,20 +2190,20 @@ "isHttpMetadata": false }, { - "$id": "199", + "$id": "223", "kind": "property", "name": "optionalNullableList", "serializedName": "optionalNullableList", "doc": "optional nullable collection", "type": { - "$id": "200", + "$id": "224", "kind": "nullable", "type": { - "$id": "201", + "$id": "225", "kind": "array", "name": "Array1", "valueType": { - "$id": "202", + "$id": "226", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -2036,16 +2228,16 @@ "isHttpMetadata": false }, { - "$id": "203", + "$id": "227", "kind": "property", "name": "requiredNullableList", "serializedName": "requiredNullableList", "doc": "required nullable collection", "type": { - "$id": "204", + "$id": "228", "kind": "nullable", "type": { - "$ref": "201" + "$ref": "225" }, "namespace": "SampleTypeSpec" }, @@ -2065,7 +2257,7 @@ ] }, { - "$id": "205", + "$id": "229", "kind": "model", "name": "RoundTripModel", "namespace": "SampleTypeSpec", @@ -2075,13 +2267,13 @@ "decorators": [], "properties": [ { - "$id": "206", + "$id": "230", "kind": "property", "name": "requiredString", "serializedName": "requiredString", "doc": "Required string, illustrating a reference type property.", "type": { - "$id": "207", + "$id": "231", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2101,13 +2293,13 @@ "isHttpMetadata": false }, { - "$id": "208", + "$id": "232", "kind": "property", "name": "requiredInt", "serializedName": "requiredInt", "doc": "Required int, illustrating a value type property.", "type": { - "$id": "209", + "$id": "233", "kind": "int32", "name": "int32", "encode": "string", @@ -2128,13 +2320,13 @@ "isHttpMetadata": false }, { - "$id": "210", + "$id": "234", "kind": "property", "name": "requiredCollection", "serializedName": "requiredCollection", "doc": "Required collection of enums", "type": { - "$id": "211", + "$id": "235", "kind": "array", "name": "ArrayStringFixedEnum", "valueType": { @@ -2157,16 +2349,16 @@ "isHttpMetadata": false }, { - "$id": "212", + "$id": "236", "kind": "property", "name": "requiredDictionary", "serializedName": "requiredDictionary", "doc": "Required dictionary of enums", "type": { - "$id": "213", + "$id": "237", "kind": "dict", "keyType": { - "$id": "214", + "$id": "238", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2191,13 +2383,13 @@ "isHttpMetadata": false }, { - "$id": "215", + "$id": "239", "kind": "property", "name": "requiredModel", "serializedName": "requiredModel", "doc": "Required model", "type": { - "$ref": "172" + "$ref": "196" }, "optional": false, "readOnly": false, @@ -2213,7 +2405,7 @@ "isHttpMetadata": false }, { - "$id": "216", + "$id": "240", "kind": "property", "name": "intExtensibleEnum", "serializedName": "intExtensibleEnum", @@ -2235,13 +2427,13 @@ "isHttpMetadata": false }, { - "$id": "217", + "$id": "241", "kind": "property", "name": "intExtensibleEnumCollection", "serializedName": "intExtensibleEnumCollection", "doc": "this is a collection of int based extensible enum", "type": { - "$id": "218", + "$id": "242", "kind": "array", "name": "ArrayIntExtensibleEnum", "valueType": { @@ -2264,7 +2456,7 @@ "isHttpMetadata": false }, { - "$id": "219", + "$id": "243", "kind": "property", "name": "floatExtensibleEnum", "serializedName": "floatExtensibleEnum", @@ -2286,7 +2478,7 @@ "isHttpMetadata": false }, { - "$id": "220", + "$id": "244", "kind": "property", "name": "floatExtensibleEnumWithIntValue", "serializedName": "floatExtensibleEnumWithIntValue", @@ -2308,13 +2500,13 @@ "isHttpMetadata": false }, { - "$id": "221", + "$id": "245", "kind": "property", "name": "floatExtensibleEnumCollection", "serializedName": "floatExtensibleEnumCollection", "doc": "this is a collection of float based extensible enum", "type": { - "$id": "222", + "$id": "246", "kind": "array", "name": "ArrayFloatExtensibleEnum", "valueType": { @@ -2337,7 +2529,7 @@ "isHttpMetadata": false }, { - "$id": "223", + "$id": "247", "kind": "property", "name": "floatFixedEnum", "serializedName": "floatFixedEnum", @@ -2359,7 +2551,7 @@ "isHttpMetadata": false }, { - "$id": "224", + "$id": "248", "kind": "property", "name": "floatFixedEnumWithIntValue", "serializedName": "floatFixedEnumWithIntValue", @@ -2381,13 +2573,13 @@ "isHttpMetadata": false }, { - "$id": "225", + "$id": "249", "kind": "property", "name": "floatFixedEnumCollection", "serializedName": "floatFixedEnumCollection", "doc": "this is a collection of float based fixed enum", "type": { - "$id": "226", + "$id": "250", "kind": "array", "name": "ArrayFloatFixedEnum", "valueType": { @@ -2410,7 +2602,7 @@ "isHttpMetadata": false }, { - "$id": "227", + "$id": "251", "kind": "property", "name": "intFixedEnum", "serializedName": "intFixedEnum", @@ -2432,13 +2624,13 @@ "isHttpMetadata": false }, { - "$id": "228", + "$id": "252", "kind": "property", "name": "intFixedEnumCollection", "serializedName": "intFixedEnumCollection", "doc": "this is a collection of int based fixed enum", "type": { - "$id": "229", + "$id": "253", "kind": "array", "name": "ArrayIntFixedEnum", "valueType": { @@ -2461,7 +2653,7 @@ "isHttpMetadata": false }, { - "$id": "230", + "$id": "254", "kind": "property", "name": "stringFixedEnum", "serializedName": "stringFixedEnum", @@ -2483,13 +2675,13 @@ "isHttpMetadata": false }, { - "$id": "231", + "$id": "255", "kind": "property", "name": "requiredUnknown", "serializedName": "requiredUnknown", "doc": "required unknown", "type": { - "$id": "232", + "$id": "256", "kind": "unknown", "name": "unknown", "crossLanguageDefinitionId": "", @@ -2509,13 +2701,13 @@ "isHttpMetadata": false }, { - "$id": "233", + "$id": "257", "kind": "property", "name": "optionalUnknown", "serializedName": "optionalUnknown", "doc": "optional unknown", "type": { - "$id": "234", + "$id": "258", "kind": "unknown", "name": "unknown", "crossLanguageDefinitionId": "", @@ -2535,23 +2727,23 @@ "isHttpMetadata": false }, { - "$id": "235", + "$id": "259", "kind": "property", "name": "requiredRecordUnknown", "serializedName": "requiredRecordUnknown", "doc": "required record of unknown", "type": { - "$id": "236", + "$id": "260", "kind": "dict", "keyType": { - "$id": "237", + "$id": "261", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "238", + "$id": "262", "kind": "unknown", "name": "unknown", "crossLanguageDefinitionId": "", @@ -2573,13 +2765,13 @@ "isHttpMetadata": false }, { - "$id": "239", + "$id": "263", "kind": "property", "name": "optionalRecordUnknown", "serializedName": "optionalRecordUnknown", "doc": "optional record of unknown", "type": { - "$ref": "236" + "$ref": "260" }, "optional": true, "readOnly": false, @@ -2595,13 +2787,13 @@ "isHttpMetadata": false }, { - "$id": "240", + "$id": "264", "kind": "property", "name": "readOnlyRequiredRecordUnknown", "serializedName": "readOnlyRequiredRecordUnknown", "doc": "required readonly record of unknown", "type": { - "$ref": "236" + "$ref": "260" }, "optional": false, "readOnly": true, @@ -2617,13 +2809,13 @@ "isHttpMetadata": false }, { - "$id": "241", + "$id": "265", "kind": "property", "name": "readOnlyOptionalRecordUnknown", "serializedName": "readOnlyOptionalRecordUnknown", "doc": "optional readonly record of unknown", "type": { - "$ref": "236" + "$ref": "260" }, "optional": true, "readOnly": true, @@ -2639,13 +2831,13 @@ "isHttpMetadata": false }, { - "$id": "242", + "$id": "266", "kind": "property", "name": "modelWithRequiredNullable", "serializedName": "modelWithRequiredNullable", "doc": "this is a model with required nullable properties", "type": { - "$id": "243", + "$id": "267", "kind": "model", "name": "ModelWithRequiredNullableProperties", "namespace": "SampleTypeSpec", @@ -2655,16 +2847,16 @@ "decorators": [], "properties": [ { - "$id": "244", + "$id": "268", "kind": "property", "name": "requiredNullablePrimitive", "serializedName": "requiredNullablePrimitive", "doc": "required nullable primitive type", "type": { - "$id": "245", + "$id": "269", "kind": "nullable", "type": { - "$id": "246", + "$id": "270", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -2686,13 +2878,13 @@ "isHttpMetadata": false }, { - "$id": "247", + "$id": "271", "kind": "property", "name": "requiredExtensibleEnum", "serializedName": "requiredExtensibleEnum", "doc": "required nullable extensible enum type", "type": { - "$id": "248", + "$id": "272", "kind": "nullable", "type": { "$ref": "22" @@ -2713,13 +2905,13 @@ "isHttpMetadata": false }, { - "$id": "249", + "$id": "273", "kind": "property", "name": "requiredFixedEnum", "serializedName": "requiredFixedEnum", "doc": "required nullable fixed enum type", "type": { - "$id": "250", + "$id": "274", "kind": "nullable", "type": { "$ref": "17" @@ -2755,13 +2947,13 @@ "isHttpMetadata": false }, { - "$id": "251", + "$id": "275", "kind": "property", "name": "requiredBytes", "serializedName": "requiredBytes", "doc": "Required bytes", "type": { - "$id": "252", + "$id": "276", "kind": "bytes", "name": "bytes", "encode": "base64", @@ -2784,10 +2976,10 @@ ] }, { - "$ref": "243" + "$ref": "267" }, { - "$id": "253", + "$id": "277", "kind": "model", "name": "Friend", "namespace": "SampleTypeSpec", @@ -2797,13 +2989,13 @@ "decorators": [], "properties": [ { - "$id": "254", + "$id": "278", "kind": "property", "name": "name", "serializedName": "name", "doc": "name of the NotFriend", "type": { - "$id": "255", + "$id": "279", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2825,7 +3017,7 @@ ] }, { - "$id": "256", + "$id": "280", "kind": "model", "name": "RenamedModel", "namespace": "SampleTypeSpec", @@ -2835,13 +3027,13 @@ "decorators": [], "properties": [ { - "$id": "257", + "$id": "281", "kind": "property", "name": "otherName", "serializedName": "otherName", "doc": "name of the ModelWithClientName", "type": { - "$id": "258", + "$id": "282", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2863,7 +3055,7 @@ ] }, { - "$id": "259", + "$id": "283", "kind": "model", "name": "ReturnsAnonymousModelResponse", "namespace": "SampleTypeSpec", @@ -2873,7 +3065,7 @@ "properties": [] }, { - "$id": "260", + "$id": "284", "kind": "model", "name": "ListWithNextLinkResponse", "namespace": "SampleTypeSpec", @@ -2882,16 +3074,16 @@ "decorators": [], "properties": [ { - "$id": "261", + "$id": "285", "kind": "property", "name": "things", "serializedName": "things", "type": { - "$id": "262", + "$id": "286", "kind": "array", "name": "ArrayThing", "valueType": { - "$ref": "172" + "$ref": "196" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -2910,12 +3102,12 @@ "isHttpMetadata": false }, { - "$id": "263", + "$id": "287", "kind": "property", "name": "next", "serializedName": "next", "type": { - "$id": "264", + "$id": "288", "kind": "url", "name": "url", "crossLanguageDefinitionId": "TypeSpec.url", @@ -2937,7 +3129,7 @@ ] }, { - "$id": "265", + "$id": "289", "kind": "model", "name": "ListWithStringNextLinkResponse", "namespace": "SampleTypeSpec", @@ -2946,12 +3138,12 @@ "decorators": [], "properties": [ { - "$id": "266", + "$id": "290", "kind": "property", "name": "things", "serializedName": "things", "type": { - "$ref": "262" + "$ref": "286" }, "optional": false, "readOnly": false, @@ -2967,12 +3159,12 @@ "isHttpMetadata": false }, { - "$id": "267", + "$id": "291", "kind": "property", "name": "next", "serializedName": "next", "type": { - "$id": "268", + "$id": "292", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2994,7 +3186,7 @@ ] }, { - "$id": "269", + "$id": "293", "kind": "model", "name": "ListWithContinuationTokenResponse", "namespace": "SampleTypeSpec", @@ -3003,12 +3195,12 @@ "decorators": [], "properties": [ { - "$id": "270", + "$id": "294", "kind": "property", "name": "things", "serializedName": "things", "type": { - "$ref": "262" + "$ref": "286" }, "optional": false, "readOnly": false, @@ -3024,12 +3216,12 @@ "isHttpMetadata": false }, { - "$id": "271", + "$id": "295", "kind": "property", "name": "nextToken", "serializedName": "nextToken", "type": { - "$id": "272", + "$id": "296", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3051,7 +3243,7 @@ ] }, { - "$id": "273", + "$id": "297", "kind": "model", "name": "ListWithContinuationTokenHeaderResponseResponse", "namespace": "", @@ -3060,12 +3252,12 @@ "decorators": [], "properties": [ { - "$id": "274", + "$id": "298", "kind": "property", "name": "things", "serializedName": "things", "type": { - "$ref": "262" + "$ref": "286" }, "optional": false, "readOnly": false, @@ -3083,7 +3275,7 @@ ] }, { - "$id": "275", + "$id": "299", "kind": "model", "name": "PageThing", "namespace": "SampleTypeSpec", @@ -3092,12 +3284,12 @@ "decorators": [], "properties": [ { - "$id": "276", + "$id": "300", "kind": "property", "name": "items", "serializedName": "items", "type": { - "$ref": "262" + "$ref": "286" }, "optional": false, "readOnly": false, @@ -3115,7 +3307,7 @@ ] }, { - "$id": "277", + "$id": "301", "kind": "model", "name": "ModelWithEmbeddedNonBodyParameters", "namespace": "SampleTypeSpec", @@ -3124,13 +3316,13 @@ "decorators": [], "properties": [ { - "$id": "278", + "$id": "302", "kind": "property", "name": "name", "serializedName": "name", "doc": "name of the ModelWithEmbeddedNonBodyParameters", "type": { - "$id": "279", + "$id": "303", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3150,13 +3342,13 @@ "isHttpMetadata": false }, { - "$id": "280", + "$id": "304", "kind": "property", "name": "requiredHeader", "serializedName": "requiredHeader", "doc": "required header parameter", "type": { - "$id": "281", + "$id": "305", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3176,13 +3368,13 @@ "isHttpMetadata": true }, { - "$id": "282", + "$id": "306", "kind": "property", "name": "optionalHeader", "serializedName": "optionalHeader", "doc": "optional header parameter", "type": { - "$id": "283", + "$id": "307", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3202,13 +3394,13 @@ "isHttpMetadata": true }, { - "$id": "284", + "$id": "308", "kind": "property", "name": "requiredQuery", "serializedName": "requiredQuery", "doc": "required query parameter", "type": { - "$id": "285", + "$id": "309", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3228,13 +3420,13 @@ "isHttpMetadata": true }, { - "$id": "286", + "$id": "310", "kind": "property", "name": "optionalQuery", "serializedName": "optionalQuery", "doc": "optional query parameter", "type": { - "$id": "287", + "$id": "311", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3256,7 +3448,7 @@ ] }, { - "$id": "288", + "$id": "312", "kind": "model", "name": "DynamicModel", "namespace": "SampleTypeSpec", @@ -3271,12 +3463,12 @@ ], "properties": [ { - "$id": "289", + "$id": "313", "kind": "property", "name": "name", "serializedName": "name", "type": { - "$id": "290", + "$id": "314", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3296,12 +3488,12 @@ "isHttpMetadata": false }, { - "$id": "291", + "$id": "315", "kind": "property", "name": "optionalUnknown", "serializedName": "optionalUnknown", "type": { - "$id": "292", + "$id": "316", "kind": "unknown", "name": "unknown", "crossLanguageDefinitionId": "", @@ -3321,12 +3513,12 @@ "isHttpMetadata": false }, { - "$id": "293", + "$id": "317", "kind": "property", "name": "optionalInt", "serializedName": "optionalInt", "type": { - "$id": "294", + "$id": "318", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -3346,15 +3538,15 @@ "isHttpMetadata": false }, { - "$id": "295", + "$id": "319", "kind": "property", "name": "optionalNullableList", "serializedName": "optionalNullableList", "type": { - "$id": "296", + "$id": "320", "kind": "nullable", "type": { - "$ref": "201" + "$ref": "225" }, "namespace": "SampleTypeSpec" }, @@ -3372,15 +3564,15 @@ "isHttpMetadata": false }, { - "$id": "297", + "$id": "321", "kind": "property", "name": "requiredNullableList", "serializedName": "requiredNullableList", "type": { - "$id": "298", + "$id": "322", "kind": "nullable", "type": { - "$ref": "201" + "$ref": "225" }, "namespace": "SampleTypeSpec" }, @@ -3398,25 +3590,25 @@ "isHttpMetadata": false }, { - "$id": "299", + "$id": "323", "kind": "property", "name": "optionalNullableDictionary", "serializedName": "optionalNullableDictionary", "type": { - "$id": "300", + "$id": "324", "kind": "nullable", "type": { - "$id": "301", + "$id": "325", "kind": "dict", "keyType": { - "$id": "302", + "$id": "326", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "303", + "$id": "327", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -3440,15 +3632,15 @@ "isHttpMetadata": false }, { - "$id": "304", + "$id": "328", "kind": "property", "name": "requiredNullableDictionary", "serializedName": "requiredNullableDictionary", "type": { - "$id": "305", + "$id": "329", "kind": "nullable", "type": { - "$ref": "301" + "$ref": "325" }, "namespace": "SampleTypeSpec" }, @@ -3466,12 +3658,12 @@ "isHttpMetadata": false }, { - "$id": "306", + "$id": "330", "kind": "property", "name": "primitiveDictionary", "serializedName": "primitiveDictionary", "type": { - "$ref": "301" + "$ref": "325" }, "optional": false, "readOnly": false, @@ -3487,12 +3679,12 @@ "isHttpMetadata": false }, { - "$id": "307", + "$id": "331", "kind": "property", "name": "foo", "serializedName": "foo", "type": { - "$id": "308", + "$id": "332", "kind": "model", "name": "AnotherDynamicModel", "namespace": "SampleTypeSpec", @@ -3507,12 +3699,12 @@ ], "properties": [ { - "$id": "309", + "$id": "333", "kind": "property", "name": "bar", "serializedName": "bar", "type": { - "$id": "310", + "$id": "334", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3547,16 +3739,16 @@ "isHttpMetadata": false }, { - "$id": "311", + "$id": "335", "kind": "property", "name": "listFoo", "serializedName": "listFoo", "type": { - "$id": "312", + "$id": "336", "kind": "array", "name": "ArrayAnotherDynamicModel", "valueType": { - "$ref": "308" + "$ref": "332" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -3575,16 +3767,16 @@ "isHttpMetadata": false }, { - "$id": "313", + "$id": "337", "kind": "property", "name": "listOfListFoo", "serializedName": "listOfListFoo", "type": { - "$id": "314", + "$id": "338", "kind": "array", "name": "ArrayArray", "valueType": { - "$ref": "312" + "$ref": "336" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -3603,22 +3795,22 @@ "isHttpMetadata": false }, { - "$id": "315", + "$id": "339", "kind": "property", "name": "dictionaryFoo", "serializedName": "dictionaryFoo", "type": { - "$id": "316", + "$id": "340", "kind": "dict", "keyType": { - "$id": "317", + "$id": "341", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$ref": "308" + "$ref": "332" }, "decorators": [] }, @@ -3636,22 +3828,22 @@ "isHttpMetadata": false }, { - "$id": "318", + "$id": "342", "kind": "property", "name": "dictionaryOfDictionaryFoo", "serializedName": "dictionaryOfDictionaryFoo", "type": { - "$id": "319", + "$id": "343", "kind": "dict", "keyType": { - "$id": "320", + "$id": "344", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$ref": "316" + "$ref": "340" }, "decorators": [] }, @@ -3669,22 +3861,22 @@ "isHttpMetadata": false }, { - "$id": "321", + "$id": "345", "kind": "property", "name": "dictionaryListFoo", "serializedName": "dictionaryListFoo", "type": { - "$id": "322", + "$id": "346", "kind": "dict", "keyType": { - "$id": "323", + "$id": "347", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$ref": "312" + "$ref": "336" }, "decorators": [] }, @@ -3702,16 +3894,16 @@ "isHttpMetadata": false }, { - "$id": "324", + "$id": "348", "kind": "property", "name": "listOfDictionaryFoo", "serializedName": "listOfDictionaryFoo", "type": { - "$id": "325", + "$id": "349", "kind": "array", "name": "ArrayRecord", "valueType": { - "$ref": "316" + "$ref": "340" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -3732,10 +3924,219 @@ ] }, { - "$ref": "308" + "$ref": "332" + }, + { + "$id": "350", + "kind": "model", + "name": "Animal", + "namespace": "SampleTypeSpec", + "crossLanguageDefinitionId": "SampleTypeSpec.Animal", + "usage": "Input,Output,Json", + "doc": "Base animal with discriminator", + "decorators": [], + "discriminatorProperty": { + "$id": "351", + "kind": "property", + "name": "kind", + "serializedName": "kind", + "doc": "The kind of animal", + "type": { + "$id": "352", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "optional": false, + "readOnly": false, + "discriminator": true, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.Animal.kind", + "serializationOptions": { + "json": { + "name": "kind" + } + }, + "isHttpMetadata": false + }, + "properties": [ + { + "$ref": "351" + }, + { + "$id": "353", + "kind": "property", + "name": "name", + "serializedName": "name", + "doc": "Name of the animal", + "type": { + "$id": "354", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "optional": false, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.Animal.name", + "serializationOptions": { + "json": { + "name": "name" + } + }, + "isHttpMetadata": false + } + ], + "discriminatedSubtypes": { + "pet": { + "$id": "355", + "kind": "model", + "name": "Pet", + "namespace": "SampleTypeSpec", + "crossLanguageDefinitionId": "SampleTypeSpec.Pet", + "usage": "Input,Output,Json", + "doc": "Pet is a discriminated animal", + "discriminatorValue": "pet", + "decorators": [], + "discriminatorProperty": { + "$id": "356", + "kind": "property", + "name": "kind", + "serializedName": "kind", + "type": { + "$ref": "80" + }, + "optional": false, + "readOnly": false, + "discriminator": true, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.Pet.kind", + "serializationOptions": { + "json": { + "name": "kind" + } + }, + "isHttpMetadata": false + }, + "baseModel": { + "$ref": "350" + }, + "properties": [ + { + "$ref": "356" + }, + { + "$id": "357", + "kind": "property", + "name": "trained", + "serializedName": "trained", + "doc": "Whether the pet is trained", + "type": { + "$id": "358", + "kind": "boolean", + "name": "boolean", + "crossLanguageDefinitionId": "TypeSpec.boolean", + "decorators": [] + }, + "optional": false, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.Pet.trained", + "serializationOptions": { + "json": { + "name": "trained" + } + }, + "isHttpMetadata": false + } + ], + "discriminatedSubtypes": { + "dog": { + "$id": "359", + "kind": "model", + "name": "Dog", + "namespace": "SampleTypeSpec", + "crossLanguageDefinitionId": "SampleTypeSpec.Dog", + "usage": "Input,Output,Json", + "doc": "Dog is a specific type of pet with hierarchy building", + "discriminatorValue": "dog", + "decorators": [], + "baseModel": { + "$ref": "355" + }, + "properties": [ + { + "$id": "360", + "kind": "property", + "name": "kind", + "serializedName": "kind", + "type": { + "$ref": "82" + }, + "optional": false, + "readOnly": false, + "discriminator": true, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.Dog.kind", + "serializationOptions": { + "json": { + "name": "kind" + } + }, + "isHttpMetadata": false + }, + { + "$id": "361", + "kind": "property", + "name": "breed", + "serializedName": "breed", + "doc": "The breed of the dog", + "type": { + "$id": "362", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "optional": false, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.Dog.breed", + "serializationOptions": { + "json": { + "name": "breed" + } + }, + "isHttpMetadata": false + } + ] + } + } + }, + "dog": { + "$ref": "359" + } + } + }, + { + "$ref": "355" + }, + { + "$ref": "359" }, { - "$id": "326", + "$id": "363", "kind": "model", "name": "GetWidgetMetricsResponse", "namespace": "SampleTypeSpec", @@ -3744,12 +4145,12 @@ "decorators": [], "properties": [ { - "$id": "327", + "$id": "364", "kind": "property", "name": "numSold", "serializedName": "numSold", "type": { - "$id": "328", + "$id": "365", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -3769,12 +4170,12 @@ "isHttpMetadata": false }, { - "$id": "329", + "$id": "366", "kind": "property", "name": "averagePrice", "serializedName": "averagePrice", "type": { - "$id": "330", + "$id": "367", "kind": "float32", "name": "float32", "crossLanguageDefinitionId": "TypeSpec.float32", @@ -3798,14 +4199,14 @@ ], "clients": [ { - "$id": "331", + "$id": "368", "kind": "client", "name": "SampleTypeSpecClient", "namespace": "SampleTypeSpec", "doc": "This is a sample typespec project.", "methods": [ { - "$id": "332", + "$id": "369", "kind": "basic", "name": "sayHi", "accessibility": "public", @@ -3815,19 +4216,19 @@ ], "doc": "Return hi", "operation": { - "$id": "333", + "$id": "370", "name": "sayHi", "resourceName": "SampleTypeSpec", "doc": "Return hi", "accessibility": "public", "parameters": [ { - "$id": "334", + "$id": "371", "kind": "header", "name": "headParameter", "serializedName": "head-parameter", "type": { - "$id": "335", + "$id": "372", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3842,12 +4243,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.sayHi.headParameter" }, { - "$id": "336", + "$id": "373", "kind": "query", "name": "queryParameter", "serializedName": "queryParameter", "type": { - "$id": "337", + "$id": "374", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3862,12 +4263,12 @@ "readOnly": false }, { - "$id": "338", + "$id": "375", "kind": "query", "name": "optionalQuery", "serializedName": "optionalQuery", "type": { - "$id": "339", + "$id": "376", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3882,12 +4283,12 @@ "readOnly": false }, { - "$id": "340", + "$id": "377", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "80" + "$ref": "84" }, "isApiVersion": false, "optional": false, @@ -3904,7 +4305,7 @@ 200 ], "bodyType": { - "$ref": "172" + "$ref": "196" }, "headers": [], "isErrorResponse": false, @@ -3924,12 +4325,12 @@ }, "parameters": [ { - "$id": "341", + "$id": "378", "kind": "method", "name": "headParameter", "serializedName": "head-parameter", "type": { - "$id": "342", + "$id": "379", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3945,12 +4346,12 @@ "decorators": [] }, { - "$id": "343", + "$id": "380", "kind": "method", "name": "queryParameter", "serializedName": "queryParameter", "type": { - "$id": "344", + "$id": "381", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3966,12 +4367,12 @@ "decorators": [] }, { - "$id": "345", + "$id": "382", "kind": "method", "name": "optionalQuery", "serializedName": "optionalQuery", "type": { - "$id": "346", + "$id": "383", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3987,12 +4388,12 @@ "decorators": [] }, { - "$id": "347", + "$id": "384", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "80" + "$ref": "84" }, "location": "Header", "isApiVersion": false, @@ -4006,7 +4407,7 @@ ], "response": { "type": { - "$ref": "172" + "$ref": "196" } }, "isOverride": false, @@ -4015,7 +4416,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.sayHi" }, { - "$id": "348", + "$id": "385", "kind": "basic", "name": "helloAgain", "accessibility": "public", @@ -4025,19 +4426,19 @@ ], "doc": "Return hi again", "operation": { - "$id": "349", + "$id": "386", "name": "helloAgain", "resourceName": "SampleTypeSpec", "doc": "Return hi again", "accessibility": "public", "parameters": [ { - "$id": "350", + "$id": "387", "kind": "header", "name": "p1", "serializedName": "p1", "type": { - "$id": "351", + "$id": "388", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4052,12 +4453,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain.p1" }, { - "$id": "352", + "$id": "389", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "82" + "$ref": "86" }, "isApiVersion": false, "optional": false, @@ -4068,12 +4469,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain.contentType" }, { - "$id": "353", + "$id": "390", "kind": "path", "name": "p2", "serializedName": "p2", "type": { - "$id": "354", + "$id": "391", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4091,12 +4492,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain.p2" }, { - "$id": "355", + "$id": "392", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "84" + "$ref": "88" }, "isApiVersion": false, "optional": false, @@ -4107,12 +4508,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain.accept" }, { - "$id": "356", + "$id": "393", "kind": "body", "name": "action", "serializedName": "action", "type": { - "$ref": "205" + "$ref": "229" }, "isApiVersion": false, "contentTypes": [ @@ -4132,7 +4533,7 @@ 200 ], "bodyType": { - "$ref": "205" + "$ref": "229" }, "headers": [], "isErrorResponse": false, @@ -4155,12 +4556,12 @@ }, "parameters": [ { - "$id": "357", + "$id": "394", "kind": "method", "name": "p1", "serializedName": "p1", "type": { - "$id": "358", + "$id": "395", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4176,12 +4577,12 @@ "decorators": [] }, { - "$id": "359", + "$id": "396", "kind": "method", "name": "action", "serializedName": "action", "type": { - "$ref": "205" + "$ref": "229" }, "location": "Body", "isApiVersion": false, @@ -4193,12 +4594,12 @@ "decorators": [] }, { - "$id": "360", + "$id": "397", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "86" + "$ref": "90" }, "location": "Header", "isApiVersion": false, @@ -4210,12 +4611,12 @@ "decorators": [] }, { - "$id": "361", + "$id": "398", "kind": "method", "name": "p2", "serializedName": "p2", "type": { - "$id": "362", + "$id": "399", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4231,12 +4632,12 @@ "decorators": [] }, { - "$id": "363", + "$id": "400", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "84" + "$ref": "88" }, "location": "Header", "isApiVersion": false, @@ -4250,7 +4651,7 @@ ], "response": { "type": { - "$ref": "205" + "$ref": "229" } }, "isOverride": false, @@ -4259,7 +4660,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain" }, { - "$id": "364", + "$id": "401", "kind": "basic", "name": "noContentType", "accessibility": "public", @@ -4269,19 +4670,19 @@ ], "doc": "Return hi again", "operation": { - "$id": "365", + "$id": "402", "name": "noContentType", "resourceName": "SampleTypeSpec", "doc": "Return hi again", "accessibility": "public", "parameters": [ { - "$id": "366", + "$id": "403", "kind": "header", "name": "p1", "serializedName": "p1", "type": { - "$id": "367", + "$id": "404", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4296,12 +4697,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType.p1" }, { - "$id": "368", + "$id": "405", "kind": "path", "name": "p2", "serializedName": "p2", "type": { - "$id": "369", + "$id": "406", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4319,13 +4720,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType.p2" }, { - "$id": "370", + "$id": "407", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "88" + "$ref": "92" }, "isApiVersion": false, "optional": false, @@ -4336,12 +4737,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType.contentType" }, { - "$id": "371", + "$id": "408", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "90" + "$ref": "94" }, "isApiVersion": false, "optional": false, @@ -4352,12 +4753,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType.accept" }, { - "$id": "372", + "$id": "409", "kind": "body", "name": "action", "serializedName": "action", "type": { - "$ref": "205" + "$ref": "229" }, "isApiVersion": false, "contentTypes": [ @@ -4377,7 +4778,7 @@ 200 ], "bodyType": { - "$ref": "205" + "$ref": "229" }, "headers": [], "isErrorResponse": false, @@ -4400,12 +4801,12 @@ }, "parameters": [ { - "$id": "373", + "$id": "410", "kind": "method", "name": "p1", "serializedName": "p1", "type": { - "$id": "374", + "$id": "411", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4421,12 +4822,12 @@ "decorators": [] }, { - "$id": "375", + "$id": "412", "kind": "method", "name": "action", "serializedName": "action", "type": { - "$ref": "205" + "$ref": "229" }, "location": "Body", "isApiVersion": false, @@ -4438,12 +4839,12 @@ "decorators": [] }, { - "$id": "376", + "$id": "413", "kind": "method", "name": "p2", "serializedName": "p2", "type": { - "$id": "377", + "$id": "414", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4459,13 +4860,13 @@ "decorators": [] }, { - "$id": "378", + "$id": "415", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "88" + "$ref": "92" }, "location": "Header", "isApiVersion": false, @@ -4477,12 +4878,12 @@ "decorators": [] }, { - "$id": "379", + "$id": "416", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "90" + "$ref": "94" }, "location": "Header", "isApiVersion": false, @@ -4496,7 +4897,7 @@ ], "response": { "type": { - "$ref": "205" + "$ref": "229" } }, "isOverride": false, @@ -4505,7 +4906,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType" }, { - "$id": "380", + "$id": "417", "kind": "basic", "name": "helloDemo2", "accessibility": "public", @@ -4515,19 +4916,19 @@ ], "doc": "Return hi in demo2", "operation": { - "$id": "381", + "$id": "418", "name": "helloDemo2", "resourceName": "SampleTypeSpec", "doc": "Return hi in demo2", "accessibility": "public", "parameters": [ { - "$id": "382", + "$id": "419", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "92" + "$ref": "96" }, "isApiVersion": false, "optional": false, @@ -4544,7 +4945,7 @@ 200 ], "bodyType": { - "$ref": "172" + "$ref": "196" }, "headers": [], "isErrorResponse": false, @@ -4564,12 +4965,12 @@ }, "parameters": [ { - "$id": "383", + "$id": "420", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "92" + "$ref": "96" }, "location": "Header", "isApiVersion": false, @@ -4583,7 +4984,7 @@ ], "response": { "type": { - "$ref": "172" + "$ref": "196" } }, "isOverride": false, @@ -4592,7 +4993,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloDemo2" }, { - "$id": "384", + "$id": "421", "kind": "basic", "name": "createLiteral", "accessibility": "public", @@ -4602,20 +5003,20 @@ ], "doc": "Create with literal value", "operation": { - "$id": "385", + "$id": "422", "name": "createLiteral", "resourceName": "SampleTypeSpec", "doc": "Create with literal value", "accessibility": "public", "parameters": [ { - "$id": "386", + "$id": "423", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "94" + "$ref": "98" }, "isApiVersion": false, "optional": false, @@ -4626,12 +5027,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.createLiteral.contentType" }, { - "$id": "387", + "$id": "424", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "96" + "$ref": "100" }, "isApiVersion": false, "optional": false, @@ -4642,12 +5043,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.createLiteral.accept" }, { - "$id": "388", + "$id": "425", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "172" + "$ref": "196" }, "isApiVersion": false, "contentTypes": [ @@ -4667,7 +5068,7 @@ 200 ], "bodyType": { - "$ref": "172" + "$ref": "196" }, "headers": [], "isErrorResponse": false, @@ -4690,12 +5091,12 @@ }, "parameters": [ { - "$id": "389", + "$id": "426", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "172" + "$ref": "196" }, "location": "Body", "isApiVersion": false, @@ -4707,13 +5108,13 @@ "decorators": [] }, { - "$id": "390", + "$id": "427", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "94" + "$ref": "98" }, "location": "Header", "isApiVersion": false, @@ -4725,12 +5126,12 @@ "decorators": [] }, { - "$id": "391", + "$id": "428", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "96" + "$ref": "100" }, "location": "Header", "isApiVersion": false, @@ -4744,7 +5145,7 @@ ], "response": { "type": { - "$ref": "172" + "$ref": "196" } }, "isOverride": false, @@ -4753,7 +5154,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.createLiteral" }, { - "$id": "392", + "$id": "429", "kind": "basic", "name": "helloLiteral", "accessibility": "public", @@ -4763,19 +5164,19 @@ ], "doc": "Send literal parameters", "operation": { - "$id": "393", + "$id": "430", "name": "helloLiteral", "resourceName": "SampleTypeSpec", "doc": "Send literal parameters", "accessibility": "public", "parameters": [ { - "$id": "394", + "$id": "431", "kind": "header", "name": "p1", "serializedName": "p1", "type": { - "$ref": "98" + "$ref": "102" }, "isApiVersion": false, "optional": false, @@ -4786,12 +5187,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloLiteral.p1" }, { - "$id": "395", + "$id": "432", "kind": "path", "name": "p2", "serializedName": "p2", "type": { - "$ref": "100" + "$ref": "104" }, "isApiVersion": false, "explode": false, @@ -4805,12 +5206,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloLiteral.p2" }, { - "$id": "396", + "$id": "433", "kind": "query", "name": "p3", "serializedName": "p3", "type": { - "$ref": "102" + "$ref": "106" }, "isApiVersion": false, "explode": false, @@ -4821,12 +5222,12 @@ "readOnly": false }, { - "$id": "397", + "$id": "434", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "104" + "$ref": "108" }, "isApiVersion": false, "optional": false, @@ -4843,7 +5244,7 @@ 200 ], "bodyType": { - "$ref": "172" + "$ref": "196" }, "headers": [], "isErrorResponse": false, @@ -4863,12 +5264,12 @@ }, "parameters": [ { - "$id": "398", + "$id": "435", "kind": "method", "name": "p1", "serializedName": "p1", "type": { - "$ref": "106" + "$ref": "110" }, "location": "Header", "isApiVersion": false, @@ -4880,12 +5281,12 @@ "decorators": [] }, { - "$id": "399", + "$id": "436", "kind": "method", "name": "p2", "serializedName": "p2", "type": { - "$ref": "108" + "$ref": "112" }, "location": "Path", "isApiVersion": false, @@ -4897,12 +5298,12 @@ "decorators": [] }, { - "$id": "400", + "$id": "437", "kind": "method", "name": "p3", "serializedName": "p3", "type": { - "$ref": "110" + "$ref": "114" }, "location": "Query", "isApiVersion": false, @@ -4914,12 +5315,12 @@ "decorators": [] }, { - "$id": "401", + "$id": "438", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "104" + "$ref": "108" }, "location": "Header", "isApiVersion": false, @@ -4933,7 +5334,7 @@ ], "response": { "type": { - "$ref": "172" + "$ref": "196" } }, "isOverride": false, @@ -4942,7 +5343,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloLiteral" }, { - "$id": "402", + "$id": "439", "kind": "basic", "name": "topAction", "accessibility": "public", @@ -4952,24 +5353,24 @@ ], "doc": "top level method", "operation": { - "$id": "403", + "$id": "440", "name": "topAction", "resourceName": "SampleTypeSpec", "doc": "top level method", "accessibility": "public", "parameters": [ { - "$id": "404", + "$id": "441", "kind": "path", "name": "action", "serializedName": "action", "type": { - "$id": "405", + "$id": "442", "kind": "utcDateTime", "name": "utcDateTime", "encode": "rfc3339", "wireType": { - "$id": "406", + "$id": "443", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4990,12 +5391,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.topAction.action" }, { - "$id": "407", + "$id": "444", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "112" + "$ref": "116" }, "isApiVersion": false, "optional": false, @@ -5012,7 +5413,7 @@ 200 ], "bodyType": { - "$ref": "172" + "$ref": "196" }, "headers": [], "isErrorResponse": false, @@ -5032,17 +5433,17 @@ }, "parameters": [ { - "$id": "408", + "$id": "445", "kind": "method", "name": "action", "serializedName": "action", "type": { - "$id": "409", + "$id": "446", "kind": "utcDateTime", "name": "utcDateTime", "encode": "rfc3339", "wireType": { - "$id": "410", + "$id": "447", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5061,12 +5462,12 @@ "decorators": [] }, { - "$id": "411", + "$id": "448", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "112" + "$ref": "116" }, "location": "Header", "isApiVersion": false, @@ -5080,7 +5481,7 @@ ], "response": { "type": { - "$ref": "172" + "$ref": "196" } }, "isOverride": false, @@ -5089,7 +5490,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.topAction" }, { - "$id": "412", + "$id": "449", "kind": "basic", "name": "topAction2", "accessibility": "public", @@ -5099,19 +5500,19 @@ ], "doc": "top level method2", "operation": { - "$id": "413", + "$id": "450", "name": "topAction2", "resourceName": "SampleTypeSpec", "doc": "top level method2", "accessibility": "public", "parameters": [ { - "$id": "414", + "$id": "451", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "114" + "$ref": "118" }, "isApiVersion": false, "optional": false, @@ -5128,7 +5529,7 @@ 200 ], "bodyType": { - "$ref": "172" + "$ref": "196" }, "headers": [], "isErrorResponse": false, @@ -5148,12 +5549,12 @@ }, "parameters": [ { - "$id": "415", + "$id": "452", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "114" + "$ref": "118" }, "location": "Header", "isApiVersion": false, @@ -5167,7 +5568,7 @@ ], "response": { "type": { - "$ref": "172" + "$ref": "196" } }, "isOverride": false, @@ -5176,7 +5577,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.topAction2" }, { - "$id": "416", + "$id": "453", "kind": "basic", "name": "patchAction", "accessibility": "public", @@ -5186,20 +5587,20 @@ ], "doc": "top level patch", "operation": { - "$id": "417", + "$id": "454", "name": "patchAction", "resourceName": "SampleTypeSpec", "doc": "top level patch", "accessibility": "public", "parameters": [ { - "$id": "418", + "$id": "455", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "116" + "$ref": "120" }, "isApiVersion": false, "optional": false, @@ -5210,12 +5611,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.patchAction.contentType" }, { - "$id": "419", + "$id": "456", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "118" + "$ref": "122" }, "isApiVersion": false, "optional": false, @@ -5226,12 +5627,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.patchAction.accept" }, { - "$id": "420", + "$id": "457", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "172" + "$ref": "196" }, "isApiVersion": false, "contentTypes": [ @@ -5251,7 +5652,7 @@ 200 ], "bodyType": { - "$ref": "172" + "$ref": "196" }, "headers": [], "isErrorResponse": false, @@ -5274,12 +5675,12 @@ }, "parameters": [ { - "$id": "421", + "$id": "458", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "172" + "$ref": "196" }, "location": "Body", "isApiVersion": false, @@ -5291,13 +5692,13 @@ "decorators": [] }, { - "$id": "422", + "$id": "459", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "116" + "$ref": "120" }, "location": "Header", "isApiVersion": false, @@ -5309,12 +5710,12 @@ "decorators": [] }, { - "$id": "423", + "$id": "460", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "118" + "$ref": "122" }, "location": "Header", "isApiVersion": false, @@ -5328,7 +5729,7 @@ ], "response": { "type": { - "$ref": "172" + "$ref": "196" } }, "isOverride": false, @@ -5337,7 +5738,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.patchAction" }, { - "$id": "424", + "$id": "461", "kind": "basic", "name": "anonymousBody", "accessibility": "public", @@ -5347,19 +5748,19 @@ ], "doc": "body parameter without body decorator", "operation": { - "$id": "425", + "$id": "462", "name": "anonymousBody", "resourceName": "SampleTypeSpec", "doc": "body parameter without body decorator", "accessibility": "public", "parameters": [ { - "$id": "426", + "$id": "463", "kind": "query", "name": "requiredQueryParam", "serializedName": "requiredQueryParam", "type": { - "$ref": "120" + "$ref": "124" }, "isApiVersion": false, "explode": false, @@ -5370,12 +5771,12 @@ "readOnly": false }, { - "$id": "427", + "$id": "464", "kind": "header", "name": "requiredHeader", "serializedName": "required-header", "type": { - "$ref": "122" + "$ref": "126" }, "isApiVersion": false, "optional": false, @@ -5386,13 +5787,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.anonymousBody.requiredHeader" }, { - "$id": "428", + "$id": "465", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "124" + "$ref": "128" }, "isApiVersion": false, "optional": false, @@ -5403,12 +5804,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.anonymousBody.contentType" }, { - "$id": "429", + "$id": "466", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "126" + "$ref": "130" }, "isApiVersion": false, "optional": false, @@ -5419,12 +5820,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.anonymousBody.accept" }, { - "$id": "430", + "$id": "467", "kind": "body", "name": "thing", "serializedName": "thing", "type": { - "$ref": "172" + "$ref": "196" }, "isApiVersion": false, "contentTypes": [ @@ -5444,7 +5845,7 @@ 200 ], "bodyType": { - "$ref": "172" + "$ref": "196" }, "headers": [], "isErrorResponse": false, @@ -5467,13 +5868,13 @@ }, "parameters": [ { - "$id": "431", + "$id": "468", "kind": "method", "name": "name", "serializedName": "name", "doc": "name of the Thing", "type": { - "$id": "432", + "$id": "469", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5489,13 +5890,13 @@ "decorators": [] }, { - "$id": "433", + "$id": "470", "kind": "method", "name": "requiredUnion", "serializedName": "requiredUnion", "doc": "required Union", "type": { - "$ref": "176" + "$ref": "200" }, "location": "Body", "isApiVersion": false, @@ -5507,7 +5908,7 @@ "decorators": [] }, { - "$id": "434", + "$id": "471", "kind": "method", "name": "requiredLiteralString", "serializedName": "requiredLiteralString", @@ -5525,13 +5926,13 @@ "decorators": [] }, { - "$id": "435", + "$id": "472", "kind": "method", "name": "requiredNullableString", "serializedName": "requiredNullableString", "doc": "required nullable string", "type": { - "$ref": "183" + "$ref": "207" }, "location": "Body", "isApiVersion": false, @@ -5543,13 +5944,13 @@ "decorators": [] }, { - "$id": "436", + "$id": "473", "kind": "method", "name": "optionalNullableString", "serializedName": "optionalNullableString", "doc": "required optional string", "type": { - "$ref": "186" + "$ref": "210" }, "location": "Body", "isApiVersion": false, @@ -5561,7 +5962,7 @@ "decorators": [] }, { - "$id": "437", + "$id": "474", "kind": "method", "name": "requiredLiteralInt", "serializedName": "requiredLiteralInt", @@ -5579,7 +5980,7 @@ "decorators": [] }, { - "$id": "438", + "$id": "475", "kind": "method", "name": "requiredLiteralFloat", "serializedName": "requiredLiteralFloat", @@ -5597,7 +5998,7 @@ "decorators": [] }, { - "$id": "439", + "$id": "476", "kind": "method", "name": "requiredLiteralBool", "serializedName": "requiredLiteralBool", @@ -5615,18 +6016,18 @@ "decorators": [] }, { - "$id": "440", + "$id": "477", "kind": "method", "name": "optionalLiteralString", "serializedName": "optionalLiteralString", "doc": "optional literal string", "type": { - "$id": "441", + "$id": "478", "kind": "enum", "name": "ThingOptionalLiteralString", "crossLanguageDefinitionId": "", "valueType": { - "$id": "442", + "$id": "479", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5634,12 +6035,12 @@ }, "values": [ { - "$id": "443", + "$id": "480", "kind": "enumvalue", "name": "reject", "value": "reject", "valueType": { - "$id": "444", + "$id": "481", "kind": "string", "decorators": [], "doc": "A sequence of textual characters.", @@ -5647,7 +6048,7 @@ "crossLanguageDefinitionId": "TypeSpec.string" }, "enumType": { - "$ref": "441" + "$ref": "478" }, "decorators": [] } @@ -5668,13 +6069,13 @@ "decorators": [] }, { - "$id": "445", + "$id": "482", "kind": "method", "name": "requiredNullableLiteralString", "serializedName": "requiredNullableLiteralString", "doc": "required nullable literal string", "type": { - "$ref": "193" + "$ref": "217" }, "location": "Body", "isApiVersion": false, @@ -5686,18 +6087,18 @@ "decorators": [] }, { - "$id": "446", + "$id": "483", "kind": "method", "name": "optionalLiteralInt", "serializedName": "optionalLiteralInt", "doc": "optional literal int", "type": { - "$id": "447", + "$id": "484", "kind": "enum", "name": "ThingOptionalLiteralInt", "crossLanguageDefinitionId": "", "valueType": { - "$id": "448", + "$id": "485", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -5705,12 +6106,12 @@ }, "values": [ { - "$id": "449", + "$id": "486", "kind": "enumvalue", "name": "456", "value": 456, "valueType": { - "$id": "450", + "$id": "487", "kind": "int32", "decorators": [], "doc": "A 32-bit integer. (`-2,147,483,648` to `2,147,483,647`)", @@ -5718,7 +6119,7 @@ "crossLanguageDefinitionId": "TypeSpec.int32" }, "enumType": { - "$ref": "447" + "$ref": "484" }, "decorators": [] } @@ -5739,18 +6140,18 @@ "decorators": [] }, { - "$id": "451", + "$id": "488", "kind": "method", "name": "optionalLiteralFloat", "serializedName": "optionalLiteralFloat", "doc": "optional literal float", "type": { - "$id": "452", + "$id": "489", "kind": "enum", "name": "ThingOptionalLiteralFloat", "crossLanguageDefinitionId": "", "valueType": { - "$id": "453", + "$id": "490", "kind": "float32", "name": "float32", "crossLanguageDefinitionId": "TypeSpec.float32", @@ -5758,12 +6159,12 @@ }, "values": [ { - "$id": "454", + "$id": "491", "kind": "enumvalue", "name": "4.56", "value": 4.56, "valueType": { - "$id": "455", + "$id": "492", "kind": "float32", "decorators": [], "doc": "A 32 bit floating point number. (`±1.5 x 10^−45` to `±3.4 x 10^38`)", @@ -5771,7 +6172,7 @@ "crossLanguageDefinitionId": "TypeSpec.float32" }, "enumType": { - "$ref": "452" + "$ref": "489" }, "decorators": [] } @@ -5792,7 +6193,7 @@ "decorators": [] }, { - "$id": "456", + "$id": "493", "kind": "method", "name": "optionalLiteralBool", "serializedName": "optionalLiteralBool", @@ -5810,13 +6211,13 @@ "decorators": [] }, { - "$id": "457", + "$id": "494", "kind": "method", "name": "requiredBadDescription", "serializedName": "requiredBadDescription", "doc": "description with xml <|endoftext|>", "type": { - "$id": "458", + "$id": "495", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5832,13 +6233,13 @@ "decorators": [] }, { - "$id": "459", + "$id": "496", "kind": "method", "name": "optionalNullableList", "serializedName": "optionalNullableList", "doc": "optional nullable collection", "type": { - "$ref": "200" + "$ref": "224" }, "location": "Body", "isApiVersion": false, @@ -5850,13 +6251,13 @@ "decorators": [] }, { - "$id": "460", + "$id": "497", "kind": "method", "name": "requiredNullableList", "serializedName": "requiredNullableList", "doc": "required nullable collection", "type": { - "$ref": "204" + "$ref": "228" }, "location": "Body", "isApiVersion": false, @@ -5868,12 +6269,12 @@ "decorators": [] }, { - "$id": "461", + "$id": "498", "kind": "method", "name": "requiredQueryParam", "serializedName": "requiredQueryParam", "type": { - "$ref": "138" + "$ref": "142" }, "location": "Query", "isApiVersion": false, @@ -5885,12 +6286,12 @@ "decorators": [] }, { - "$id": "462", + "$id": "499", "kind": "method", "name": "requiredHeader", "serializedName": "required-header", "type": { - "$ref": "140" + "$ref": "144" }, "location": "Header", "isApiVersion": false, @@ -5902,13 +6303,13 @@ "decorators": [] }, { - "$id": "463", + "$id": "500", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "124" + "$ref": "128" }, "location": "Header", "isApiVersion": false, @@ -5920,12 +6321,12 @@ "decorators": [] }, { - "$id": "464", + "$id": "501", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "126" + "$ref": "130" }, "location": "Header", "isApiVersion": false, @@ -5939,7 +6340,7 @@ ], "response": { "type": { - "$ref": "172" + "$ref": "196" } }, "isOverride": false, @@ -5948,7 +6349,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.anonymousBody" }, { - "$id": "465", + "$id": "502", "kind": "basic", "name": "friendlyModel", "accessibility": "public", @@ -5958,20 +6359,20 @@ ], "doc": "Model can have its friendly name", "operation": { - "$id": "466", + "$id": "503", "name": "friendlyModel", "resourceName": "SampleTypeSpec", "doc": "Model can have its friendly name", "accessibility": "public", "parameters": [ { - "$id": "467", + "$id": "504", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "142" + "$ref": "146" }, "isApiVersion": false, "optional": false, @@ -5982,12 +6383,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.friendlyModel.contentType" }, { - "$id": "468", + "$id": "505", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "144" + "$ref": "148" }, "isApiVersion": false, "optional": false, @@ -5998,12 +6399,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.friendlyModel.accept" }, { - "$id": "469", + "$id": "506", "kind": "body", "name": "friend", "serializedName": "friend", "type": { - "$ref": "253" + "$ref": "277" }, "isApiVersion": false, "contentTypes": [ @@ -6023,7 +6424,7 @@ 200 ], "bodyType": { - "$ref": "253" + "$ref": "277" }, "headers": [], "isErrorResponse": false, @@ -6046,13 +6447,13 @@ }, "parameters": [ { - "$id": "470", + "$id": "507", "kind": "method", "name": "name", "serializedName": "name", "doc": "name of the NotFriend", "type": { - "$id": "471", + "$id": "508", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6068,13 +6469,13 @@ "decorators": [] }, { - "$id": "472", + "$id": "509", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "142" + "$ref": "146" }, "location": "Header", "isApiVersion": false, @@ -6086,12 +6487,12 @@ "decorators": [] }, { - "$id": "473", + "$id": "510", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "144" + "$ref": "148" }, "location": "Header", "isApiVersion": false, @@ -6105,7 +6506,7 @@ ], "response": { "type": { - "$ref": "253" + "$ref": "277" } }, "isOverride": false, @@ -6114,7 +6515,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.friendlyModel" }, { - "$id": "474", + "$id": "511", "kind": "basic", "name": "addTimeHeader", "accessibility": "public", @@ -6123,23 +6524,23 @@ "2024-08-16-preview" ], "operation": { - "$id": "475", + "$id": "512", "name": "addTimeHeader", "resourceName": "SampleTypeSpec", "accessibility": "public", "parameters": [ { - "$id": "476", + "$id": "513", "kind": "header", "name": "repeatabilityFirstSent", "serializedName": "Repeatability-First-Sent", "type": { - "$id": "477", + "$id": "514", "kind": "utcDateTime", "name": "utcDateTime", "encode": "rfc7231", "wireType": { - "$id": "478", + "$id": "515", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6177,17 +6578,17 @@ }, "parameters": [ { - "$id": "479", + "$id": "516", "kind": "method", "name": "repeatabilityFirstSent", "serializedName": "Repeatability-First-Sent", "type": { - "$id": "480", + "$id": "517", "kind": "utcDateTime", "name": "utcDateTime", "encode": "rfc7231", "wireType": { - "$id": "481", + "$id": "518", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6213,7 +6614,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.addTimeHeader" }, { - "$id": "482", + "$id": "519", "kind": "basic", "name": "projectedNameModel", "accessibility": "public", @@ -6223,20 +6624,20 @@ ], "doc": "Model can have its projected name", "operation": { - "$id": "483", + "$id": "520", "name": "projectedNameModel", "resourceName": "SampleTypeSpec", "doc": "Model can have its projected name", "accessibility": "public", "parameters": [ { - "$id": "484", + "$id": "521", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "146" + "$ref": "150" }, "isApiVersion": false, "optional": false, @@ -6247,12 +6648,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.projectedNameModel.contentType" }, { - "$id": "485", + "$id": "522", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "148" + "$ref": "152" }, "isApiVersion": false, "optional": false, @@ -6263,12 +6664,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.projectedNameModel.accept" }, { - "$id": "486", + "$id": "523", "kind": "body", "name": "renamedModel", "serializedName": "renamedModel", "type": { - "$ref": "256" + "$ref": "280" }, "isApiVersion": false, "contentTypes": [ @@ -6288,7 +6689,7 @@ 200 ], "bodyType": { - "$ref": "256" + "$ref": "280" }, "headers": [], "isErrorResponse": false, @@ -6311,13 +6712,13 @@ }, "parameters": [ { - "$id": "487", + "$id": "524", "kind": "method", "name": "otherName", "serializedName": "otherName", "doc": "name of the ModelWithClientName", "type": { - "$id": "488", + "$id": "525", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6333,13 +6734,13 @@ "decorators": [] }, { - "$id": "489", + "$id": "526", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "146" + "$ref": "150" }, "location": "Header", "isApiVersion": false, @@ -6351,12 +6752,12 @@ "decorators": [] }, { - "$id": "490", + "$id": "527", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "148" + "$ref": "152" }, "location": "Header", "isApiVersion": false, @@ -6370,7 +6771,7 @@ ], "response": { "type": { - "$ref": "256" + "$ref": "280" } }, "isOverride": false, @@ -6379,7 +6780,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.projectedNameModel" }, { - "$id": "491", + "$id": "528", "kind": "basic", "name": "returnsAnonymousModel", "accessibility": "public", @@ -6389,19 +6790,19 @@ ], "doc": "return anonymous model", "operation": { - "$id": "492", + "$id": "529", "name": "returnsAnonymousModel", "resourceName": "SampleTypeSpec", "doc": "return anonymous model", "accessibility": "public", "parameters": [ { - "$id": "493", + "$id": "530", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "150" + "$ref": "154" }, "isApiVersion": false, "optional": false, @@ -6418,7 +6819,7 @@ 200 ], "bodyType": { - "$ref": "259" + "$ref": "283" }, "headers": [], "isErrorResponse": false, @@ -6438,12 +6839,12 @@ }, "parameters": [ { - "$id": "494", + "$id": "531", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "150" + "$ref": "154" }, "location": "Header", "isApiVersion": false, @@ -6457,7 +6858,7 @@ ], "response": { "type": { - "$ref": "259" + "$ref": "283" } }, "isOverride": false, @@ -6466,7 +6867,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.returnsAnonymousModel" }, { - "$id": "495", + "$id": "532", "kind": "basic", "name": "getUnknownValue", "accessibility": "public", @@ -6476,19 +6877,19 @@ ], "doc": "get extensible enum", "operation": { - "$id": "496", + "$id": "533", "name": "getUnknownValue", "resourceName": "SampleTypeSpec", "doc": "get extensible enum", "accessibility": "public", "parameters": [ { - "$id": "497", + "$id": "534", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$id": "498", + "$id": "535", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6509,7 +6910,7 @@ 200 ], "bodyType": { - "$id": "499", + "$id": "536", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6540,12 +6941,12 @@ }, "parameters": [ { - "$id": "500", + "$id": "537", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "498" + "$ref": "535" }, "location": "Header", "isApiVersion": false, @@ -6559,7 +6960,7 @@ ], "response": { "type": { - "$ref": "499" + "$ref": "536" } }, "isOverride": false, @@ -6568,7 +6969,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.getUnknownValue" }, { - "$id": "501", + "$id": "538", "kind": "basic", "name": "internalProtocol", "accessibility": "public", @@ -6578,20 +6979,20 @@ ], "doc": "When set protocol false and convenient true, then the protocol method should be internal", "operation": { - "$id": "502", + "$id": "539", "name": "internalProtocol", "resourceName": "SampleTypeSpec", "doc": "When set protocol false and convenient true, then the protocol method should be internal", "accessibility": "public", "parameters": [ { - "$id": "503", + "$id": "540", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "152" + "$ref": "156" }, "isApiVersion": false, "optional": false, @@ -6602,12 +7003,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.internalProtocol.contentType" }, { - "$id": "504", + "$id": "541", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "154" + "$ref": "158" }, "isApiVersion": false, "optional": false, @@ -6618,12 +7019,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.internalProtocol.accept" }, { - "$id": "505", + "$id": "542", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "172" + "$ref": "196" }, "isApiVersion": false, "contentTypes": [ @@ -6643,7 +7044,7 @@ 200 ], "bodyType": { - "$ref": "172" + "$ref": "196" }, "headers": [], "isErrorResponse": false, @@ -6666,12 +7067,12 @@ }, "parameters": [ { - "$id": "506", + "$id": "543", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "172" + "$ref": "196" }, "location": "Body", "isApiVersion": false, @@ -6683,13 +7084,13 @@ "decorators": [] }, { - "$id": "507", + "$id": "544", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "152" + "$ref": "156" }, "location": "Header", "isApiVersion": false, @@ -6701,12 +7102,12 @@ "decorators": [] }, { - "$id": "508", + "$id": "545", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "154" + "$ref": "158" }, "location": "Header", "isApiVersion": false, @@ -6720,7 +7121,7 @@ ], "response": { "type": { - "$ref": "172" + "$ref": "196" } }, "isOverride": false, @@ -6729,7 +7130,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.internalProtocol" }, { - "$id": "509", + "$id": "546", "kind": "basic", "name": "stillConvenient", "accessibility": "public", @@ -6739,7 +7140,7 @@ ], "doc": "When set protocol false and convenient true, the convenient method should be generated even it has the same signature as protocol one", "operation": { - "$id": "510", + "$id": "547", "name": "stillConvenient", "resourceName": "SampleTypeSpec", "doc": "When set protocol false and convenient true, the convenient method should be generated even it has the same signature as protocol one", @@ -6771,7 +7172,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.stillConvenient" }, { - "$id": "511", + "$id": "548", "kind": "basic", "name": "headAsBoolean", "accessibility": "public", @@ -6781,19 +7182,19 @@ ], "doc": "head as boolean.", "operation": { - "$id": "512", + "$id": "549", "name": "headAsBoolean", "resourceName": "SampleTypeSpec", "doc": "head as boolean.", "accessibility": "public", "parameters": [ { - "$id": "513", + "$id": "550", "kind": "path", "name": "id", "serializedName": "id", "type": { - "$id": "514", + "$id": "551", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6831,12 +7232,12 @@ }, "parameters": [ { - "$id": "515", + "$id": "552", "kind": "method", "name": "id", "serializedName": "id", "type": { - "$id": "516", + "$id": "553", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6859,7 +7260,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.headAsBoolean" }, { - "$id": "517", + "$id": "554", "kind": "basic", "name": "WithApiVersion", "accessibility": "public", @@ -6869,19 +7270,19 @@ ], "doc": "Return hi again", "operation": { - "$id": "518", + "$id": "555", "name": "WithApiVersion", "resourceName": "SampleTypeSpec", "doc": "Return hi again", "accessibility": "public", "parameters": [ { - "$id": "519", + "$id": "556", "kind": "header", "name": "p1", "serializedName": "p1", "type": { - "$id": "520", + "$id": "557", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6896,12 +7297,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.WithApiVersion.p1" }, { - "$id": "521", + "$id": "558", "kind": "query", "name": "apiVersion", "serializedName": "apiVersion", "type": { - "$id": "522", + "$id": "559", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6911,7 +7312,7 @@ "explode": false, "defaultValue": { "type": { - "$id": "523", + "$id": "560", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string" @@ -6945,12 +7346,12 @@ }, "parameters": [ { - "$id": "524", + "$id": "561", "kind": "method", "name": "p1", "serializedName": "p1", "type": { - "$id": "525", + "$id": "562", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6973,7 +7374,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.WithApiVersion" }, { - "$id": "526", + "$id": "563", "kind": "paging", "name": "ListWithNextLink", "accessibility": "public", @@ -6983,19 +7384,19 @@ ], "doc": "List things with nextlink", "operation": { - "$id": "527", + "$id": "564", "name": "ListWithNextLink", "resourceName": "SampleTypeSpec", "doc": "List things with nextlink", "accessibility": "public", "parameters": [ { - "$id": "528", + "$id": "565", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "156" + "$ref": "160" }, "isApiVersion": false, "optional": false, @@ -7012,7 +7413,7 @@ 200 ], "bodyType": { - "$ref": "260" + "$ref": "284" }, "headers": [], "isErrorResponse": false, @@ -7032,12 +7433,12 @@ }, "parameters": [ { - "$id": "529", + "$id": "566", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "156" + "$ref": "160" }, "location": "Header", "isApiVersion": false, @@ -7051,7 +7452,7 @@ ], "response": { "type": { - "$ref": "262" + "$ref": "286" }, "resultSegments": [ "things" @@ -7075,7 +7476,7 @@ } }, { - "$id": "530", + "$id": "567", "kind": "paging", "name": "ListWithStringNextLink", "accessibility": "public", @@ -7085,19 +7486,19 @@ ], "doc": "List things with nextlink", "operation": { - "$id": "531", + "$id": "568", "name": "ListWithStringNextLink", "resourceName": "SampleTypeSpec", "doc": "List things with nextlink", "accessibility": "public", "parameters": [ { - "$id": "532", + "$id": "569", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "158" + "$ref": "162" }, "isApiVersion": false, "optional": false, @@ -7114,7 +7515,7 @@ 200 ], "bodyType": { - "$ref": "265" + "$ref": "289" }, "headers": [], "isErrorResponse": false, @@ -7134,12 +7535,12 @@ }, "parameters": [ { - "$id": "533", + "$id": "570", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "158" + "$ref": "162" }, "location": "Header", "isApiVersion": false, @@ -7153,7 +7554,7 @@ ], "response": { "type": { - "$ref": "262" + "$ref": "286" }, "resultSegments": [ "things" @@ -7177,7 +7578,7 @@ } }, { - "$id": "534", + "$id": "571", "kind": "paging", "name": "ListWithContinuationToken", "accessibility": "public", @@ -7187,19 +7588,19 @@ ], "doc": "List things with continuation token", "operation": { - "$id": "535", + "$id": "572", "name": "ListWithContinuationToken", "resourceName": "SampleTypeSpec", "doc": "List things with continuation token", "accessibility": "public", "parameters": [ { - "$id": "536", + "$id": "573", "kind": "query", "name": "token", "serializedName": "token", "type": { - "$id": "537", + "$id": "574", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7214,12 +7615,12 @@ "readOnly": false }, { - "$id": "538", + "$id": "575", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "160" + "$ref": "164" }, "isApiVersion": false, "optional": false, @@ -7236,7 +7637,7 @@ 200 ], "bodyType": { - "$ref": "269" + "$ref": "293" }, "headers": [], "isErrorResponse": false, @@ -7256,12 +7657,12 @@ }, "parameters": [ { - "$id": "539", + "$id": "576", "kind": "method", "name": "token", "serializedName": "token", "type": { - "$id": "540", + "$id": "577", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7277,12 +7678,12 @@ "decorators": [] }, { - "$id": "541", + "$id": "578", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "160" + "$ref": "164" }, "location": "Header", "isApiVersion": false, @@ -7296,7 +7697,7 @@ ], "response": { "type": { - "$ref": "262" + "$ref": "286" }, "resultSegments": [ "things" @@ -7312,7 +7713,7 @@ ], "continuationToken": { "parameter": { - "$ref": "536" + "$ref": "573" }, "responseSegments": [ "nextToken" @@ -7323,7 +7724,7 @@ } }, { - "$id": "542", + "$id": "579", "kind": "paging", "name": "ListWithContinuationTokenHeaderResponse", "accessibility": "public", @@ -7333,19 +7734,19 @@ ], "doc": "List things with continuation token header response", "operation": { - "$id": "543", + "$id": "580", "name": "ListWithContinuationTokenHeaderResponse", "resourceName": "SampleTypeSpec", "doc": "List things with continuation token header response", "accessibility": "public", "parameters": [ { - "$id": "544", + "$id": "581", "kind": "query", "name": "token", "serializedName": "token", "type": { - "$id": "545", + "$id": "582", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7360,12 +7761,12 @@ "readOnly": false }, { - "$id": "546", + "$id": "583", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "162" + "$ref": "166" }, "isApiVersion": false, "optional": false, @@ -7382,14 +7783,14 @@ 200 ], "bodyType": { - "$ref": "273" + "$ref": "297" }, "headers": [ { "name": "nextToken", "nameInResponse": "next-token", "type": { - "$id": "547", + "$id": "584", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7414,12 +7815,12 @@ }, "parameters": [ { - "$id": "548", + "$id": "585", "kind": "method", "name": "token", "serializedName": "token", "type": { - "$id": "549", + "$id": "586", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7435,12 +7836,12 @@ "decorators": [] }, { - "$id": "550", + "$id": "587", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "162" + "$ref": "166" }, "location": "Header", "isApiVersion": false, @@ -7454,7 +7855,7 @@ ], "response": { "type": { - "$ref": "262" + "$ref": "286" }, "resultSegments": [ "things" @@ -7470,7 +7871,7 @@ ], "continuationToken": { "parameter": { - "$ref": "544" + "$ref": "581" }, "responseSegments": [ "next-token" @@ -7481,7 +7882,7 @@ } }, { - "$id": "551", + "$id": "588", "kind": "paging", "name": "ListWithPaging", "accessibility": "public", @@ -7491,19 +7892,19 @@ ], "doc": "List things with paging", "operation": { - "$id": "552", + "$id": "589", "name": "ListWithPaging", "resourceName": "SampleTypeSpec", "doc": "List things with paging", "accessibility": "public", "parameters": [ { - "$id": "553", + "$id": "590", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "164" + "$ref": "168" }, "isApiVersion": false, "optional": false, @@ -7520,7 +7921,7 @@ 200 ], "bodyType": { - "$ref": "275" + "$ref": "299" }, "headers": [], "isErrorResponse": false, @@ -7540,12 +7941,12 @@ }, "parameters": [ { - "$id": "554", + "$id": "591", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "164" + "$ref": "168" }, "location": "Header", "isApiVersion": false, @@ -7559,7 +7960,7 @@ ], "response": { "type": { - "$ref": "262" + "$ref": "286" }, "resultSegments": [ "items" @@ -7577,7 +7978,7 @@ } }, { - "$id": "555", + "$id": "592", "kind": "basic", "name": "EmbeddedParameters", "accessibility": "public", @@ -7587,20 +7988,20 @@ ], "doc": "An operation with embedded parameters within the body", "operation": { - "$id": "556", + "$id": "593", "name": "EmbeddedParameters", "resourceName": "SampleTypeSpec", "doc": "An operation with embedded parameters within the body", "accessibility": "public", "parameters": [ { - "$id": "557", + "$id": "594", "kind": "header", "name": "requiredHeader", "serializedName": "required-header", "doc": "required header parameter", "type": { - "$id": "558", + "$id": "595", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7615,13 +8016,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ModelWithEmbeddedNonBodyParameters.requiredHeader" }, { - "$id": "559", + "$id": "596", "kind": "header", "name": "optionalHeader", "serializedName": "optional-header", "doc": "optional header parameter", "type": { - "$id": "560", + "$id": "597", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7636,13 +8037,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ModelWithEmbeddedNonBodyParameters.optionalHeader" }, { - "$id": "561", + "$id": "598", "kind": "query", "name": "requiredQuery", "serializedName": "requiredQuery", "doc": "required query parameter", "type": { - "$id": "562", + "$id": "599", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7657,13 +8058,13 @@ "readOnly": false }, { - "$id": "563", + "$id": "600", "kind": "query", "name": "optionalQuery", "serializedName": "optionalQuery", "doc": "optional query parameter", "type": { - "$id": "564", + "$id": "601", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7678,13 +8079,13 @@ "readOnly": false }, { - "$id": "565", + "$id": "602", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "166" + "$ref": "170" }, "isApiVersion": false, "optional": false, @@ -7695,12 +8096,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.EmbeddedParameters.contentType" }, { - "$id": "566", + "$id": "603", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "277" + "$ref": "301" }, "isApiVersion": false, "contentTypes": [ @@ -7737,12 +8138,12 @@ }, "parameters": [ { - "$id": "567", + "$id": "604", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "277" + "$ref": "301" }, "location": "Body", "isApiVersion": false, @@ -7754,13 +8155,13 @@ "decorators": [] }, { - "$id": "568", + "$id": "605", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "166" + "$ref": "170" }, "location": "Header", "isApiVersion": false, @@ -7779,7 +8180,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.EmbeddedParameters" }, { - "$id": "569", + "$id": "606", "kind": "basic", "name": "DynamicModelOperation", "accessibility": "public", @@ -7789,20 +8190,20 @@ ], "doc": "An operation with a dynamic model", "operation": { - "$id": "570", + "$id": "607", "name": "DynamicModelOperation", "resourceName": "SampleTypeSpec", "doc": "An operation with a dynamic model", "accessibility": "public", "parameters": [ { - "$id": "571", + "$id": "608", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "168" + "$ref": "172" }, "isApiVersion": false, "optional": false, @@ -7813,12 +8214,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.DynamicModelOperation.contentType" }, { - "$id": "572", + "$id": "609", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "288" + "$ref": "312" }, "isApiVersion": false, "contentTypes": [ @@ -7855,12 +8256,12 @@ }, "parameters": [ { - "$id": "573", + "$id": "610", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "288" + "$ref": "312" }, "location": "Body", "isApiVersion": false, @@ -7872,13 +8273,13 @@ "decorators": [] }, { - "$id": "574", + "$id": "611", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "168" + "$ref": "172" }, "location": "Header", "isApiVersion": false, @@ -7899,12 +8300,12 @@ ], "parameters": [ { - "$id": "575", + "$id": "612", "kind": "endpoint", "name": "sampleTypeSpecUrl", "serializedName": "sampleTypeSpecUrl", "type": { - "$id": "576", + "$id": "613", "kind": "url", "name": "endpoint", "crossLanguageDefinitionId": "TypeSpec.url" @@ -7919,12 +8320,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.sampleTypeSpecUrl" }, { - "$id": "577", + "$id": "614", "kind": "method", "name": "apiVersion", "serializedName": "apiVersion", "type": { - "$id": "578", + "$id": "615", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7934,7 +8335,7 @@ "isApiVersion": true, "defaultValue": { "type": { - "$id": "579", + "$id": "616", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string" @@ -7958,54 +8359,213 @@ ], "children": [ { - "$id": "580", + "$id": "617", "kind": "client", - "name": "Metrics", + "name": "AnimalOperations", "namespace": "SampleTypeSpec", "methods": [ { - "$id": "581", + "$id": "618", "kind": "basic", - "name": "getWidgetMetrics", + "name": "updatePetAsAnimal", "accessibility": "public", "apiVersions": [ "2024-07-16-preview", "2024-08-16-preview" ], - "doc": "Get Widget metrics for given day of week", + "doc": "Update a pet as an animal", "operation": { - "$id": "582", - "name": "getWidgetMetrics", - "resourceName": "Metrics", - "doc": "Get Widget metrics for given day of week", + "$id": "619", + "name": "updatePetAsAnimal", + "resourceName": "AnimalOperations", + "doc": "Update a pet as an animal", "accessibility": "public", "parameters": [ { - "$id": "583", - "kind": "path", - "name": "day", - "serializedName": "day", + "$id": "620", + "kind": "header", + "name": "contentType", + "serializedName": "Content-Type", + "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "57" + "$ref": "174" }, "isApiVersion": false, - "explode": false, - "style": "simple", - "allowReserved": false, - "skipUrlEncoding": false, + "optional": false, + "isContentType": true, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal.contentType" + }, + { + "$id": "621", + "kind": "header", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "176" + }, + "isApiVersion": false, + "optional": false, + "isContentType": false, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal.accept" + }, + { + "$id": "622", + "kind": "body", + "name": "animal", + "serializedName": "animal", + "type": { + "$ref": "350" + }, + "isApiVersion": false, + "contentTypes": [ + "application/json" + ], + "defaultContentType": "application/json", "optional": false, "scope": "Method", "decorators": [], "readOnly": false, - "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.day" + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal.animal" + } + ], + "responses": [ + { + "statusCodes": [ + 200 + ], + "bodyType": { + "$ref": "350" + }, + "headers": [], + "isErrorResponse": false, + "contentTypes": [ + "application/json" + ] + } + ], + "httpMethod": "PUT", + "uri": "{sampleTypeSpecUrl}", + "path": "/animals/pet/as-animal", + "requestMediaTypes": [ + "application/json" + ], + "bufferResponse": true, + "generateProtocolMethod": true, + "generateConvenienceMethod": true, + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal", + "decorators": [] + }, + "parameters": [ + { + "$id": "623", + "kind": "method", + "name": "animal", + "serializedName": "animal", + "type": { + "$ref": "350" + }, + "location": "Body", + "isApiVersion": false, + "optional": false, + "scope": "Method", + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal.animal", + "readOnly": false, + "access": "public", + "decorators": [] + }, + { + "$id": "624", + "kind": "method", + "name": "contentType", + "serializedName": "Content-Type", + "doc": "Body parameter's content type. Known values are application/json", + "type": { + "$ref": "174" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal.contentType", + "readOnly": false, + "access": "public", + "decorators": [] + }, + { + "$id": "625", + "kind": "method", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "176" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal.accept", + "readOnly": false, + "access": "public", + "decorators": [] + } + ], + "response": { + "type": { + "$ref": "350" + } + }, + "isOverride": false, + "generateConvenient": true, + "generateProtocol": true, + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal" + }, + { + "$id": "626", + "kind": "basic", + "name": "updateDogAsAnimal", + "accessibility": "public", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "doc": "Update a dog as an animal", + "operation": { + "$id": "627", + "name": "updateDogAsAnimal", + "resourceName": "AnimalOperations", + "doc": "Update a dog as an animal", + "accessibility": "public", + "parameters": [ + { + "$id": "628", + "kind": "header", + "name": "contentType", + "serializedName": "Content-Type", + "doc": "Body parameter's content type. Known values are application/json", + "type": { + "$ref": "178" + }, + "isApiVersion": false, + "optional": false, + "isContentType": true, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal.contentType" }, { - "$id": "584", + "$id": "629", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "170" + "$ref": "180" }, "isApiVersion": false, "optional": false, @@ -8013,7 +8573,26 @@ "scope": "Constant", "readOnly": false, "decorators": [], - "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.accept" + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal.accept" + }, + { + "$id": "630", + "kind": "body", + "name": "animal", + "serializedName": "animal", + "type": { + "$ref": "350" + }, + "isApiVersion": false, + "contentTypes": [ + "application/json" + ], + "defaultContentType": "application/json", + "optional": false, + "scope": "Method", + "decorators": [], + "readOnly": false, + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal.animal" } ], "responses": [ @@ -8022,7 +8601,7 @@ 200 ], "bodyType": { - "$ref": "326" + "$ref": "350" }, "headers": [], "isErrorResponse": false, @@ -8031,46 +8610,67 @@ ] } ], - "httpMethod": "GET", + "httpMethod": "PUT", "uri": "{sampleTypeSpecUrl}", - "path": "/metrics/widgets/daysOfWeek/{day}", + "path": "/animals/dog/as-animal", + "requestMediaTypes": [ + "application/json" + ], "bufferResponse": true, "generateProtocolMethod": true, "generateConvenienceMethod": true, - "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics", + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal", "decorators": [] }, "parameters": [ { - "$id": "585", + "$id": "631", "kind": "method", - "name": "day", - "serializedName": "day", + "name": "animal", + "serializedName": "animal", "type": { - "$ref": "57" + "$ref": "350" }, - "location": "Path", + "location": "Body", "isApiVersion": false, "optional": false, "scope": "Method", - "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.day", + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal.animal", + "readOnly": false, + "access": "public", + "decorators": [] + }, + { + "$id": "632", + "kind": "method", + "name": "contentType", + "serializedName": "Content-Type", + "doc": "Body parameter's content type. Known values are application/json", + "type": { + "$ref": "178" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal.contentType", "readOnly": false, "access": "public", "decorators": [] }, { - "$id": "586", + "$id": "633", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "170" + "$ref": "180" }, "location": "Header", "isApiVersion": false, "optional": false, "scope": "Constant", - "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.accept", + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal.accept", "readOnly": false, "access": "public", "decorators": [] @@ -8078,23 +8678,749 @@ ], "response": { "type": { - "$ref": "326" + "$ref": "350" } }, "isOverride": false, "generateConvenient": true, "generateProtocol": true, - "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics" + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal" } ], "parameters": [ { - "$id": "587", + "$id": "634", + "kind": "endpoint", + "name": "sampleTypeSpecUrl", + "serializedName": "sampleTypeSpecUrl", + "type": { + "$id": "635", + "kind": "url", + "name": "endpoint", + "crossLanguageDefinitionId": "TypeSpec.url" + }, + "isApiVersion": false, + "optional": false, + "scope": "Client", + "isEndpoint": true, + "serverUrlTemplate": "{sampleTypeSpecUrl}", + "skipUrlEncoding": false, + "readOnly": false, + "crossLanguageDefinitionId": "SampleTypeSpec.sampleTypeSpecUrl" + } + ], + "initializedBy": 0, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "parent": { + "$ref": "368" + } + }, + { + "$id": "636", + "kind": "client", + "name": "PetOperations", + "namespace": "SampleTypeSpec", + "methods": [ + { + "$id": "637", + "kind": "basic", + "name": "updatePetAsPet", + "accessibility": "public", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "doc": "Update a pet as a pet", + "operation": { + "$id": "638", + "name": "updatePetAsPet", + "resourceName": "PetOperations", + "doc": "Update a pet as a pet", + "accessibility": "public", + "parameters": [ + { + "$id": "639", + "kind": "header", + "name": "contentType", + "serializedName": "Content-Type", + "doc": "Body parameter's content type. Known values are application/json", + "type": { + "$ref": "182" + }, + "isApiVersion": false, + "optional": false, + "isContentType": true, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet.contentType" + }, + { + "$id": "640", + "kind": "header", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "184" + }, + "isApiVersion": false, + "optional": false, + "isContentType": false, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet.accept" + }, + { + "$id": "641", + "kind": "body", + "name": "pet", + "serializedName": "pet", + "type": { + "$ref": "355" + }, + "isApiVersion": false, + "contentTypes": [ + "application/json" + ], + "defaultContentType": "application/json", + "optional": false, + "scope": "Method", + "decorators": [], + "readOnly": false, + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet.pet" + } + ], + "responses": [ + { + "statusCodes": [ + 200 + ], + "bodyType": { + "$ref": "355" + }, + "headers": [], + "isErrorResponse": false, + "contentTypes": [ + "application/json" + ] + } + ], + "httpMethod": "PUT", + "uri": "{sampleTypeSpecUrl}", + "path": "/pets/pet/as-pet", + "requestMediaTypes": [ + "application/json" + ], + "bufferResponse": true, + "generateProtocolMethod": true, + "generateConvenienceMethod": true, + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet", + "decorators": [] + }, + "parameters": [ + { + "$id": "642", + "kind": "method", + "name": "pet", + "serializedName": "pet", + "type": { + "$ref": "355" + }, + "location": "Body", + "isApiVersion": false, + "optional": false, + "scope": "Method", + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet.pet", + "readOnly": false, + "access": "public", + "decorators": [] + }, + { + "$id": "643", + "kind": "method", + "name": "contentType", + "serializedName": "Content-Type", + "doc": "Body parameter's content type. Known values are application/json", + "type": { + "$ref": "182" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet.contentType", + "readOnly": false, + "access": "public", + "decorators": [] + }, + { + "$id": "644", + "kind": "method", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "184" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet.accept", + "readOnly": false, + "access": "public", + "decorators": [] + } + ], + "response": { + "type": { + "$ref": "355" + } + }, + "isOverride": false, + "generateConvenient": true, + "generateProtocol": true, + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet" + }, + { + "$id": "645", + "kind": "basic", + "name": "updateDogAsPet", + "accessibility": "public", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "doc": "Update a dog as a pet", + "operation": { + "$id": "646", + "name": "updateDogAsPet", + "resourceName": "PetOperations", + "doc": "Update a dog as a pet", + "accessibility": "public", + "parameters": [ + { + "$id": "647", + "kind": "header", + "name": "contentType", + "serializedName": "Content-Type", + "doc": "Body parameter's content type. Known values are application/json", + "type": { + "$ref": "186" + }, + "isApiVersion": false, + "optional": false, + "isContentType": true, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet.contentType" + }, + { + "$id": "648", + "kind": "header", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "188" + }, + "isApiVersion": false, + "optional": false, + "isContentType": false, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet.accept" + }, + { + "$id": "649", + "kind": "body", + "name": "pet", + "serializedName": "pet", + "type": { + "$ref": "355" + }, + "isApiVersion": false, + "contentTypes": [ + "application/json" + ], + "defaultContentType": "application/json", + "optional": false, + "scope": "Method", + "decorators": [], + "readOnly": false, + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet.pet" + } + ], + "responses": [ + { + "statusCodes": [ + 200 + ], + "bodyType": { + "$ref": "355" + }, + "headers": [], + "isErrorResponse": false, + "contentTypes": [ + "application/json" + ] + } + ], + "httpMethod": "PUT", + "uri": "{sampleTypeSpecUrl}", + "path": "/pets/dog/as-pet", + "requestMediaTypes": [ + "application/json" + ], + "bufferResponse": true, + "generateProtocolMethod": true, + "generateConvenienceMethod": true, + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet", + "decorators": [] + }, + "parameters": [ + { + "$id": "650", + "kind": "method", + "name": "pet", + "serializedName": "pet", + "type": { + "$ref": "355" + }, + "location": "Body", + "isApiVersion": false, + "optional": false, + "scope": "Method", + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet.pet", + "readOnly": false, + "access": "public", + "decorators": [] + }, + { + "$id": "651", + "kind": "method", + "name": "contentType", + "serializedName": "Content-Type", + "doc": "Body parameter's content type. Known values are application/json", + "type": { + "$ref": "186" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet.contentType", + "readOnly": false, + "access": "public", + "decorators": [] + }, + { + "$id": "652", + "kind": "method", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "188" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet.accept", + "readOnly": false, + "access": "public", + "decorators": [] + } + ], + "response": { + "type": { + "$ref": "355" + } + }, + "isOverride": false, + "generateConvenient": true, + "generateProtocol": true, + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet" + } + ], + "parameters": [ + { + "$id": "653", + "kind": "endpoint", + "name": "sampleTypeSpecUrl", + "serializedName": "sampleTypeSpecUrl", + "type": { + "$id": "654", + "kind": "url", + "name": "endpoint", + "crossLanguageDefinitionId": "TypeSpec.url" + }, + "isApiVersion": false, + "optional": false, + "scope": "Client", + "isEndpoint": true, + "serverUrlTemplate": "{sampleTypeSpecUrl}", + "skipUrlEncoding": false, + "readOnly": false, + "crossLanguageDefinitionId": "SampleTypeSpec.sampleTypeSpecUrl" + } + ], + "initializedBy": 0, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "parent": { + "$ref": "368" + } + }, + { + "$id": "655", + "kind": "client", + "name": "DogOperations", + "namespace": "SampleTypeSpec", + "methods": [ + { + "$id": "656", + "kind": "basic", + "name": "updateDogAsDog", + "accessibility": "public", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "doc": "Update a dog as a dog", + "operation": { + "$id": "657", + "name": "updateDogAsDog", + "resourceName": "DogOperations", + "doc": "Update a dog as a dog", + "accessibility": "public", + "parameters": [ + { + "$id": "658", + "kind": "header", + "name": "contentType", + "serializedName": "Content-Type", + "doc": "Body parameter's content type. Known values are application/json", + "type": { + "$ref": "190" + }, + "isApiVersion": false, + "optional": false, + "isContentType": true, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog.contentType" + }, + { + "$id": "659", + "kind": "header", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "192" + }, + "isApiVersion": false, + "optional": false, + "isContentType": false, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog.accept" + }, + { + "$id": "660", + "kind": "body", + "name": "dog", + "serializedName": "dog", + "type": { + "$ref": "359" + }, + "isApiVersion": false, + "contentTypes": [ + "application/json" + ], + "defaultContentType": "application/json", + "optional": false, + "scope": "Method", + "decorators": [], + "readOnly": false, + "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog.dog" + } + ], + "responses": [ + { + "statusCodes": [ + 200 + ], + "bodyType": { + "$ref": "359" + }, + "headers": [], + "isErrorResponse": false, + "contentTypes": [ + "application/json" + ] + } + ], + "httpMethod": "PUT", + "uri": "{sampleTypeSpecUrl}", + "path": "/dogs/dog/as-dog", + "requestMediaTypes": [ + "application/json" + ], + "bufferResponse": true, + "generateProtocolMethod": true, + "generateConvenienceMethod": true, + "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog", + "decorators": [] + }, + "parameters": [ + { + "$id": "661", + "kind": "method", + "name": "dog", + "serializedName": "dog", + "type": { + "$ref": "359" + }, + "location": "Body", + "isApiVersion": false, + "optional": false, + "scope": "Method", + "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog.dog", + "readOnly": false, + "access": "public", + "decorators": [] + }, + { + "$id": "662", + "kind": "method", + "name": "contentType", + "serializedName": "Content-Type", + "doc": "Body parameter's content type. Known values are application/json", + "type": { + "$ref": "190" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog.contentType", + "readOnly": false, + "access": "public", + "decorators": [] + }, + { + "$id": "663", + "kind": "method", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "192" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog.accept", + "readOnly": false, + "access": "public", + "decorators": [] + } + ], + "response": { + "type": { + "$ref": "359" + } + }, + "isOverride": false, + "generateConvenient": true, + "generateProtocol": true, + "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog" + } + ], + "parameters": [ + { + "$id": "664", + "kind": "endpoint", + "name": "sampleTypeSpecUrl", + "serializedName": "sampleTypeSpecUrl", + "type": { + "$id": "665", + "kind": "url", + "name": "endpoint", + "crossLanguageDefinitionId": "TypeSpec.url" + }, + "isApiVersion": false, + "optional": false, + "scope": "Client", + "isEndpoint": true, + "serverUrlTemplate": "{sampleTypeSpecUrl}", + "skipUrlEncoding": false, + "readOnly": false, + "crossLanguageDefinitionId": "SampleTypeSpec.sampleTypeSpecUrl" + } + ], + "initializedBy": 0, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "parent": { + "$ref": "368" + } + }, + { + "$id": "666", + "kind": "client", + "name": "Metrics", + "namespace": "SampleTypeSpec", + "methods": [ + { + "$id": "667", + "kind": "basic", + "name": "getWidgetMetrics", + "accessibility": "public", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "doc": "Get Widget metrics for given day of week", + "operation": { + "$id": "668", + "name": "getWidgetMetrics", + "resourceName": "Metrics", + "doc": "Get Widget metrics for given day of week", + "accessibility": "public", + "parameters": [ + { + "$id": "669", + "kind": "path", + "name": "day", + "serializedName": "day", + "type": { + "$ref": "57" + }, + "isApiVersion": false, + "explode": false, + "style": "simple", + "allowReserved": false, + "skipUrlEncoding": false, + "optional": false, + "scope": "Method", + "decorators": [], + "readOnly": false, + "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.day" + }, + { + "$id": "670", + "kind": "header", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "194" + }, + "isApiVersion": false, + "optional": false, + "isContentType": false, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.accept" + } + ], + "responses": [ + { + "statusCodes": [ + 200 + ], + "bodyType": { + "$ref": "363" + }, + "headers": [], + "isErrorResponse": false, + "contentTypes": [ + "application/json" + ] + } + ], + "httpMethod": "GET", + "uri": "{sampleTypeSpecUrl}", + "path": "/metrics/widgets/daysOfWeek/{day}", + "bufferResponse": true, + "generateProtocolMethod": true, + "generateConvenienceMethod": true, + "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics", + "decorators": [] + }, + "parameters": [ + { + "$id": "671", + "kind": "method", + "name": "day", + "serializedName": "day", + "type": { + "$ref": "57" + }, + "location": "Path", + "isApiVersion": false, + "optional": false, + "scope": "Method", + "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.day", + "readOnly": false, + "access": "public", + "decorators": [] + }, + { + "$id": "672", + "kind": "method", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "194" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.accept", + "readOnly": false, + "access": "public", + "decorators": [] + } + ], + "response": { + "type": { + "$ref": "363" + } + }, + "isOverride": false, + "generateConvenient": true, + "generateProtocol": true, + "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics" + } + ], + "parameters": [ + { + "$id": "673", "kind": "endpoint", "name": "sampleTypeSpecUrl", "serializedName": "sampleTypeSpecUrl", "type": { - "$id": "588", + "$id": "674", "kind": "url", "name": "endpoint", "crossLanguageDefinitionId": "TypeSpec.url" @@ -8117,7 +9443,7 @@ "2024-08-16-preview" ], "parent": { - "$ref": "331" + "$ref": "368" } } ] From 4ad4a9c1deac5bb43adddf3961119f61b6efd261 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Wed, 3 Dec 2025 21:24:25 -0800 Subject: [PATCH 8/8] minor: removed unnessary args --- .../src/Providers/ModelProvider.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs index d1b6e172bad..b126b0338ad 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs @@ -758,14 +758,14 @@ p.Property is null : DiscriminatorLiteral; var args = baseParameters.Where(p => p.Property?.IsDiscriminator != true) - .Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor, includeDiscriminatorParameter: false)); + .Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor)); constructorInitializer = new ConstructorInitializer(true, [discriminatorExpression, .. args]); } else { // Standard base constructor call - constructorInitializer = new ConstructorInitializer(true, [.. baseParameters.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor, includeDiscriminatorParameter: false))]); + constructorInitializer = new ConstructorInitializer(true, [.. baseParameters.Select(p => GetExpressionForCtor(p, overriddenProperties, isInitializationConstructor))]); } } else @@ -843,20 +843,13 @@ p.Property is null return null; } - private ValueExpression GetExpressionForCtor(ParameterProvider parameter, HashSet overriddenProperties, bool isPrimaryConstructor, bool includeDiscriminatorParameter = false) + private ValueExpression GetExpressionForCtor(ParameterProvider parameter, HashSet overriddenProperties, bool isPrimaryConstructor) { if (parameter.Property is not null && parameter.Property.IsDiscriminator && _inputModel.DiscriminatorValue != null) { if (isPrimaryConstructor) { - if (includeDiscriminatorParameter && _isMultiLevelDiscriminator) - { - return parameter; - } - else - { - return DiscriminatorValueExpression ?? throw new InvalidOperationException($"invalid discriminator {_inputModel.DiscriminatorValue} for property {parameter.Property.Name}"); - } + return DiscriminatorValueExpression ?? throw new InvalidOperationException($"invalid discriminator {_inputModel.DiscriminatorValue} for property {parameter.Property.Name}"); } else if (IsUnknownDiscriminatorModel) {