From 2df4960967286d8006971bad909bcaae619b18c9 Mon Sep 17 00:00:00 2001 From: Josh Love Date: Fri, 23 Oct 2026 13:25:34 -0700 Subject: [PATCH 1/9] feat(http-client-csharp): emit obsolete attributes for deprecated APIs Preserve non-obsolete GA contracts and compatibility overloads while exposing TypeSpec deprecation messages on new APIs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- packages/http-client-csharp/docs/emitter.md | 15 + .../emitter/test/Unit/model-type.test.ts | 20 + .../test/Unit/operation-converter.test.ts | 16 + .../Providers/ScmMethodProviderCollection.cs | 25 + .../ScmMethodProviderCollectionTests.cs | 83 + .../TestClient.cs | 26 + .../TestClient.cs | 37 + .../src/Providers/EnumProvider.cs | 1 - .../src/Providers/NamedTypeSymbolProvider.cs | 3 +- .../src/Providers/TypeProvider.cs | 35 +- .../src/Shared/DeprecationApiHelpers.cs | 25 + .../src/Shared/ExperimentalApiHelpers.cs | 17 +- .../src/Utilities/BackCompatHelper.cs | 16 +- .../Legacy.cs | 17 + .../LegacyClient.cs | 18 + .../DeprecationPreservesLastContract/Types.cs | 26 + .../test/Providers/TypeProviderTests.cs | 119 + .../WriteDeprecatedEnumWithEscapedMessage.cs | 14 + .../test/Writers/TypeProviderWriterTests.cs | 10 + .../test/common/InputFactory.cs | 21 +- .../Local.Tests/CustomizationTests.cs | 36 + .../Local/Sample-TypeSpec/Sample-TypeSpec.tsp | 33 + .../DeprecationSamples.RestClient.cs | 47 + .../src/Generated/DeprecationSamples.cs | 146 + .../Models/CurrentDetails.Serialization.cs | 170 + .../src/Generated/Models/CurrentDetails.cs | 41 + .../Models/LegacyChoice.Serialization.cs | 44 + .../src/Generated/Models/LegacyChoice.cs | 21 + .../Models/LegacyDetails.Serialization.cs | 159 + .../src/Generated/Models/LegacyDetails.cs | 46 + .../Models/LegacyExtensibleChoice.cs | 65 + .../Generated/Models/SampleTypeSpecContext.cs | 4 + .../src/Generated/SampleTypeSpecClient.cs | 7 + .../Generated/SampleTypeSpecModelFactory.cs | 29 + .../Local/Sample-TypeSpec/tspCodeModel.json | 3703 ++++++++++------- 35 files changed, 3470 insertions(+), 1625 deletions(-) create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecatedCustomizedPartialMethodsKeepExistingAttributes/TestClient.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecationPreservesLastContractMethods/TestClient.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/DeprecationApiHelpers.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecatedCustomModelKeepsExistingAttribute/Legacy.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationPreservesBackCompatOverloads/LegacyClient.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationPreservesLastContract/Types.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Writers/TestData/TypeProviderWriterTests/WriteDeprecatedEnumWithEscapedMessage.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.RestClient.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyChoice.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyChoice.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.Serialization.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyExtensibleChoice.cs diff --git a/packages/http-client-csharp/docs/emitter.md b/packages/http-client-csharp/docs/emitter.md index 827da57427a..73d5d702f22 100644 --- a/packages/http-client-csharp/docs/emitter.md +++ b/packages/http-client-csharp/docs/emitter.md @@ -27,6 +27,21 @@ options: option: value ``` +## Deprecation + +The TypeSpec `#deprecated` directive emits warning-only C# `Obsolete` attributes on +models, enums, and operation methods, including synchronous, asynchronous, protocol, +and convenience methods. The attribute preserves the directive's message. An +`Obsolete` attribute supplied in a custom partial declaration takes precedence. + +When a last released GA contract is available, an API that was not previously +obsolete does not gain an `Obsolete` attribute. Newly added APIs and APIs that were +already obsolete use the current TypeSpec deprecation message. Compatibility +overloads also preserve the published API's non-obsolete status. + +Warnings for references to obsolete APIs are suppressed only within the generated +implementation. Consumers still receive deprecation warnings. + ## Emitter options ### `emitter-output-dir` diff --git a/packages/http-client-csharp/emitter/test/Unit/model-type.test.ts b/packages/http-client-csharp/emitter/test/Unit/model-type.test.ts index 204ecbfec07..fd56139fc73 100644 --- a/packages/http-client-csharp/emitter/test/Unit/model-type.test.ts +++ b/packages/http-client-csharp/emitter/test/Unit/model-type.test.ts @@ -20,6 +20,26 @@ describe("Discriminator property", () => { runner = await createEmitterTestHost(); }); + it.each([undefined, "", 'Use "Current" instead.\nSee C:\\sdk.'])( + "preserves model and enum deprecation metadata: %s", + async (message) => { + const directive = message === undefined ? "" : `#deprecated ${JSON.stringify(message)}`; + const program = await typeSpecCompile( + `${directive} + enum LegacyChoice { one, two } + ${directive} + model Legacy { choice: LegacyChoice; } + #suppress "deprecated" "Testing deprecated model references." + @get op read(): Legacy;`, + runner, + ); + const sdkContext = await createCSharpSdkContext(createEmitterContext(program)); + const [root] = createModel(sdkContext); + strictEqual(root.models.find((m) => m.name === "Legacy")?.deprecation, message); + strictEqual(root.enums.find((e) => e.name === "LegacyChoice")?.deprecation, message); + }, + ); + it("Base model has discriminator property", async () => { const program = await typeSpecCompile( ` diff --git a/packages/http-client-csharp/emitter/test/Unit/operation-converter.test.ts b/packages/http-client-csharp/emitter/test/Unit/operation-converter.test.ts index bcf63d2ca6a..86f691376fd 100644 --- a/packages/http-client-csharp/emitter/test/Unit/operation-converter.test.ts +++ b/packages/http-client-csharp/emitter/test/Unit/operation-converter.test.ts @@ -19,6 +19,22 @@ describe("Operation Converter", () => { runner = await createEmitterTestHost(); }); + it.each([undefined, "", 'Use "read" instead.\nSee C:\\sdk.'])( + "preserves operation deprecation metadata: %s", + async (message) => { + const program = await typeSpecCompile( + `${message === undefined ? "" : `#deprecated ${JSON.stringify(message)}`} + @get op legacy(): string;`, + runner, + ); + const sdkContext = await createCSharpSdkContext(createEmitterContext(program)); + const [root] = createModel(sdkContext); + strictEqual(root.clients[0].methods[0].operation.deprecated, message); + const serialized = JSON.parse(serializeCodeModel(sdkContext, root)); + strictEqual(serialized.clients[0].methods[0].operation.deprecated, message); + }, + ); + it.each([ { start: 200, end: 299 }, { start: 204, end: 204 }, diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs index 9bb8026bd01..2387bf32f90 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs @@ -215,6 +215,7 @@ private ScmMethodProvider BuildConvenienceMethod(MethodProvider protocolMethod, } ApplyExperimentalAttributes(methodSignature, customSignature, BuildConvenienceMethodAttributes() ?? []); + ApplyDeprecationAttribute(methodSignature, customSignature); // Recompute the response body type so we can branch the body accordingly. GetResponseType(ServiceMethod.Operation.Responses, true, isAsync, out var responseBodyType); @@ -299,6 +300,11 @@ .. GetStackVariablesForReturnValueConversion(result, responseBodyType, isAsync, var convenienceMethod = new ScmMethodProvider(methodSignature, methodBody, EnclosingType, ScmMethodKind.Convenience, collectionDefinition: collection, serviceMethod: ServiceMethod); ExperimentalApiHelpers.AddDependencySuppressions(convenienceMethod, ServiceMethod.Operation); + if (protocolMethod.Signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)) + { + convenienceMethod.Update(suppressions: ExperimentalApiHelpers.MergeSuppressions( + convenienceMethod.Suppressions, DeprecationApiHelpers.GetSuppressions())); + } if (convenienceMethod.XmlDocs != null) { @@ -1149,6 +1155,24 @@ private static void ApplyExperimentalAttributes( } } + private void ApplyDeprecationAttribute(MethodSignature signature, MethodSignature? customSignature) + { + if (customSignature?.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) == true) + { + // Attributes on the defining partial declaration also apply to the implementation. + signature.Update(attributes: [.. signature.Attributes.Where(a => !DeprecationApiHelpers.IsObsoleteAttribute(a))]); + } + else if (!signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) + && Client.BackCompatProvider.LastContractView?.Methods.Any(previous => + MethodSignatureHelper.IsPublicApi(previous.Signature) + && MethodSignatureBase.SignatureComparer.Equals(previous.Signature, signature) + && !previous.Signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)) != true + && DeprecationApiHelpers.BuildAttribute(ServiceMethod.Operation.Deprecated) is { } attribute) + { + signature.Update(attributes: [.. signature.Attributes, attribute]); + } + } + private IReadOnlyList GetMethodArguments( MethodSignature signature, Dictionary declarations, @@ -1492,6 +1516,7 @@ private ScmMethodProvider BuildProtocolMethod(MethodProvider createRequestMethod } ApplyExperimentalAttributes(methodSignature, customSignature, ExperimentalApiHelpers.BuildAttributes(ServiceMethod.Operation.Experimental)); + ApplyDeprecationAttribute(methodSignature, customSignature); TypeProvider? collection = null; MethodBodyStatement[] methodBody; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs index 6fa27841d94..ce2e5b0b2a5 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs @@ -32,6 +32,89 @@ namespace Microsoft.TypeSpec.Generator.ClientModel.Tests.Providers { internal class ScmMethodProviderCollectionTests { + [TestCase(null)] + [TestCase("")] + [TestCase("Use \"Read\" instead.\nSee C:\\sdk.")] + public void DeprecatedOperationsAnnotateAllPublicMethods(string? message) + { + var operation = InputFactory.Operation("Bar", deprecated: message); + var serviceMethod = InputFactory.BasicServiceMethod("Bar", operation); + var inputClient = InputFactory.Client("TestClient", methods: [serviceMethod]); + MockHelpers.LoadMockGenerator(clients: () => [inputClient]); + var client = ScmCodeModelGenerator.Instance.TypeFactory.CreateClient(inputClient)!; + var methods = new ScmMethodProviderCollection(serviceMethod, client); + + Assert.AreEqual(4, methods.Count); + foreach (var method in methods.Append(client.RestClient.GetCreateRequestMethod(operation))) + { + var attribute = method.Signature.Attributes.SingleOrDefault(a => a.Type.Equals(typeof(ObsoleteAttribute))); + if (message is null || method is ScmMethodProvider { Kind: ScmMethodKind.CreateRequest }) + { + Assert.IsNull(attribute); + } + else + { + Assert.IsNotNull(attribute); + Assert.AreEqual(Snippet.Literal(message).ToDisplayString(), attribute!.Arguments.Single().ToDisplayString()); + Assert.IsEmpty(attribute.PositionalArguments); + } + } + } + + [Test] + public async Task DeprecatedCustomizedPartialMethodsKeepExistingAttributes() + { + var operation = InputFactory.Operation("Bar", deprecated: "Generated message"); + var serviceMethod = InputFactory.BasicServiceMethod("Bar", operation); + var inputClient = InputFactory.Client("TestClient", methods: [serviceMethod]); + await MockHelpers.LoadMockGeneratorAsync(clients: () => [inputClient], + compilation: async () => await Helpers.GetCompilationFromDirectoryAsync()); + var client = ScmCodeModelGenerator.Instance.TypeFactory.CreateClient(inputClient)!; + var methods = new ScmMethodProviderCollection(serviceMethod, client); + + Assert.AreEqual(4, methods.Count); + foreach (var method in methods) + { + Assert.IsTrue(method.IsPartialMethod); + Assert.IsFalse(method.Signature.Attributes.Any(a => a.Type.Equals(typeof(ObsoleteAttribute)))); + } + Assert.IsTrue(client.CustomCodeView!.Methods.All(m => + m.Signature.Attributes.Single().Arguments.Single().ToDisplayString() == "\"Custom message\"")); + } + + [Test] + public async Task DeprecationPreservesLastContractMethods() + { + var operation = InputFactory.Operation("Bar", deprecated: "Current message"); + var newOperation = InputFactory.Operation("New", deprecated: "Current message"); + var previewOperation = InputFactory.Operation("Preview", deprecated: "Current message"); + var inputClient = InputFactory.Client("TestClient", methods: + [ + InputFactory.BasicServiceMethod("Bar", operation), + InputFactory.BasicServiceMethod("New", newOperation), + InputFactory.BasicServiceMethod("Preview", previewOperation) + ]); + await MockHelpers.LoadMockGeneratorAsync(clients: () => [inputClient], + lastContractCompilation: () => Helpers.GetCompilationFromDirectoryAsync()); + var client = ScmCodeModelGenerator.Instance.TypeFactory.CreateClient(inputClient)!; + client.ProcessTypeForBackCompatibility(); + var methods = client.Methods.OfType().ToArray(); + + Assert.AreEqual(12, methods.Length); + foreach (var method in methods) + { + bool expected = method.Signature.Name != "Bar" && method.Signature.Name != "BarAsync" + || method.Signature.Name == "Bar" && method.Kind == ScmMethodKind.Protocol + || method.Signature.Name == "BarAsync" && method.Kind == ScmMethodKind.Convenience; + Assert.AreEqual(expected, method.Signature.Attributes.Any(a => a.Type.Equals(typeof(ObsoleteAttribute))), + $"{method.Signature.Name} {method.Kind}"); + if (method.Signature.Name == "Bar" && method.Kind == ScmMethodKind.Convenience) + { + Assert.IsTrue(method.Suppressions.Any(s => s.Code.ToDisplayString() == "\"CS0618\"")); + } + } + } + [TestCase(true)] [TestCase(false)] public void HeadResponseAsBoolReturnsTypedResults(bool responseAsBool) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecatedCustomizedPartialMethodsKeepExistingAttributes/TestClient.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecatedCustomizedPartialMethodsKeepExistingAttributes/TestClient.cs new file mode 100644 index 00000000000..2fc3d0c3ade --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecatedCustomizedPartialMethodsKeepExistingAttributes/TestClient.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading; +using System.Threading.Tasks; + +namespace Sample +{ + public partial class TestClient + { + [Obsolete("Custom message")] + public partial ClientResult Bar(CancellationToken cancellationToken); + + [Obsolete("Custom message")] + public partial Task BarAsync(CancellationToken cancellationToken); + + [Obsolete("Custom message")] + public partial ClientResult Bar(RequestOptions options); + + [Obsolete("Custom message")] + public partial Task BarAsync(RequestOptions options); + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecationPreservesLastContractMethods/TestClient.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecationPreservesLastContractMethods/TestClient.cs new file mode 100644 index 00000000000..0cee10a1465 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecationPreservesLastContractMethods/TestClient.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Diagnostics.CodeAnalysis; +using System.Threading; +using System.Threading.Tasks; + +namespace Sample +{ + public class TestClient + { + public ClientResult Bar(CancellationToken cancellationToken = default) => throw null; + + [Obsolete("Previous message")] + public Task BarAsync(CancellationToken cancellationToken = default) => throw null; + + [Obsolete("Previous message")] + public ClientResult Bar(RequestOptions options) => throw null; + + public Task BarAsync(RequestOptions options) => throw null; + + [Experimental("PREVIEW001")] + public ClientResult Preview(CancellationToken cancellationToken = default) => throw null; + + [Experimental("PREVIEW001")] + public Task PreviewAsync(CancellationToken cancellationToken = default) => throw null; + + [Experimental("PREVIEW001")] + public ClientResult Preview(RequestOptions options) => throw null; + + [Experimental("PREVIEW001")] + public Task PreviewAsync(RequestOptions options) => throw null; + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/EnumProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/EnumProvider.cs index 74e1679a7b2..d15d5566730 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/EnumProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/EnumProvider.cs @@ -32,7 +32,6 @@ public static EnumProvider Create(InputEnumType input, TypeProvider? declaringTy protected EnumProvider(InputEnumType? input) : base(input) { _inputType = input; - _deprecated = input?.Deprecation; IsExtensible = input?.IsExtensible ?? false; InputNamespace = input?.Namespace; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/NamedTypeSymbolProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/NamedTypeSymbolProvider.cs index 5903522f740..982c893c8c0 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/NamedTypeSymbolProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/NamedTypeSymbolProvider.cs @@ -399,7 +399,8 @@ protected internal override MethodProvider[] BuildMethods() GetSymbolXmlDoc(methodSymbol, "returns"), [.. methodSymbol.Parameters.Select(p => ConvertToParameterProvider(methodSymbol, p))], Attributes: [.. methodSymbol.GetAttributes() - .Where(a => a.AttributeClass?.ToDisplayString() == typeof(ExperimentalAttribute).FullName) + .Where(a => a.AttributeClass?.ToDisplayString() is { } name + && (name == typeof(ExperimentalAttribute).FullName || name == typeof(ObsoleteAttribute).FullName)) .Select(a => new AttributeStatement(a))], GenericArguments: methodSymbol.TypeParameters.IsEmpty ? null diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs index c525ea2240f..818f2f0a726 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs @@ -209,7 +209,12 @@ internal void PreserveXmlDocs() public string? Deprecated { - get => _deprecated; + get => _deprecated ??= _inputType switch + { + InputModelType model => model.Deprecation, + InputEnumType enumType => enumType.Deprecation, + _ => null + }; private set => _deprecated = value; } @@ -758,10 +763,20 @@ private IReadOnlyList AssignSerializationProviderOwners(IEnumerabl protected virtual IReadOnlyList BuildAttributes() { + var attributes = new List(); var attribute = ExperimentalApiHelpers.BuildAttribute(_inputType?.Experimental); - return attribute is null || CustomCodeView?.Attributes.Any(ExperimentalApiHelpers.IsExperimentalAttribute) == true - ? [] - : [attribute]; + if (attribute is not null && CustomCodeView?.Attributes.Any(ExperimentalApiHelpers.IsExperimentalAttribute) != true) + { + attributes.Add(attribute); + } + var obsoleteAttribute = DeprecationApiHelpers.BuildAttribute(Deprecated); + if (obsoleteAttribute is not null + && CustomCodeView?.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) != true + && (LastContractView is null || LastContractView.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute))) + { + attributes.Add(obsoleteAttribute); + } + return attributes; } private CSharpType? _enumUnderlyingType; @@ -1236,6 +1251,18 @@ protected internal virtual IReadOnlyList BuildMethodsForBackComp BackCompatHelper.RestorePreviousParameterNames(this, methods); BackCompatHelper.AddBackCompatOverloads(this, methods); + foreach (var method in methods) + { + if (method.Signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) + && previousMethods.Any(previous => MethodSignatureHelper.IsPublicApi(previous.Signature) + && MethodSignatureBase.SignatureComparer.Equals(previous.Signature, method.Signature) + && !previous.Signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute))) + { + method.Signature.Update(attributes: [.. method.Signature.Attributes.Where(a => !DeprecationApiHelpers.IsObsoleteAttribute(a))]); + method.Update(suppressions: ExperimentalApiHelpers.MergeSuppressions(method.Suppressions, DeprecationApiHelpers.GetSuppressions())); + } + } + return methods; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/DeprecationApiHelpers.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/DeprecationApiHelpers.cs new file mode 100644 index 00000000000..05e41f8c90e --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/DeprecationApiHelpers.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Microsoft.TypeSpec.Generator.Statements; +using static Microsoft.TypeSpec.Generator.Snippets.Snippet; + +namespace Microsoft.TypeSpec.Generator.Utilities +{ + internal static class DeprecationApiHelpers + { + public static bool IsObsoleteAttribute(AttributeStatement attribute) + => attribute.Type.Equals(typeof(ObsoleteAttribute)); + + public static AttributeStatement? BuildAttribute(string? message) + => message is null ? null : new AttributeStatement(typeof(ObsoleteAttribute), [Literal(message)]); + + public static SuppressionStatement[] GetSuppressions() + => + [ + new(null, Literal("CS0612"), "This generated code references obsolete functionality."), + new(null, Literal("CS0618"), "This generated code references obsolete functionality.") + ]; + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/ExperimentalApiHelpers.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/ExperimentalApiHelpers.cs index bcde58c16a3..07a75d50a06 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/ExperimentalApiHelpers.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/ExperimentalApiHelpers.cs @@ -58,7 +58,7 @@ public static SuppressionStatement[] GetReferenceSuppressions(InputType? type) { var collector = new DiagnosticCollector(); collector.AddReference(type); - return CreateSuppressions(collector.Ids.Order(StringComparer.Ordinal)); + return collector.GetSuppressions(); } public static SuppressionStatement[] GetReferenceSuppressions(CSharpType? type) @@ -79,8 +79,7 @@ public static SuppressionStatement[] GetReferenceSuppressions(CSharpType? type) } if (CodeModelGenerator.Instance.TypeFactory.CSharpTypeMap.TryGetValue(type, out var provider) && provider is not null) { - var custom = GetAttributeSuppressions(provider.CustomCodeView?.Attributes ?? []); - suppressions.AddRange(custom.Length > 0 ? custom : GetAttributeSuppressions(provider.Attributes)); + suppressions.AddRange(GetAttributeSuppressions(provider.Attributes.Concat(provider.CustomCodeView?.Attributes ?? []))); if (type.IsLiteral && type.Literal is EnumTypeMember member) { suppressions.AddRange(GetAttributeSuppressions(provider.Properties.Where(p => p.Name == member.Name).SelectMany(p => p.Attributes))); @@ -93,8 +92,10 @@ public static SuppressionStatement[] GetReferenceSuppressions(CSharpType? type) public static SuppressionStatement[] GetAttributeSuppressions(IEnumerable attributes) { var ids = new List(); + bool obsolete = false; foreach (var attribute in attributes) { + obsolete |= DeprecationApiHelpers.IsObsoleteAttribute(attribute); if (!IsExperimentalAttribute(attribute)) { continue; @@ -110,7 +111,7 @@ public static SuppressionStatement[] GetAttributeSuppressions(IEnumerable[] suppressions) @@ -164,8 +165,13 @@ private static void ValidateDiagnosticId(string diagnosticId) private sealed class DiagnosticCollector { private readonly HashSet _references = []; + private bool _hasDeprecatedReference; public HashSet Ids { get; } = new(StringComparer.Ordinal); + public SuppressionStatement[] GetSuppressions() + => MergeSuppressions(CreateSuppressions(Ids.Order(StringComparer.Ordinal)), + _hasDeprecatedReference ? DeprecationApiHelpers.GetSuppressions() : []); + public void AddId(string? id) { if (id is not null) @@ -198,6 +204,7 @@ public void AddReference(InputType? type) return; } AddId(type.Experimental?.DiagnosticId); + _hasDeprecatedReference |= type is InputModelType { Deprecation: not null } or InputEnumType { Deprecation: not null }; switch (type) { case InputArrayType array: diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs index c3fe67860cf..89cb738d9c3 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs @@ -510,9 +510,10 @@ public static void AddBackCompatOverloads(TypeProvider enclosingType, List !ExperimentalApiHelpers.IsExperimentalAttribute(a)), - .. attribute is null ? Array.Empty() : [attribute] + .. overload.Signature.Attributes.Where(a => !ExperimentalApiHelpers.IsExperimentalAttribute(a) + && !DeprecationApiHelpers.IsObsoleteAttribute(a)), + .. attribute is null ? Array.Empty() : [attribute], + .. obsolete is not null && previousMethod.Signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) ? new[] { obsolete } : [] ]); - overload.Update(suppressions: ExperimentalApiHelpers.MergeSuppressions(overload.Suppressions, currentMethod.Suppressions)); + overload.Update(suppressions: ExperimentalApiHelpers.MergeSuppressions(overload.Suppressions, currentMethod.Suppressions, + obsolete is null ? [] : DeprecationApiHelpers.GetSuppressions())); } // Returns true when both signatures have the same return type (matched by name); a null return type diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecatedCustomModelKeepsExistingAttribute/Legacy.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecatedCustomModelKeepsExistingAttribute/Legacy.cs new file mode 100644 index 00000000000..acaf6a4e43e --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecatedCustomModelKeepsExistingAttribute/Legacy.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Sample.Models +{ + [Obsolete("Custom message")] + public partial class Legacy + { + } + + [Obsolete("Custom message")] + public readonly partial struct LegacyChoice + { + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationPreservesBackCompatOverloads/LegacyClient.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationPreservesBackCompatOverloads/LegacyClient.cs new file mode 100644 index 00000000000..b48157ad925 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationPreservesBackCompatOverloads/LegacyClient.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Sample +{ + public class LegacyClient + { + public void Read(int value) { } + + public string Reorder(string name, int value) => null; + } + + public class ObsoleteClient + { + [System.Obsolete("Previous message")] + public void Read(int value) { } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationPreservesLastContract/Types.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationPreservesLastContract/Types.cs new file mode 100644 index 00000000000..911be4fdf9e --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationPreservesLastContract/Types.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Sample.Models +{ + public class StableModel { } + + [Obsolete("Previous message")] + public class ObsoleteModel { } + + [Experimental("PREVIEW001")] + public class PreviewModel { } + + public enum StableEnum { One } + + [Obsolete("Previous message")] + public enum ObsoleteEnum { One } + + public readonly partial struct StableChoice { } + + [Obsolete("Previous message")] + public readonly partial struct ObsoleteChoice { } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs index 27425b437b6..186093e042f 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs @@ -24,6 +24,125 @@ namespace Microsoft.TypeSpec.Generator.Tests.Providers { public class TypeProviderTests { + [TestCase("model", null)] + [TestCase("model", "Use \"Current\" instead.\nSee C:\\sdk.")] + [TestCase("struct", "")] + [TestCase("fixed", "Use Current instead.")] + [TestCase("extensible", "Use Current instead.")] + [TestCase("fixed", null)] + [TestCase("extensible", null)] + public void DeprecatedTypesEmitWarningOnlyAttributes(string kind, string? message) + { + MockHelpers.LoadMockGenerator(); + TypeProvider provider = kind is "model" or "struct" + ? CodeModelGenerator.Instance.TypeFactory.CreateModel(InputFactory.Model("Legacy", modelAsStruct: kind == "struct", deprecation: message))! + : CodeModelGenerator.Instance.TypeFactory.CreateEnum(InputFactory.StringEnum("Legacy", + [("One", "one")], isExtensible: kind == "extensible", deprecation: message))!; + + for (int i = 0; i < 2; i++) + { + Assert.AreEqual(message, provider.Deprecated); + var attribute = provider.Attributes.SingleOrDefault(a => a.Type.Equals(typeof(ObsoleteAttribute))); + if (message is null) + { + Assert.IsNull(attribute); + } + else + { + Assert.IsNotNull(attribute); + Assert.AreEqual(Snippet.Literal(message).ToDisplayString(), attribute!.Arguments.Single().ToDisplayString()); + Assert.IsEmpty(attribute.PositionalArguments); + } + provider.Reset(); + } + } + + [TestCase(false)] + [TestCase(true)] + public async Task DeprecatedCustomModelKeepsExistingAttribute(bool isEnum) + { + var model = InputFactory.Model("Legacy", deprecation: "Generated message"); + var choice = InputFactory.StringEnum("LegacyChoice", [("One", "one")], isExtensible: true, deprecation: "Generated message"); + await MockHelpers.LoadMockGeneratorAsync(inputModelTypes: [model], + inputEnumTypes: [choice], + compilation: async () => await Helpers.GetCompilationFromDirectoryAsync()); + TypeProvider provider = isEnum + ? CodeModelGenerator.Instance.TypeFactory.CreateEnum(choice)! + : CodeModelGenerator.Instance.TypeFactory.CreateModel(model)!; + + Assert.IsFalse(provider.Attributes.Any(a => a.Type.Equals(typeof(ObsoleteAttribute)))); + Assert.AreEqual("\"Custom message\"", provider.CustomCodeView!.Attributes.Single().Arguments.Single().ToDisplayString()); + } + + [TestCase("StableModel", "model", false)] + [TestCase("ObsoleteModel", "model", true)] + [TestCase("PreviewModel", "model", true)] + [TestCase("NewModel", "model", true)] + [TestCase("StableEnum", "fixed", false)] + [TestCase("ObsoleteEnum", "fixed", true)] + [TestCase("StableChoice", "extensible", false)] + [TestCase("ObsoleteChoice", "extensible", true)] + public async Task DeprecationPreservesLastContract(string name, string kind, bool obsolete) + { + await MockHelpers.LoadMockGeneratorAsync(lastContractCompilation: () => Helpers.GetCompilationFromDirectoryAsync()); + TypeProvider provider = kind == "model" + ? CodeModelGenerator.Instance.TypeFactory.CreateModel(InputFactory.Model(name, deprecation: "Current message"))! + : CodeModelGenerator.Instance.TypeFactory.CreateEnum(InputFactory.StringEnum(name, + [("One", "one")], isExtensible: kind == "extensible", deprecation: "Current message"))!; + + provider.ProcessTypeForBackCompatibility(); + Assert.AreEqual(obsolete, provider.Attributes.Any(a => a.Type.Equals(typeof(ObsoleteAttribute)))); + } + + [TestCase(false)] + [TestCase(true)] + public async Task DeprecationPreservesBackCompatOverloads(bool previouslyObsolete) + { + await MockHelpers.LoadMockGeneratorAsync(lastContractCompilation: () => Helpers.GetCompilationFromDirectoryAsync()); + var provider = new TestTypeProvider(name: previouslyObsolete ? "ObsoleteClient" : "LegacyClient", ns: "Sample"); + var method = new MethodProvider( + new MethodSignature("Read", null, MethodSignatureModifiers.Public, null, null, + [ + new ParameterProvider("value", $"", typeof(int)), + new ParameterProvider("added", $"", typeof(bool), defaultValue: Snippet.Default, location: ParameterLocation.Query) + ], + Attributes: [new AttributeStatement(typeof(ObsoleteAttribute), [Snippet.Literal("Current message")])]), + MethodBodyStatement.Empty, provider); + provider.Update(methods: [method]); + provider.ProcessTypeForBackCompatibility(); + + Assert.AreEqual(2, provider.Methods.Count); + Assert.IsTrue(provider.Methods.Single(m => m.Signature.Parameters.Count == 2).Signature.Attributes.Any(a => a.Type.Equals(typeof(ObsoleteAttribute)))); + var previous = provider.Methods.Single(m => m.Signature.Parameters.Count == 1); + Assert.AreEqual(previouslyObsolete, previous.Signature.Attributes.Any(a => a.Type.Equals(typeof(ObsoleteAttribute)))); + if (previouslyObsolete) + { + Assert.AreEqual("\"Current message\"", previous.Signature.Attributes.Single(a => a.Type.Equals(typeof(ObsoleteAttribute))).Arguments.Single().ToDisplayString()); + } + Assert.IsTrue(previous.Suppressions.Any(s => s.Code.ToDisplayString() == "\"CS0618\"")); + } + + [Test] + public async Task DeprecationPreservesReorderedLastContractMethods() + { + await MockHelpers.LoadMockGeneratorAsync(lastContractCompilation: () => + Helpers.GetCompilationFromDirectoryAsync(method: nameof(DeprecationPreservesBackCompatOverloads))); + var provider = new TestTypeProvider(name: "LegacyClient", ns: "Sample"); + var method = new MethodProvider( + new MethodSignature("Reorder", null, MethodSignatureModifiers.Public, typeof(string), null, + [ + new ParameterProvider("value", $"", typeof(int)), + new ParameterProvider("name", $"", typeof(string)) + ], + Attributes: [new AttributeStatement(typeof(ObsoleteAttribute), [Snippet.Literal("Current message")])]), + Snippet.Return(Snippet.Null), provider); + provider.Update(methods: [method]); + provider.ProcessTypeForBackCompatibility(); + + CollectionAssert.AreEqual(new[] { "name", "value" }, provider.Methods.Single().Signature.Parameters.Select(p => p.Name)); + Assert.IsFalse(provider.Methods.Single().Signature.Attributes.Any(a => a.Type.Equals(typeof(ObsoleteAttribute)))); + } + [Test] public void ExperimentalApiHelpersAreInternal() { diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Writers/TestData/TypeProviderWriterTests/WriteDeprecatedEnumWithEscapedMessage.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Writers/TestData/TypeProviderWriterTests/WriteDeprecatedEnumWithEscapedMessage.cs new file mode 100644 index 00000000000..65056f7ae25 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Writers/TestData/TypeProviderWriterTests/WriteDeprecatedEnumWithEscapedMessage.cs @@ -0,0 +1,14 @@ +// + +#nullable disable + +using System; + +namespace Sample.Models +{ + [global::System.ObsoleteAttribute("Use \"Current\" instead.\nSee C:\\sdk.")] + public enum Legacy + { + One + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Writers/TypeProviderWriterTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Writers/TypeProviderWriterTests.cs index 1258ccb409d..a697781083c 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Writers/TypeProviderWriterTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Writers/TypeProviderWriterTests.cs @@ -88,6 +88,16 @@ public void TypeProviderWriter_WriteEnumWithFieldAttributes() Assert.AreEqual(expected, result); } + [Test] + public void WriteDeprecatedEnumWithEscapedMessage() + { + var input = InputFactory.StringEnum("Legacy", [("One", "one")], + deprecation: "Use \"Current\" instead.\nSee C:\\sdk."); + var provider = EnumProvider.Create(input); + + Assert.AreEqual(Helpers.GetExpectedFromFile(), new TypeProviderWriter(provider).Write().Content); + } + private class TestEnumWithAttributesProvider : TypeProvider { protected override string BuildRelativeFilePath() => "TestEnum.cs"; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/common/InputFactory.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/common/InputFactory.cs index 22d5b8e454c..20bebb36014 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/common/InputFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/common/InputFactory.cs @@ -186,7 +186,8 @@ public static InputEnumType StringEnum( string clientNamespace = "Sample.Models", InputExternalTypeMetadata? external = null, bool isExactName = false, - IReadOnlyList? apiVersions = null) + IReadOnlyList? apiVersions = null, + string? deprecation = null) { var enumValues = new List(); var enumType = Enum( @@ -198,7 +199,8 @@ public static InputEnumType StringEnum( isExtensible: isExtensible, clientNamespace: clientNamespace, external: external, - isExactName: isExactName); + isExactName: isExactName, + deprecation: deprecation); foreach (var (valueName, value) in values) { @@ -330,14 +332,15 @@ public static InputEnumType Enum( string clientNamespace = "Sample.Models", InputExternalTypeMetadata? external = null, bool isExactName = false, - IReadOnlyList? apiVersions = null) + IReadOnlyList? apiVersions = null, + string? deprecation = null) { var enumType = new InputEnumType( name, clientNamespace, name, access, - null, + deprecation, "", $"{name} description", usage, @@ -613,7 +616,8 @@ public static InputModelType Model( InputExternalTypeMetadata? external = null, InputSerializationOptions? serializationOptions = null, bool isExactName = false, - IReadOnlyList? apiVersions = null) + IReadOnlyList? apiVersions = null, + string? deprecation = null) { IEnumerable propertiesList = properties ?? [Property("StringProperty", InputPrimitiveType.String)]; @@ -622,7 +626,7 @@ public static InputModelType Model( @namespace, name, access, - null, + deprecation, "", $"{name} description", usage, @@ -758,13 +762,14 @@ public static InputOperation Operation( string? ns = null, bool isExactName = false, bool generateProtocolMethod = true, - bool bufferResponse = true) + bool bufferResponse = true, + string? deprecated = null) { var operation = new InputOperation( name, "", $"{name} description", - null, + deprecated, access, parameters is null ? [] : [.. parameters], responses is null ? [OperationResponse()] : [.. responses], diff --git a/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs b/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs index 5024b297bf2..417e50b8888 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs @@ -13,6 +13,42 @@ namespace TestProjects.Local.Tests { public class CustomizationTests { + [TestCase("LegacyDetails", "Use \"CurrentDetails\" instead.\nSee C:\\sdk.")] + [TestCase("LegacyChoice", "Use CurrentChoice instead.")] + [TestCase("LegacyExtensibleChoice", "Use CurrentExtensibleChoice instead.")] + [TestCase("CurrentDetails", null)] + public void DeprecatedTypesPreserveWarningOnlyMessages(string typeName, string? message) + { + var type = typeof(SampleTypeSpecClient).Assembly.GetType($"SampleTypeSpec.{typeName}"); + Assert.IsNotNull(type); + var attribute = type!.GetCustomAttribute(); + Assert.AreEqual(message, attribute?.Message); + if (message is not null) + { + Assert.IsFalse(attribute!.IsError); + } + } + + [TestCase("Legacy", "Use \"read\" instead.\nSee C:\\sdk.")] + [TestCase("LegacyAsync", "Use \"read\" instead.\nSee C:\\sdk.")] + [TestCase("Read", null)] + [TestCase("ReadAsync", null)] + public void DeprecatedOperationsPreserveWarningOnlyMessages(string methodName, string? message) + { + var methods = typeof(SampleTypeSpecClient).Assembly.GetType("SampleTypeSpec.DeprecationSamples")! + .GetMethods().Where(m => m.Name == methodName).ToArray(); + Assert.AreEqual(2, methods.Length); + foreach (var method in methods) + { + var attribute = method.GetCustomAttribute(); + Assert.AreEqual(message, attribute?.Message); + if (message is not null) + { + Assert.IsFalse(attribute!.IsError); + } + } + } + [TestCase("GetNotebookResult", "GetNotebookResponse", true)] [TestCase("GetWidgetMetricsResult", "GetWidgetMetricsResponse", true)] [TestCase("ListWithContinuationTokenHeaderResponseResult", "ListWithContinuationTokenHeaderResponseResponse", false)] diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/Sample-TypeSpec.tsp b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/Sample-TypeSpec.tsp index c55a73051c2..4a5a50f85ff 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/Sample-TypeSpec.tsp +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/Sample-TypeSpec.tsp @@ -1131,3 +1131,36 @@ op getAcronymParameters( @post @convenientAPI(true, "csharp") op setAcronymAddresses(@query ipV4Address: string, @query ipV6Address?: string): void; + +#deprecated "Use \"CurrentDetails\" instead.\nSee C:\\sdk." +model LegacyDetails { + choice: LegacyChoice; + extensibleChoice: LegacyExtensibleChoice; +} + +#deprecated "Use CurrentChoice instead." +enum LegacyChoice { + one, + two, +} + +#deprecated "Use CurrentExtensibleChoice instead." +union LegacyExtensibleChoice { + string, + one: "one", +} + +model CurrentDetails extends LegacyDetails { + previous?: LegacyDetails[]; +} + +interface DeprecationSamples { + #deprecated "Use \"read\" instead.\nSee C:\\sdk." + @route("/deprecated") + @get + legacy(): LegacyDetails; + + @route("/deprecated/current") + @get + read(): CurrentDetails; +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.RestClient.cs new file mode 100644 index 00000000000..099e5741be9 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.RestClient.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.ClientModel.Primitives; + +namespace SampleTypeSpec +{ + /// + public partial class DeprecationSamples + { + private static PipelineMessageClassifier _pipelineMessageClassifier200; + + private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); + +#pragma warning disable CS0612 // This generated code references obsolete functionality. +#pragma warning disable CS0618 // This generated code references obsolete functionality. + internal PipelineMessage CreateLegacyRequest(RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/deprecated", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "GET", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Accept", "application/json"); + message.Apply(options); + return message; + } +#pragma warning restore CS0612 // This generated code references obsolete functionality. +#pragma warning restore CS0618 // This generated code references obsolete functionality. + + internal PipelineMessage CreateReadRequest(RequestOptions options) + { + ClientUriBuilder uri = new ClientUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/deprecated/current", false); + PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "GET", PipelineMessageClassifier200); + PipelineRequest request = message.Request; + request.Headers.Set("Accept", "application/json"); + message.Apply(options); + return message; + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs new file mode 100644 index 00000000000..df76e478e75 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs @@ -0,0 +1,146 @@ +// 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 DeprecationSamples sub-client. + public partial class DeprecationSamples + { + private readonly Uri _endpoint; + + /// Initializes a new instance of DeprecationSamples for mocking. + protected DeprecationSamples() + { + } + + /// Initializes a new instance of DeprecationSamples. + /// The HTTP pipeline for sending and receiving REST requests and responses. + /// Service endpoint. + internal DeprecationSamples(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] Legacy + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// Service returned a non-success status code. + /// The response returned from the service. + [Obsolete("Use \"read\" instead.\nSee C:\\sdk.")] + public virtual ClientResult Legacy(RequestOptions options) + { + using PipelineMessage message = CreateLegacyRequest(options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + /// + /// [Protocol Method] Legacy + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// Service returned a non-success status code. + /// The response returned from the service. + [Obsolete("Use \"read\" instead.\nSee C:\\sdk.")] + public virtual async Task LegacyAsync(RequestOptions options) + { + using PipelineMessage message = CreateLegacyRequest(options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + /// Legacy. + /// The cancellation token that can be used to cancel the operation. + /// Service returned a non-success status code. + [Obsolete("Use \"read\" instead.\nSee C:\\sdk.")] + public virtual ClientResult Legacy(CancellationToken cancellationToken = default) + { + ClientResult result = Legacy(cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((LegacyDetails)result, result.GetRawResponse()); + } + + /// Legacy. + /// The cancellation token that can be used to cancel the operation. + /// Service returned a non-success status code. + [Obsolete("Use \"read\" instead.\nSee C:\\sdk.")] + public virtual async Task> LegacyAsync(CancellationToken cancellationToken = default) + { + ClientResult result = await LegacyAsync(cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((LegacyDetails)result, result.GetRawResponse()); + } + + /// + /// [Protocol Method] Read + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual ClientResult Read(RequestOptions options) + { + using PipelineMessage message = CreateReadRequest(options); + return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); + } + + /// + /// [Protocol Method] Read + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// Service returned a non-success status code. + /// The response returned from the service. + public virtual async Task ReadAsync(RequestOptions options) + { + using PipelineMessage message = CreateReadRequest(options); + return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); + } + + /// Read. + /// The cancellation token that can be used to cancel the operation. + /// Service returned a non-success status code. + public virtual ClientResult Read(CancellationToken cancellationToken = default) + { + ClientResult result = Read(cancellationToken.ToRequestOptions()); + return ClientResult.FromValue((CurrentDetails)result, result.GetRawResponse()); + } + + /// Read. + /// The cancellation token that can be used to cancel the operation. + /// Service returned a non-success status code. + public virtual async Task> ReadAsync(CancellationToken cancellationToken = default) + { + ClientResult result = await ReadAsync(cancellationToken.ToRequestOptions()).ConfigureAwait(false); + return ClientResult.FromValue((CurrentDetails)result, result.GetRawResponse()); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.Serialization.cs new file mode 100644 index 00000000000..b5067a47fd8 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.Serialization.cs @@ -0,0 +1,170 @@ +// 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; + +#pragma warning disable CS0612 // This generated code references obsolete functionality. +#pragma warning disable CS0618 // This generated code references obsolete functionality. +namespace SampleTypeSpec +{ + /// The CurrentDetails. + public partial class CurrentDetails : LegacyDetails, IJsonModel + { + /// Initializes a new instance of for deserialization. + internal CurrentDetails() + { + } + + /// The data to parse. + /// The client options for reading and writing models. + protected override LegacyDetails 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 DeserializeCurrentDetails(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(CurrentDetails)} does not support reading '{options.Format}' format."); + } + } + + /// 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(CurrentDetails)} does not support writing '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The data to parse. + /// The client options for reading and writing models. + CurrentDetails IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (CurrentDetails)PersistableModelCreateCore(data, options); + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// The to deserialize the from. + public static explicit operator CurrentDetails(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); + return DeserializeCurrentDetails(document.RootElement, ModelSerializationExtensions.WireOptions); + } + + /// 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(CurrentDetails)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsCollectionDefined(Previous)) + { + writer.WritePropertyName("previous"u8); + writer.WriteStartArray(); + foreach (LegacyDetails item in Previous) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + CurrentDetails IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (CurrentDetails)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override LegacyDetails 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(CurrentDetails)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeCurrentDetails(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static CurrentDetails DeserializeCurrentDetails(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + LegacyChoice choice = default; + LegacyExtensibleChoice extensibleChoice = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + IList previous = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("choice"u8)) + { + choice = prop.Value.GetString().ToLegacyChoice(); + continue; + } + if (prop.NameEquals("extensibleChoice"u8)) + { + extensibleChoice = new LegacyExtensibleChoice(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("previous"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(DeserializeLegacyDetails(item, options)); + } + previous = array; + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, prop.Value.GetUtf8Bytes()); + } + } + return new CurrentDetails(choice, extensibleChoice, additionalBinaryDataProperties, previous ?? new ChangeTrackingList()); + } + } +} +#pragma warning restore CS0612 // This generated code references obsolete functionality. +#pragma warning restore CS0618 // This generated code references obsolete functionality. diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.cs new file mode 100644 index 00000000000..87ecfbe0454 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +#pragma warning disable CS0612 // This generated code references obsolete functionality. +#pragma warning disable CS0618 // This generated code references obsolete functionality. +namespace SampleTypeSpec +{ + /// The CurrentDetails. + public partial class CurrentDetails : LegacyDetails + { + /// Initializes a new instance of . + /// + /// + internal CurrentDetails(LegacyChoice choice, LegacyExtensibleChoice extensibleChoice) : base(choice, extensibleChoice) + { + Previous = new ChangeTrackingList(); + } + + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + /// + internal CurrentDetails(LegacyChoice choice, LegacyExtensibleChoice extensibleChoice, IDictionary additionalBinaryDataProperties, IList previous) : base(choice, extensibleChoice, additionalBinaryDataProperties) + { + Previous = previous; + } + + /// Gets the Previous. + public IList Previous { get; } + } +} +#pragma warning restore CS0612 // This generated code references obsolete functionality. +#pragma warning restore CS0618 // This generated code references obsolete functionality. diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyChoice.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyChoice.Serialization.cs new file mode 100644 index 00000000000..b2a25743bae --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyChoice.Serialization.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace SampleTypeSpec +{ + internal static partial class LegacyChoiceExtensions + { + /// The value to serialize. +#pragma warning disable CS0612 // This generated code references obsolete functionality. +#pragma warning disable CS0618 // This generated code references obsolete functionality. + public static string ToSerialString(this LegacyChoice value) => value switch + { + LegacyChoice.One => "one", + LegacyChoice.Two => "two", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown LegacyChoice value.") + }; +#pragma warning restore CS0612 // This generated code references obsolete functionality. +#pragma warning restore CS0618 // This generated code references obsolete functionality. + + /// The value to deserialize. +#pragma warning disable CS0612 // This generated code references obsolete functionality. +#pragma warning disable CS0618 // This generated code references obsolete functionality. + public static LegacyChoice ToLegacyChoice(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "one")) + { + return LegacyChoice.One; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "two")) + { + return LegacyChoice.Two; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown LegacyChoice value."); + } +#pragma warning restore CS0612 // This generated code references obsolete functionality. +#pragma warning restore CS0618 // This generated code references obsolete functionality. + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyChoice.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyChoice.cs new file mode 100644 index 00000000000..66af332886d --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyChoice.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace SampleTypeSpec +{ + /// + [Obsolete("Use CurrentChoice instead.")] + public enum LegacyChoice + { + /// One. + One, + /// Two. + Two + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.Serialization.cs new file mode 100644 index 00000000000..acc280227b9 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.Serialization.cs @@ -0,0 +1,159 @@ +// 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 +{ + /// The LegacyDetails. + public partial class LegacyDetails : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal LegacyDetails() + { + } + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual LegacyDetails 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 DeserializeLegacyDetails(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(LegacyDetails)} does not support reading '{options.Format}' format."); + } + } + + /// 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(LegacyDetails)} does not support writing '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The data to parse. + /// The client options for reading and writing models. + LegacyDetails IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// The to deserialize the from. + public static explicit operator LegacyDetails(ClientResult result) + { + PipelineResponse response = result.GetRawResponse(); + using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions); + return DeserializeLegacyDetails(document.RootElement, ModelSerializationExtensions.WireOptions); + } + + /// 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(LegacyDetails)} does not support writing '{format}' format."); + } + writer.WritePropertyName("choice"u8); + writer.WriteStringValue(Choice.ToSerialString()); + writer.WritePropertyName("extensibleChoice"u8); + writer.WriteStringValue(ExtensibleChoice.ToString()); + 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. + LegacyDetails IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual LegacyDetails 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(LegacyDetails)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeLegacyDetails(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static LegacyDetails DeserializeLegacyDetails(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + LegacyChoice choice = default; + LegacyExtensibleChoice extensibleChoice = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("choice"u8)) + { + choice = prop.Value.GetString().ToLegacyChoice(); + continue; + } + if (prop.NameEquals("extensibleChoice"u8)) + { + extensibleChoice = new LegacyExtensibleChoice(prop.Value.GetString()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, prop.Value.GetUtf8Bytes()); + } + } + return new LegacyDetails(choice, extensibleChoice, additionalBinaryDataProperties); + } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.cs new file mode 100644 index 00000000000..c9ea9ed544c --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace SampleTypeSpec +{ + /// The LegacyDetails. + [Obsolete("Use \"CurrentDetails\" instead.\nSee C:\\sdk.")] + public partial class LegacyDetails + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + /// + internal LegacyDetails(LegacyChoice choice, LegacyExtensibleChoice extensibleChoice) + { + Choice = choice; + ExtensibleChoice = extensibleChoice; + } + + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + internal LegacyDetails(LegacyChoice choice, LegacyExtensibleChoice extensibleChoice, IDictionary additionalBinaryDataProperties) + { + Choice = choice; + ExtensibleChoice = extensibleChoice; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets the Choice. + public LegacyChoice Choice { get; } + + /// Gets the ExtensibleChoice. + public LegacyExtensibleChoice ExtensibleChoice { get; } + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyExtensibleChoice.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyExtensibleChoice.cs new file mode 100644 index 00000000000..b08d8670e95 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyExtensibleChoice.cs @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace SampleTypeSpec +{ + /// + [Obsolete("Use CurrentExtensibleChoice instead.")] + public readonly partial struct LegacyExtensibleChoice : IEquatable + { + private readonly string _value; + private const string OneValue = "one"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public LegacyExtensibleChoice(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Gets the One. + public static LegacyExtensibleChoice One { get; } = new LegacyExtensibleChoice(OneValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(LegacyExtensibleChoice left, LegacyExtensibleChoice right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(LegacyExtensibleChoice left, LegacyExtensibleChoice right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator LegacyExtensibleChoice(string value) => new LegacyExtensibleChoice(value); + + /// Converts a string to a . + /// The value. + public static implicit operator LegacyExtensibleChoice?(string value) => value == null ? null : new LegacyExtensibleChoice(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is LegacyExtensibleChoice other && Equals(other); + + /// + public bool Equals(LegacyExtensibleChoice other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} 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 217ca74f694..d37e7953c7d 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 @@ -16,11 +16,15 @@ namespace SampleTypeSpec /// [ModelReaderWriterBuildable(typeof(Animal))] [ModelReaderWriterBuildable(typeof(AnotherDynamicModel))] + [ModelReaderWriterBuildable(typeof(CurrentDetails))] [ModelReaderWriterBuildable(typeof(Dog))] [ModelReaderWriterBuildable(typeof(DynamicModel))] [ModelReaderWriterBuildable(typeof(Friend))] [ModelReaderWriterBuildable(typeof(GetNotebookResult))] [ModelReaderWriterBuildable(typeof(GetWidgetMetricsResult))] +#pragma warning disable CS0618 // global::SampleTypeSpec.LegacyDetails is obsolete and may be removed in future versions. + [ModelReaderWriterBuildable(typeof(LegacyDetails))] +#pragma warning restore CS0618 // global::SampleTypeSpec.LegacyDetails is obsolete and may be removed in future versions. [ModelReaderWriterBuildable(typeof(LifecycleModel))] [ModelReaderWriterBuildable(typeof(ModelWithEmbeddedNonBodyParameters))] [ModelReaderWriterBuildable(typeof(ModelWithRequiredNullableProperties))] 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 3078b4583e8..6dd99ef227e 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 @@ -41,6 +41,7 @@ public partial class SampleTypeSpecClient private PetOperations _cachedPetOperations; private DogOperations _cachedDogOperations; private PlantOperations _cachedPlantOperations; + private DeprecationSamples _cachedDeprecationSamples; /// Initializes a new instance of SampleTypeSpecClient for mocking. protected SampleTypeSpecClient() @@ -2307,5 +2308,11 @@ public virtual Notebooks GetNotebooksClient(string notebook) return new Notebooks(Pipeline, _endpoint, notebook); } + + /// Initializes a new instance of DeprecationSamples. + public virtual DeprecationSamples GetDeprecationSamplesClient() + { + return Volatile.Read(ref _cachedDeprecationSamples) ?? Interlocked.CompareExchange(ref _cachedDeprecationSamples, new DeprecationSamples(Pipeline, _endpoint), null) ?? _cachedDeprecationSamples; + } } } 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 ec099abe9b5..5050361f876 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 @@ -553,6 +553,35 @@ public static GetNotebookResult GetNotebookResult(string name = default, string return new GetNotebookResult(name, content, additionalBinaryDataProperties: null); } + /// The LegacyDetails. + /// + /// + /// A new instance for mocking. +#pragma warning disable CS0612 // This generated code references obsolete functionality. +#pragma warning disable CS0618 // This generated code references obsolete functionality. + public static LegacyDetails LegacyDetails(LegacyChoice choice = default, LegacyExtensibleChoice extensibleChoice = default) + { + return new LegacyDetails(choice, extensibleChoice, additionalBinaryDataProperties: null); + } +#pragma warning restore CS0612 // This generated code references obsolete functionality. +#pragma warning restore CS0618 // This generated code references obsolete functionality. + + /// The CurrentDetails. + /// + /// + /// + /// A new instance for mocking. +#pragma warning disable CS0612 // This generated code references obsolete functionality. +#pragma warning disable CS0618 // This generated code references obsolete functionality. + public static CurrentDetails CurrentDetails(LegacyChoice choice = default, LegacyExtensibleChoice extensibleChoice = default, IEnumerable previous = default) + { + previous ??= new ChangeTrackingList(); + + return new CurrentDetails(choice, extensibleChoice, additionalBinaryDataProperties: null, previous.ToList()); + } +#pragma warning restore CS0612 // This generated code references obsolete functionality. +#pragma warning restore CS0618 // This generated code references obsolete functionality. + /// The NullableDynamicModel. /// /// 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 b99442d142b..883c0b7a605 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 @@ -1143,12 +1143,12 @@ { "$id": "87", "kind": "enum", - "name": "DaysOfWeekExtensibleEnum", + "name": "LegacyChoice", "apiVersions": [ "2024-07-16-preview", "2024-08-16-preview" ], - "crossLanguageDefinitionId": "SampleTypeSpec.DaysOfWeekExtensibleEnum", + "crossLanguageDefinitionId": "SampleTypeSpec.LegacyChoice", "valueType": { "$id": "88", "kind": "string", @@ -1160,8 +1160,8 @@ { "$id": "89", "kind": "enumvalue", - "name": "Monday", - "value": "Monday", + "name": "one", + "value": "one", "valueType": { "$ref": "88" }, @@ -1174,8 +1174,8 @@ { "$id": "90", "kind": "enumvalue", - "name": "Tuesday", - "value": "Tuesday", + "name": "two", + "value": "two", "valueType": { "$ref": "88" }, @@ -1184,73 +1184,167 @@ }, "decorators": [], "isExactName": false + } + ], + "namespace": "SampleTypeSpec", + "deprecation": "Use CurrentChoice instead.", + "isFixed": true, + "isFlags": false, + "usage": "Output,Json", + "decorators": [], + "isExactName": false + }, + { + "$id": "91", + "kind": "enum", + "name": "LegacyExtensibleChoice", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "crossLanguageDefinitionId": "SampleTypeSpec.LegacyExtensibleChoice", + "valueType": { + "$id": "92", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "values": [ + { + "$id": "93", + "kind": "enumvalue", + "name": "one", + "value": "one", + "valueType": { + "$ref": "92" + }, + "enumType": { + "$ref": "91" + }, + "decorators": [], + "isExactName": false + } + ], + "namespace": "SampleTypeSpec", + "deprecation": "Use CurrentExtensibleChoice instead.", + "isFixed": false, + "isFlags": false, + "usage": "Output,Json", + "decorators": [], + "isExactName": false + }, + { + "$id": "94", + "kind": "enum", + "name": "DaysOfWeekExtensibleEnum", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "crossLanguageDefinitionId": "SampleTypeSpec.DaysOfWeekExtensibleEnum", + "valueType": { + "$id": "95", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "values": [ + { + "$id": "96", + "kind": "enumvalue", + "name": "Monday", + "value": "Monday", + "valueType": { + "$ref": "95" + }, + "enumType": { + "$ref": "94" + }, + "decorators": [], + "isExactName": false + }, + { + "$id": "97", + "kind": "enumvalue", + "name": "Tuesday", + "value": "Tuesday", + "valueType": { + "$ref": "95" + }, + "enumType": { + "$ref": "94" + }, + "decorators": [], + "isExactName": false }, { - "$id": "91", + "$id": "98", "kind": "enumvalue", "name": "Wednesday", "value": "Wednesday", "valueType": { - "$ref": "88" + "$ref": "95" }, "enumType": { - "$ref": "87" + "$ref": "94" }, "decorators": [], "isExactName": false }, { - "$id": "92", + "$id": "99", "kind": "enumvalue", "name": "Thursday", "value": "Thursday", "valueType": { - "$ref": "88" + "$ref": "95" }, "enumType": { - "$ref": "87" + "$ref": "94" }, "decorators": [], "isExactName": false }, { - "$id": "93", + "$id": "100", "kind": "enumvalue", "name": "Friday", "value": "Friday", "valueType": { - "$ref": "88" + "$ref": "95" }, "enumType": { - "$ref": "87" + "$ref": "94" }, "decorators": [], "isExactName": false }, { - "$id": "94", + "$id": "101", "kind": "enumvalue", "name": "Saturday", "value": "Saturday", "valueType": { - "$ref": "88" + "$ref": "95" }, "enumType": { - "$ref": "87" + "$ref": "94" }, "decorators": [], "isExactName": false }, { - "$id": "95", + "$id": "102", "kind": "enumvalue", "name": "Sunday", "value": "Sunday", "valueType": { - "$ref": "88" + "$ref": "95" }, "enumType": { - "$ref": "87" + "$ref": "94" }, "decorators": [], "isExactName": false @@ -1264,7 +1358,7 @@ "isExactName": false }, { - "$id": "96", + "$id": "103", "kind": "enum", "name": "Versions", "apiVersions": [ @@ -1273,7 +1367,7 @@ ], "crossLanguageDefinitionId": "SampleTypeSpec.Versions", "valueType": { - "$id": "97", + "$id": "104", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1281,29 +1375,29 @@ }, "values": [ { - "$id": "98", + "$id": "105", "kind": "enumvalue", "name": "2024-07-16-preview", "value": "2024-07-16-preview", "valueType": { - "$ref": "97" + "$ref": "104" }, "enumType": { - "$ref": "96" + "$ref": "103" }, "decorators": [], "isExactName": false }, { - "$id": "99", + "$id": "106", "kind": "enumvalue", "name": "2024-08-16-preview", "value": "2024-08-16-preview", "valueType": { - "$ref": "97" + "$ref": "104" }, "enumType": { - "$ref": "96" + "$ref": "103" }, "decorators": [], "isExactName": false, @@ -1323,13 +1417,13 @@ ], "constants": [ { - "$id": "100", + "$id": "107", "kind": "constant", "name": "ThingRequiredLiteralString", "namespace": "SampleTypeSpec", "usage": "Input,Output,Spread,Json", "valueType": { - "$id": "101", + "$id": "108", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1340,13 +1434,13 @@ "isExactName": false }, { - "$id": "102", + "$id": "109", "kind": "constant", "name": "ThingRequiredLiteralInt", "namespace": "SampleTypeSpec", "usage": "Input,Output,Spread,Json", "valueType": { - "$id": "103", + "$id": "110", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -1357,13 +1451,13 @@ "isExactName": false }, { - "$id": "104", + "$id": "111", "kind": "constant", "name": "ThingRequiredLiteralFloat", "namespace": "SampleTypeSpec", "usage": "Input,Output,Spread,Json", "valueType": { - "$id": "105", + "$id": "112", "kind": "float32", "name": "float32", "crossLanguageDefinitionId": "TypeSpec.float32", @@ -1374,13 +1468,13 @@ "isExactName": false }, { - "$id": "106", + "$id": "113", "kind": "constant", "name": "ThingRequiredLiteralBool", "namespace": "SampleTypeSpec", "usage": "Input,Output,Spread,Json", "valueType": { - "$id": "107", + "$id": "114", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -1391,13 +1485,13 @@ "isExactName": false }, { - "$id": "108", + "$id": "115", "kind": "constant", "name": "ThingOptionalLiteralBool", "namespace": "SampleTypeSpec", "usage": "Input,Output,Spread,Json", "valueType": { - "$id": "109", + "$id": "116", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -1408,13 +1502,13 @@ "isExactName": false }, { - "$id": "110", + "$id": "117", "kind": "constant", "name": "PetKind", "namespace": "SampleTypeSpec", "usage": "Input,Output,Json", "valueType": { - "$id": "111", + "$id": "118", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1425,13 +1519,13 @@ "isExactName": false }, { - "$id": "112", + "$id": "119", "kind": "constant", "name": "DogKind", "namespace": "SampleTypeSpec", "usage": "Input,Output,Json", "valueType": { - "$id": "113", + "$id": "120", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1442,13 +1536,13 @@ "isExactName": false }, { - "$id": "114", + "$id": "121", "kind": "constant", "name": "TreeSpecies", "namespace": "SampleTypeSpec", "usage": "Input,Output,Json,Xml", "valueType": { - "$id": "115", + "$id": "122", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1459,13 +1553,13 @@ "isExactName": false }, { - "$id": "116", + "$id": "123", "kind": "constant", "name": "GetTreeAsJsonResponseContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "117", + "$id": "124", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1476,13 +1570,13 @@ "isExactName": false }, { - "$id": "118", + "$id": "125", "kind": "constant", "name": "HelloAgainRequestContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "119", + "$id": "126", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1493,13 +1587,13 @@ "isExactName": false }, { - "$id": "120", + "$id": "127", "kind": "constant", "name": "HelloAgainRequestContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "121", + "$id": "128", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1510,13 +1604,13 @@ "isExactName": false }, { - "$id": "122", + "$id": "129", "kind": "constant", "name": "GetTreeAsJsonResponseContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "123", + "$id": "130", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1527,13 +1621,13 @@ "isExactName": false }, { - "$id": "124", + "$id": "131", "kind": "constant", "name": "GetTreeAsJsonResponseContentType2", "namespace": "", "usage": "None", "valueType": { - "$id": "125", + "$id": "132", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1544,13 +1638,13 @@ "isExactName": false }, { - "$id": "126", + "$id": "133", "kind": "constant", "name": "GetTreeAsJsonResponseContentType3", "namespace": "", "usage": "None", "valueType": { - "$id": "127", + "$id": "134", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1561,13 +1655,13 @@ "isExactName": false }, { - "$id": "128", + "$id": "135", "kind": "constant", "name": "GetTreeAsJsonResponseContentType4", "namespace": "", "usage": "None", "valueType": { - "$id": "129", + "$id": "136", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1578,13 +1672,13 @@ "isExactName": false }, { - "$id": "130", + "$id": "137", "kind": "constant", "name": "GetTreeAsJsonResponseContentType5", "namespace": "", "usage": "None", "valueType": { - "$id": "131", + "$id": "138", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1595,13 +1689,13 @@ "isExactName": false }, { - "$id": "132", + "$id": "139", "kind": "constant", "name": "GetTreeAsJsonResponseContentType6", "namespace": "", "usage": "None", "valueType": { - "$id": "133", + "$id": "140", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1612,13 +1706,13 @@ "isExactName": false }, { - "$id": "134", + "$id": "141", "kind": "constant", "name": "HelloLiteralRequestP1", "namespace": "", "usage": "None", "valueType": { - "$id": "135", + "$id": "142", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1629,13 +1723,13 @@ "isExactName": false }, { - "$id": "136", + "$id": "143", "kind": "constant", "name": "HelloLiteralRequestP11", "namespace": "", "usage": "None", "valueType": { - "$id": "137", + "$id": "144", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1646,13 +1740,13 @@ "isExactName": false }, { - "$id": "138", + "$id": "145", "kind": "constant", "name": "ThingRequiredLiteralInt1", "namespace": "", "usage": "None", "valueType": { - "$id": "139", + "$id": "146", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -1663,13 +1757,13 @@ "isExactName": false }, { - "$id": "140", + "$id": "147", "kind": "constant", "name": "ThingRequiredLiteralInt2", "namespace": "", "usage": "None", "valueType": { - "$id": "141", + "$id": "148", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -1680,13 +1774,13 @@ "isExactName": false }, { - "$id": "142", + "$id": "149", "kind": "constant", "name": "ThingOptionalLiteralBool1", "namespace": "", "usage": "None", "valueType": { - "$id": "143", + "$id": "150", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -1697,13 +1791,13 @@ "isExactName": false }, { - "$id": "144", + "$id": "151", "kind": "constant", "name": "ThingOptionalLiteralBool2", "namespace": "", "usage": "None", "valueType": { - "$id": "145", + "$id": "152", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -1714,13 +1808,13 @@ "isExactName": false }, { - "$id": "146", + "$id": "153", "kind": "constant", "name": "GetTreeAsJsonResponseContentType7", "namespace": "", "usage": "None", "valueType": { - "$id": "147", + "$id": "154", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1731,13 +1825,13 @@ "isExactName": false }, { - "$id": "148", + "$id": "155", "kind": "constant", "name": "GetTreeAsJsonResponseContentType8", "namespace": "", "usage": "None", "valueType": { - "$id": "149", + "$id": "156", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1748,13 +1842,13 @@ "isExactName": false }, { - "$id": "150", + "$id": "157", "kind": "constant", "name": "GetTreeAsJsonResponseContentType9", "namespace": "", "usage": "None", "valueType": { - "$id": "151", + "$id": "158", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1765,13 +1859,13 @@ "isExactName": false }, { - "$id": "152", + "$id": "159", "kind": "constant", "name": "GetTreeAsJsonResponseContentType10", "namespace": "", "usage": "None", "valueType": { - "$id": "153", + "$id": "160", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1782,13 +1876,13 @@ "isExactName": false }, { - "$id": "154", + "$id": "161", "kind": "constant", "name": "GetTreeAsJsonResponseContentType11", "namespace": "", "usage": "None", "valueType": { - "$id": "155", + "$id": "162", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1799,13 +1893,13 @@ "isExactName": false }, { - "$id": "156", + "$id": "163", "kind": "constant", "name": "AnonymousBodyRequestRequiredQueryParam", "namespace": "", "usage": "None", "valueType": { - "$id": "157", + "$id": "164", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1816,13 +1910,13 @@ "isExactName": false }, { - "$id": "158", + "$id": "165", "kind": "constant", "name": "AnonymousBodyRequestRequiredQueryParam1", "namespace": "", "usage": "None", "valueType": { - "$id": "159", + "$id": "166", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1833,13 +1927,13 @@ "isExactName": false }, { - "$id": "160", + "$id": "167", "kind": "constant", "name": "AnonymousBodyRequestRequiredHeader", "namespace": "", "usage": "None", "valueType": { - "$id": "161", + "$id": "168", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1850,13 +1944,13 @@ "isExactName": false }, { - "$id": "162", + "$id": "169", "kind": "constant", "name": "AnonymousBodyRequestRequiredHeader1", "namespace": "", "usage": "None", "valueType": { - "$id": "163", + "$id": "170", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1867,13 +1961,13 @@ "isExactName": false }, { - "$id": "164", + "$id": "171", "kind": "constant", "name": "GetTreeAsJsonResponseContentType12", "namespace": "", "usage": "None", "valueType": { - "$id": "165", + "$id": "172", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1884,13 +1978,13 @@ "isExactName": false }, { - "$id": "166", + "$id": "173", "kind": "constant", "name": "GetTreeAsJsonResponseContentType13", "namespace": "", "usage": "None", "valueType": { - "$id": "167", + "$id": "174", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1901,13 +1995,13 @@ "isExactName": false }, { - "$id": "168", + "$id": "175", "kind": "constant", "name": "ThingRequiredLiteralString1", "namespace": "", "usage": "None", "valueType": { - "$id": "169", + "$id": "176", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -1918,13 +2012,13 @@ "isExactName": false }, { - "$id": "170", + "$id": "177", "kind": "constant", "name": "ThingRequiredLiteralInt3", "namespace": "", "usage": "None", "valueType": { - "$id": "171", + "$id": "178", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -1935,13 +2029,13 @@ "isExactName": false }, { - "$id": "172", + "$id": "179", "kind": "constant", "name": "ThingRequiredLiteralFloat1", "namespace": "", "usage": "None", "valueType": { - "$id": "173", + "$id": "180", "kind": "float32", "name": "float32", "crossLanguageDefinitionId": "TypeSpec.float32", @@ -1952,13 +2046,13 @@ "isExactName": false }, { - "$id": "174", + "$id": "181", "kind": "constant", "name": "ThingRequiredLiteralBool1", "namespace": "", "usage": "None", "valueType": { - "$id": "175", + "$id": "182", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -1969,13 +2063,13 @@ "isExactName": false }, { - "$id": "176", + "$id": "183", "kind": "constant", "name": "ThingOptionalLiteralBool3", "namespace": "", "usage": "None", "valueType": { - "$id": "177", + "$id": "184", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -1986,13 +2080,13 @@ "isExactName": false }, { - "$id": "178", + "$id": "185", "kind": "constant", "name": "GetTreeAsJsonResponseContentType14", "namespace": "", "usage": "None", "valueType": { - "$id": "179", + "$id": "186", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2003,13 +2097,13 @@ "isExactName": false }, { - "$id": "180", + "$id": "187", "kind": "constant", "name": "GetTreeAsJsonResponseContentType15", "namespace": "", "usage": "None", "valueType": { - "$id": "181", + "$id": "188", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2020,13 +2114,13 @@ "isExactName": false }, { - "$id": "182", + "$id": "189", "kind": "constant", "name": "GetTreeAsJsonResponseContentType16", "namespace": "", "usage": "None", "valueType": { - "$id": "183", + "$id": "190", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2037,13 +2131,13 @@ "isExactName": false }, { - "$id": "184", + "$id": "191", "kind": "constant", "name": "GetTreeAsJsonResponseContentType17", "namespace": "", "usage": "None", "valueType": { - "$id": "185", + "$id": "192", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2054,13 +2148,13 @@ "isExactName": false }, { - "$id": "186", + "$id": "193", "kind": "constant", "name": "GetTreeAsJsonResponseContentType18", "namespace": "", "usage": "None", "valueType": { - "$id": "187", + "$id": "194", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2071,13 +2165,13 @@ "isExactName": false }, { - "$id": "188", + "$id": "195", "kind": "constant", "name": "HelloAgainRequestContentType2", "namespace": "", "usage": "None", "valueType": { - "$id": "189", + "$id": "196", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2088,13 +2182,13 @@ "isExactName": false }, { - "$id": "190", + "$id": "197", "kind": "constant", "name": "GetTreeAsJsonResponseContentType19", "namespace": "", "usage": "None", "valueType": { - "$id": "191", + "$id": "198", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2105,13 +2199,13 @@ "isExactName": false }, { - "$id": "192", + "$id": "199", "kind": "constant", "name": "GetTreeAsJsonResponseContentType20", "namespace": "", "usage": "None", "valueType": { - "$id": "193", + "$id": "200", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2122,13 +2216,13 @@ "isExactName": false }, { - "$id": "194", + "$id": "201", "kind": "constant", "name": "GetTreeAsJsonResponseContentType21", "namespace": "", "usage": "None", "valueType": { - "$id": "195", + "$id": "202", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2139,13 +2233,13 @@ "isExactName": false }, { - "$id": "196", + "$id": "203", "kind": "constant", "name": "GetTreeAsJsonResponseContentType22", "namespace": "", "usage": "None", "valueType": { - "$id": "197", + "$id": "204", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2156,13 +2250,13 @@ "isExactName": false }, { - "$id": "198", + "$id": "205", "kind": "constant", "name": "GetTreeAsJsonResponseContentType23", "namespace": "", "usage": "None", "valueType": { - "$id": "199", + "$id": "206", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2173,13 +2267,13 @@ "isExactName": false }, { - "$id": "200", + "$id": "207", "kind": "constant", "name": "GetTreeAsJsonResponseContentType24", "namespace": "", "usage": "None", "valueType": { - "$id": "201", + "$id": "208", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2190,13 +2284,13 @@ "isExactName": false }, { - "$id": "202", + "$id": "209", "kind": "constant", "name": "GetTreeAsJsonResponseContentType25", "namespace": "", "usage": "None", "valueType": { - "$id": "203", + "$id": "210", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2207,13 +2301,13 @@ "isExactName": false }, { - "$id": "204", + "$id": "211", "kind": "constant", "name": "GetTreeAsJsonResponseContentType26", "namespace": "", "usage": "None", "valueType": { - "$id": "205", + "$id": "212", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2224,13 +2318,13 @@ "isExactName": false }, { - "$id": "206", + "$id": "213", "kind": "constant", "name": "GetTreeAsJsonResponseContentType27", "namespace": "", "usage": "None", "valueType": { - "$id": "207", + "$id": "214", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2241,13 +2335,13 @@ "isExactName": false }, { - "$id": "208", + "$id": "215", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "209", + "$id": "216", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2258,13 +2352,13 @@ "isExactName": false }, { - "$id": "210", + "$id": "217", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "211", + "$id": "218", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2275,13 +2369,13 @@ "isExactName": false }, { - "$id": "212", + "$id": "219", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType2", "namespace": "", "usage": "None", "valueType": { - "$id": "213", + "$id": "220", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2292,13 +2386,13 @@ "isExactName": false }, { - "$id": "214", + "$id": "221", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType3", "namespace": "", "usage": "None", "valueType": { - "$id": "215", + "$id": "222", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2309,13 +2403,13 @@ "isExactName": false }, { - "$id": "216", + "$id": "223", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType4", "namespace": "", "usage": "None", "valueType": { - "$id": "217", + "$id": "224", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2326,13 +2420,13 @@ "isExactName": false }, { - "$id": "218", + "$id": "225", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType5", "namespace": "", "usage": "None", "valueType": { - "$id": "219", + "$id": "226", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2343,13 +2437,13 @@ "isExactName": false }, { - "$id": "220", + "$id": "227", "kind": "constant", "name": "UploadCatRequestContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "221", + "$id": "228", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2360,13 +2454,13 @@ "isExactName": false }, { - "$id": "222", + "$id": "229", "kind": "constant", "name": "UploadCatRequestContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "223", + "$id": "230", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2377,13 +2471,13 @@ "isExactName": false }, { - "$id": "224", + "$id": "231", "kind": "constant", "name": "SendJsonLinesRequestContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "225", + "$id": "232", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2394,13 +2488,13 @@ "isExactName": false }, { - "$id": "226", + "$id": "233", "kind": "constant", "name": "JsonlStreamStreamingItemContentType", "namespace": "TypeSpec.Http.Streams", "usage": "None", "valueType": { - "$id": "227", + "$id": "234", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2411,13 +2505,13 @@ "isExactName": false }, { - "$id": "228", + "$id": "235", "kind": "constant", "name": "SendJsonLinesRequestContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "229", + "$id": "236", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2428,13 +2522,13 @@ "isExactName": false }, { - "$id": "230", + "$id": "237", "kind": "constant", "name": "SendJsonLinesRequestContentType2", "namespace": "", "usage": "None", "valueType": { - "$id": "231", + "$id": "238", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2445,13 +2539,13 @@ "isExactName": false }, { - "$id": "232", + "$id": "239", "kind": "constant", "name": "ReceiveSseResponseContentType", "namespace": "", "usage": "None", "valueType": { - "$id": "233", + "$id": "240", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2462,13 +2556,13 @@ "isExactName": false }, { - "$id": "234", + "$id": "241", "kind": "constant", "name": "ReceiveSse", "namespace": "", "usage": "None", "valueType": { - "$id": "235", + "$id": "242", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2479,13 +2573,13 @@ "isExactName": false }, { - "$id": "236", + "$id": "243", "kind": "constant", "name": "ReceiveSseResponseContentType1", "namespace": "", "usage": "None", "valueType": { - "$id": "237", + "$id": "244", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2496,13 +2590,13 @@ "isExactName": false }, { - "$id": "238", + "$id": "245", "kind": "constant", "name": "SendJsonLinesRequestContentType3", "namespace": "", "usage": "None", "valueType": { - "$id": "239", + "$id": "246", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2513,13 +2607,13 @@ "isExactName": false }, { - "$id": "240", + "$id": "247", "kind": "constant", "name": "SendJsonLinesRequestContentType4", "namespace": "", "usage": "None", "valueType": { - "$id": "241", + "$id": "248", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2530,13 +2624,13 @@ "isExactName": false }, { - "$id": "242", + "$id": "249", "kind": "constant", "name": "GetTreeAsJsonResponseContentType28", "namespace": "", "usage": "None", "valueType": { - "$id": "243", + "$id": "250", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2547,13 +2641,13 @@ "isExactName": false }, { - "$id": "244", + "$id": "251", "kind": "constant", "name": "GetTreeAsJsonResponseContentType29", "namespace": "", "usage": "None", "valueType": { - "$id": "245", + "$id": "252", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2564,13 +2658,13 @@ "isExactName": false }, { - "$id": "246", + "$id": "253", "kind": "constant", "name": "GetTreeAsJsonResponseContentType30", "namespace": "", "usage": "None", "valueType": { - "$id": "247", + "$id": "254", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2581,13 +2675,13 @@ "isExactName": false }, { - "$id": "248", + "$id": "255", "kind": "constant", "name": "GetTreeAsJsonResponseContentType31", "namespace": "", "usage": "None", "valueType": { - "$id": "249", + "$id": "256", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2598,13 +2692,13 @@ "isExactName": false }, { - "$id": "250", + "$id": "257", "kind": "constant", "name": "GetTreeAsJsonResponseContentType32", "namespace": "", "usage": "None", "valueType": { - "$id": "251", + "$id": "258", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2615,13 +2709,13 @@ "isExactName": false }, { - "$id": "252", + "$id": "259", "kind": "constant", "name": "GetTreeAsJsonResponseContentType33", "namespace": "", "usage": "None", "valueType": { - "$id": "253", + "$id": "260", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2632,13 +2726,13 @@ "isExactName": false }, { - "$id": "254", + "$id": "261", "kind": "constant", "name": "GetTreeAsJsonResponseContentType34", "namespace": "", "usage": "None", "valueType": { - "$id": "255", + "$id": "262", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2649,13 +2743,13 @@ "isExactName": false }, { - "$id": "256", + "$id": "263", "kind": "constant", "name": "GetTreeAsJsonResponseContentType35", "namespace": "", "usage": "None", "valueType": { - "$id": "257", + "$id": "264", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2666,13 +2760,13 @@ "isExactName": false }, { - "$id": "258", + "$id": "265", "kind": "constant", "name": "GetTreeAsJsonResponseContentType36", "namespace": "", "usage": "None", "valueType": { - "$id": "259", + "$id": "266", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2683,13 +2777,13 @@ "isExactName": false }, { - "$id": "260", + "$id": "267", "kind": "constant", "name": "GetTreeAsJsonResponseContentType37", "namespace": "", "usage": "None", "valueType": { - "$id": "261", + "$id": "268", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2700,13 +2794,13 @@ "isExactName": false }, { - "$id": "262", + "$id": "269", "kind": "constant", "name": "GetTreeAsJsonResponseContentType38", "namespace": "", "usage": "None", "valueType": { - "$id": "263", + "$id": "270", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2717,13 +2811,13 @@ "isExactName": false }, { - "$id": "264", + "$id": "271", "kind": "constant", "name": "GetTreeAsJsonResponseContentType39", "namespace": "", "usage": "None", "valueType": { - "$id": "265", + "$id": "272", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2734,13 +2828,13 @@ "isExactName": false }, { - "$id": "266", + "$id": "273", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType6", "namespace": "", "usage": "None", "valueType": { - "$id": "267", + "$id": "274", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2751,13 +2845,13 @@ "isExactName": false }, { - "$id": "268", + "$id": "275", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType7", "namespace": "", "usage": "None", "valueType": { - "$id": "269", + "$id": "276", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2768,13 +2862,13 @@ "isExactName": false }, { - "$id": "270", + "$id": "277", "kind": "constant", "name": "GetTreeAsJsonResponseContentType40", "namespace": "", "usage": "None", "valueType": { - "$id": "271", + "$id": "278", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2785,13 +2879,13 @@ "isExactName": false }, { - "$id": "272", + "$id": "279", "kind": "constant", "name": "GetTreeAsJsonResponseContentType41", "namespace": "", "usage": "None", "valueType": { - "$id": "273", + "$id": "280", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2802,13 +2896,13 @@ "isExactName": false }, { - "$id": "274", + "$id": "281", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType8", "namespace": "", "usage": "None", "valueType": { - "$id": "275", + "$id": "282", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2819,13 +2913,13 @@ "isExactName": false }, { - "$id": "276", + "$id": "283", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType9", "namespace": "", "usage": "None", "valueType": { - "$id": "277", + "$id": "284", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2836,13 +2930,13 @@ "isExactName": false }, { - "$id": "278", + "$id": "285", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType10", "namespace": "", "usage": "None", "valueType": { - "$id": "279", + "$id": "286", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2853,13 +2947,13 @@ "isExactName": false }, { - "$id": "280", + "$id": "287", "kind": "constant", "name": "GetXmlAdvancedModelResponseContentType11", "namespace": "", "usage": "None", "valueType": { - "$id": "281", + "$id": "288", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2870,13 +2964,13 @@ "isExactName": false }, { - "$id": "282", + "$id": "289", "kind": "constant", "name": "GetTreeAsJsonResponseContentType42", "namespace": "", "usage": "None", "valueType": { - "$id": "283", + "$id": "290", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2887,13 +2981,13 @@ "isExactName": false }, { - "$id": "284", + "$id": "291", "kind": "constant", "name": "GetTreeAsJsonResponseContentType43", "namespace": "", "usage": "None", "valueType": { - "$id": "285", + "$id": "292", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2904,13 +2998,13 @@ "isExactName": false }, { - "$id": "286", + "$id": "293", "kind": "constant", "name": "GetTreeAsJsonResponseContentType44", "namespace": "", "usage": "None", "valueType": { - "$id": "287", + "$id": "294", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2921,13 +3015,13 @@ "isExactName": false }, { - "$id": "288", + "$id": "295", "kind": "constant", "name": "GetTreeAsJsonResponseContentType45", "namespace": "", "usage": "None", "valueType": { - "$id": "289", + "$id": "296", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2938,13 +3032,13 @@ "isExactName": false }, { - "$id": "290", + "$id": "297", "kind": "constant", "name": "GetTreeAsJsonResponseContentType46", "namespace": "", "usage": "None", "valueType": { - "$id": "291", + "$id": "298", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2955,13 +3049,47 @@ "isExactName": false }, { - "$id": "292", + "$id": "299", "kind": "constant", "name": "GetTreeAsJsonResponseContentType47", "namespace": "", "usage": "None", "valueType": { - "$id": "293", + "$id": "300", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [], + "isExactName": false + }, + { + "$id": "301", + "kind": "constant", + "name": "GetTreeAsJsonResponseContentType48", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "302", + "kind": "string", + "name": "string", + "crossLanguageDefinitionId": "TypeSpec.string", + "decorators": [] + }, + "value": "application/json", + "decorators": [], + "isExactName": false + }, + { + "$id": "303", + "kind": "constant", + "name": "GetTreeAsJsonResponseContentType49", + "namespace": "", + "usage": "None", + "valueType": { + "$id": "304", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -2974,7 +3102,7 @@ ], "models": [ { - "$id": "294", + "$id": "305", "kind": "model", "name": "Thing", "apiVersions": [ @@ -2994,7 +3122,7 @@ "isExactName": false, "properties": [ { - "$id": "295", + "$id": "306", "kind": "property", "name": "name", "apiVersions": [ @@ -3004,7 +3132,7 @@ "serializedName": "name", "doc": "name of the Thing", "type": { - "$id": "296", + "$id": "307", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3025,7 +3153,7 @@ "isExactName": false }, { - "$id": "297", + "$id": "308", "kind": "property", "name": "requiredUnion", "apiVersions": [ @@ -3035,23 +3163,23 @@ "serializedName": "requiredUnion", "doc": "required Union", "type": { - "$id": "298", + "$id": "309", "kind": "union", "name": "ThingRequiredUnion", "variantTypes": [ { - "$id": "299", + "$id": "310", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, { - "$id": "300", + "$id": "311", "kind": "array", "name": "Array", "valueType": { - "$id": "301", + "$id": "312", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3061,7 +3189,7 @@ "decorators": [] }, { - "$id": "302", + "$id": "313", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -3087,7 +3215,7 @@ "isExactName": false }, { - "$id": "303", + "$id": "314", "kind": "property", "name": "requiredLiteralString", "apiVersions": [ @@ -3097,7 +3225,7 @@ "serializedName": "requiredLiteralString", "doc": "required literal string", "type": { - "$ref": "100" + "$ref": "107" }, "optional": false, "readOnly": false, @@ -3114,7 +3242,7 @@ "isExactName": false }, { - "$id": "304", + "$id": "315", "kind": "property", "name": "requiredNullableString", "apiVersions": [ @@ -3124,10 +3252,10 @@ "serializedName": "requiredNullableString", "doc": "required nullable string", "type": { - "$id": "305", + "$id": "316", "kind": "nullable", "type": { - "$id": "306", + "$id": "317", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3150,7 +3278,7 @@ "isExactName": false }, { - "$id": "307", + "$id": "318", "kind": "property", "name": "optionalNullableString", "apiVersions": [ @@ -3160,10 +3288,10 @@ "serializedName": "optionalNullableString", "doc": "required optional string", "type": { - "$id": "308", + "$id": "319", "kind": "nullable", "type": { - "$id": "309", + "$id": "320", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3186,7 +3314,7 @@ "isExactName": false }, { - "$id": "310", + "$id": "321", "kind": "property", "name": "requiredLiteralInt", "apiVersions": [ @@ -3196,7 +3324,7 @@ "serializedName": "requiredLiteralInt", "doc": "required literal int", "type": { - "$ref": "102" + "$ref": "109" }, "optional": false, "readOnly": false, @@ -3213,7 +3341,7 @@ "isExactName": false }, { - "$id": "311", + "$id": "322", "kind": "property", "name": "requiredLiteralFloat", "apiVersions": [ @@ -3223,7 +3351,7 @@ "serializedName": "requiredLiteralFloat", "doc": "required literal float", "type": { - "$ref": "104" + "$ref": "111" }, "optional": false, "readOnly": false, @@ -3240,7 +3368,7 @@ "isExactName": false }, { - "$id": "312", + "$id": "323", "kind": "property", "name": "requiredLiteralBool", "apiVersions": [ @@ -3250,7 +3378,7 @@ "serializedName": "requiredLiteralBool", "doc": "required literal bool", "type": { - "$ref": "106" + "$ref": "113" }, "optional": false, "readOnly": false, @@ -3267,7 +3395,7 @@ "isExactName": false }, { - "$id": "313", + "$id": "324", "kind": "property", "name": "optionalLiteralString", "apiVersions": [ @@ -3294,7 +3422,7 @@ "isExactName": false }, { - "$id": "314", + "$id": "325", "kind": "property", "name": "requiredNullableLiteralString", "apiVersions": [ @@ -3304,7 +3432,7 @@ "serializedName": "requiredNullableLiteralString", "doc": "required nullable literal string", "type": { - "$id": "315", + "$id": "326", "kind": "nullable", "type": { "$ref": "5" @@ -3326,7 +3454,7 @@ "isExactName": false }, { - "$id": "316", + "$id": "327", "kind": "property", "name": "optionalLiteralInt", "apiVersions": [ @@ -3353,7 +3481,7 @@ "isExactName": false }, { - "$id": "317", + "$id": "328", "kind": "property", "name": "optionalLiteralFloat", "apiVersions": [ @@ -3380,7 +3508,7 @@ "isExactName": false }, { - "$id": "318", + "$id": "329", "kind": "property", "name": "optionalLiteralBool", "apiVersions": [ @@ -3390,7 +3518,7 @@ "serializedName": "optionalLiteralBool", "doc": "optional literal bool", "type": { - "$ref": "108" + "$ref": "115" }, "optional": true, "readOnly": false, @@ -3407,7 +3535,7 @@ "isExactName": false }, { - "$id": "319", + "$id": "330", "kind": "property", "name": "requiredBadDescription", "apiVersions": [ @@ -3417,7 +3545,7 @@ "serializedName": "requiredBadDescription", "doc": "description with xml <|endoftext|>", "type": { - "$id": "320", + "$id": "331", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3438,7 +3566,7 @@ "isExactName": false }, { - "$id": "321", + "$id": "332", "kind": "property", "name": "optionalNullableList", "apiVersions": [ @@ -3448,14 +3576,14 @@ "serializedName": "optionalNullableList", "doc": "optional nullable collection", "type": { - "$id": "322", + "$id": "333", "kind": "nullable", "type": { - "$id": "323", + "$id": "334", "kind": "array", "name": "Array1", "valueType": { - "$id": "324", + "$id": "335", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -3481,7 +3609,7 @@ "isExactName": false }, { - "$id": "325", + "$id": "336", "kind": "property", "name": "requiredNullableList", "apiVersions": [ @@ -3491,10 +3619,10 @@ "serializedName": "requiredNullableList", "doc": "required nullable collection", "type": { - "$id": "326", + "$id": "337", "kind": "nullable", "type": { - "$ref": "323" + "$ref": "334" }, "namespace": "SampleTypeSpec" }, @@ -3513,7 +3641,7 @@ "isExactName": false }, { - "$id": "327", + "$id": "338", "kind": "property", "name": "propertyWithSpecialDocs", "apiVersions": [ @@ -3523,7 +3651,7 @@ "serializedName": "propertyWithSpecialDocs", "doc": "This tests:\n- Simple bullet point. This bullet point is going to be very long to test how text wrapping is handled in bullet points within documentation comments. It should properly indent the wrapped lines.\n- Another bullet point with **bold text**. This bullet point is also intentionally long to see how the formatting is preserved when the text wraps onto multiple lines in the generated documentation.\n- Third bullet point with *italic text*. Similar to the previous points, this one is extended to ensure that the wrapping and formatting are correctly applied in the output.\n- Complex bullet point with **bold** and *italic* combined. This bullet point combines both bold and italic formatting and is long enough to test the wrapping behavior in such cases.\n- **Bold bullet point**: A bullet point that is entirely bolded. This point is also made lengthy to observe how the bold formatting is maintained across wrapped lines.\n- *Italic bullet point*: A bullet point that is entirely italicized. This final point is extended to verify that italic formatting is correctly applied even when the text spans multiple lines.", "type": { - "$id": "328", + "$id": "339", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3546,7 +3674,7 @@ ] }, { - "$id": "329", + "$id": "340", "kind": "model", "name": "RoundTripModel", "apiVersions": [ @@ -3566,7 +3694,7 @@ "isExactName": false, "properties": [ { - "$id": "330", + "$id": "341", "kind": "property", "name": "requiredString", "apiVersions": [ @@ -3576,7 +3704,7 @@ "serializedName": "requiredString", "doc": "Required string, illustrating a reference type property.", "type": { - "$id": "331", + "$id": "342", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3597,7 +3725,7 @@ "isExactName": false }, { - "$id": "332", + "$id": "343", "kind": "property", "name": "requiredInt", "apiVersions": [ @@ -3607,7 +3735,7 @@ "serializedName": "requiredInt", "doc": "Required int, illustrating a value type property.", "type": { - "$id": "333", + "$id": "344", "kind": "int32", "name": "int32", "encode": "string", @@ -3629,7 +3757,7 @@ "isExactName": false }, { - "$id": "334", + "$id": "345", "kind": "property", "name": "requiredCollection", "apiVersions": [ @@ -3639,7 +3767,7 @@ "serializedName": "requiredCollection", "doc": "Required collection of enums", "type": { - "$id": "335", + "$id": "346", "kind": "array", "name": "ArrayStringFixedEnum", "valueType": { @@ -3663,7 +3791,7 @@ "isExactName": false }, { - "$id": "336", + "$id": "347", "kind": "property", "name": "requiredDictionary", "apiVersions": [ @@ -3673,10 +3801,10 @@ "serializedName": "requiredDictionary", "doc": "Required dictionary of enums", "type": { - "$id": "337", + "$id": "348", "kind": "dict", "keyType": { - "$id": "338", + "$id": "349", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -3702,7 +3830,7 @@ "isExactName": false }, { - "$id": "339", + "$id": "350", "kind": "property", "name": "requiredModel", "apiVersions": [ @@ -3712,7 +3840,7 @@ "serializedName": "requiredModel", "doc": "Required model", "type": { - "$ref": "294" + "$ref": "305" }, "optional": false, "readOnly": false, @@ -3729,7 +3857,7 @@ "isExactName": false }, { - "$id": "340", + "$id": "351", "kind": "property", "name": "intExtensibleEnum", "apiVersions": [ @@ -3756,7 +3884,7 @@ "isExactName": false }, { - "$id": "341", + "$id": "352", "kind": "property", "name": "intExtensibleEnumCollection", "apiVersions": [ @@ -3766,7 +3894,7 @@ "serializedName": "intExtensibleEnumCollection", "doc": "this is a collection of int based extensible enum", "type": { - "$id": "342", + "$id": "353", "kind": "array", "name": "ArrayIntExtensibleEnum", "valueType": { @@ -3790,7 +3918,7 @@ "isExactName": false }, { - "$id": "343", + "$id": "354", "kind": "property", "name": "floatExtensibleEnum", "apiVersions": [ @@ -3817,7 +3945,7 @@ "isExactName": false }, { - "$id": "344", + "$id": "355", "kind": "property", "name": "floatExtensibleEnumWithIntValue", "apiVersions": [ @@ -3844,7 +3972,7 @@ "isExactName": false }, { - "$id": "345", + "$id": "356", "kind": "property", "name": "floatExtensibleEnumCollection", "apiVersions": [ @@ -3854,7 +3982,7 @@ "serializedName": "floatExtensibleEnumCollection", "doc": "this is a collection of float based extensible enum", "type": { - "$id": "346", + "$id": "357", "kind": "array", "name": "ArrayFloatExtensibleEnum", "valueType": { @@ -3878,7 +4006,7 @@ "isExactName": false }, { - "$id": "347", + "$id": "358", "kind": "property", "name": "floatFixedEnum", "apiVersions": [ @@ -3905,7 +4033,7 @@ "isExactName": false }, { - "$id": "348", + "$id": "359", "kind": "property", "name": "floatFixedEnumWithIntValue", "apiVersions": [ @@ -3932,7 +4060,7 @@ "isExactName": false }, { - "$id": "349", + "$id": "360", "kind": "property", "name": "floatFixedEnumCollection", "apiVersions": [ @@ -3942,7 +4070,7 @@ "serializedName": "floatFixedEnumCollection", "doc": "this is a collection of float based fixed enum", "type": { - "$id": "350", + "$id": "361", "kind": "array", "name": "ArrayFloatFixedEnum", "valueType": { @@ -3966,7 +4094,7 @@ "isExactName": false }, { - "$id": "351", + "$id": "362", "kind": "property", "name": "intFixedEnum", "apiVersions": [ @@ -3993,7 +4121,7 @@ "isExactName": false }, { - "$id": "352", + "$id": "363", "kind": "property", "name": "intFixedEnumCollection", "apiVersions": [ @@ -4003,7 +4131,7 @@ "serializedName": "intFixedEnumCollection", "doc": "this is a collection of int based fixed enum", "type": { - "$id": "353", + "$id": "364", "kind": "array", "name": "ArrayIntFixedEnum", "valueType": { @@ -4027,7 +4155,7 @@ "isExactName": false }, { - "$id": "354", + "$id": "365", "kind": "property", "name": "stringFixedEnum", "apiVersions": [ @@ -4054,7 +4182,7 @@ "isExactName": false }, { - "$id": "355", + "$id": "366", "kind": "property", "name": "requiredUnknown", "apiVersions": [ @@ -4064,7 +4192,7 @@ "serializedName": "requiredUnknown", "doc": "required unknown", "type": { - "$id": "356", + "$id": "367", "kind": "unknown", "name": "unknown", "crossLanguageDefinitionId": "", @@ -4085,7 +4213,7 @@ "isExactName": false }, { - "$id": "357", + "$id": "368", "kind": "property", "name": "optionalUnknown", "apiVersions": [ @@ -4095,7 +4223,7 @@ "serializedName": "optionalUnknown", "doc": "optional unknown", "type": { - "$id": "358", + "$id": "369", "kind": "unknown", "name": "unknown", "crossLanguageDefinitionId": "", @@ -4116,7 +4244,7 @@ "isExactName": false }, { - "$id": "359", + "$id": "370", "kind": "property", "name": "requiredRecordUnknown", "apiVersions": [ @@ -4126,17 +4254,17 @@ "serializedName": "requiredRecordUnknown", "doc": "required record of unknown", "type": { - "$id": "360", + "$id": "371", "kind": "dict", "keyType": { - "$id": "361", + "$id": "372", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "362", + "$id": "373", "kind": "unknown", "name": "unknown", "crossLanguageDefinitionId": "", @@ -4159,7 +4287,7 @@ "isExactName": false }, { - "$id": "363", + "$id": "374", "kind": "property", "name": "optionalRecordUnknown", "apiVersions": [ @@ -4169,7 +4297,7 @@ "serializedName": "optionalRecordUnknown", "doc": "optional record of unknown", "type": { - "$ref": "360" + "$ref": "371" }, "optional": true, "readOnly": false, @@ -4186,7 +4314,7 @@ "isExactName": false }, { - "$id": "364", + "$id": "375", "kind": "property", "name": "readOnlyRequiredRecordUnknown", "apiVersions": [ @@ -4196,7 +4324,7 @@ "serializedName": "readOnlyRequiredRecordUnknown", "doc": "required readonly record of unknown", "type": { - "$ref": "360" + "$ref": "371" }, "optional": false, "readOnly": true, @@ -4213,7 +4341,7 @@ "isExactName": false }, { - "$id": "365", + "$id": "376", "kind": "property", "name": "readOnlyOptionalRecordUnknown", "apiVersions": [ @@ -4223,7 +4351,7 @@ "serializedName": "readOnlyOptionalRecordUnknown", "doc": "optional readonly record of unknown", "type": { - "$ref": "360" + "$ref": "371" }, "optional": true, "readOnly": true, @@ -4240,7 +4368,7 @@ "isExactName": false }, { - "$id": "366", + "$id": "377", "kind": "property", "name": "modelWithRequiredNullable", "apiVersions": [ @@ -4250,7 +4378,7 @@ "serializedName": "modelWithRequiredNullable", "doc": "this is a model with required nullable properties", "type": { - "$id": "367", + "$id": "378", "kind": "model", "name": "ModelWithRequiredNullableProperties", "apiVersions": [ @@ -4270,7 +4398,7 @@ "isExactName": false, "properties": [ { - "$id": "368", + "$id": "379", "kind": "property", "name": "requiredNullablePrimitive", "apiVersions": [ @@ -4280,10 +4408,10 @@ "serializedName": "requiredNullablePrimitive", "doc": "required nullable primitive type", "type": { - "$id": "369", + "$id": "380", "kind": "nullable", "type": { - "$id": "370", + "$id": "381", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -4306,7 +4434,7 @@ "isExactName": false }, { - "$id": "371", + "$id": "382", "kind": "property", "name": "requiredExtensibleEnum", "apiVersions": [ @@ -4316,7 +4444,7 @@ "serializedName": "requiredExtensibleEnum", "doc": "required nullable extensible enum type", "type": { - "$id": "372", + "$id": "383", "kind": "nullable", "type": { "$ref": "27" @@ -4338,7 +4466,7 @@ "isExactName": false }, { - "$id": "373", + "$id": "384", "kind": "property", "name": "requiredFixedEnum", "apiVersions": [ @@ -4348,7 +4476,7 @@ "serializedName": "requiredFixedEnum", "doc": "required nullable fixed enum type", "type": { - "$id": "374", + "$id": "385", "kind": "nullable", "type": { "$ref": "17" @@ -4370,7 +4498,7 @@ "isExactName": false }, { - "$id": "375", + "$id": "386", "kind": "property", "name": "fixedUnion", "apiVersions": [ @@ -4396,7 +4524,7 @@ "isExactName": false }, { - "$id": "376", + "$id": "387", "kind": "property", "name": "numericEnum", "apiVersions": [ @@ -4438,7 +4566,7 @@ "isExactName": false }, { - "$id": "377", + "$id": "388", "kind": "property", "name": "requiredBytes", "apiVersions": [ @@ -4448,7 +4576,7 @@ "serializedName": "requiredBytes", "doc": "Required bytes", "type": { - "$id": "378", + "$id": "389", "kind": "bytes", "name": "bytes", "encode": "base64", @@ -4472,10 +4600,10 @@ ] }, { - "$ref": "367" + "$ref": "378" }, { - "$id": "379", + "$id": "390", "kind": "model", "name": "Wrapper", "apiVersions": [ @@ -4490,7 +4618,7 @@ "isExactName": false, "properties": [ { - "$id": "380", + "$id": "391", "kind": "property", "name": "p1", "apiVersions": [ @@ -4499,7 +4627,7 @@ ], "doc": "header parameter", "type": { - "$id": "381", + "$id": "392", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4516,7 +4644,7 @@ "isExactName": false }, { - "$id": "382", + "$id": "393", "kind": "property", "name": "action", "apiVersions": [ @@ -4525,7 +4653,7 @@ ], "doc": "body parameter", "type": { - "$ref": "329" + "$ref": "340" }, "optional": false, "readOnly": false, @@ -4538,7 +4666,7 @@ "isExactName": false }, { - "$id": "383", + "$id": "394", "kind": "property", "name": "p2", "apiVersions": [ @@ -4547,7 +4675,7 @@ ], "doc": "path parameter", "type": { - "$id": "384", + "$id": "395", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4566,7 +4694,7 @@ ] }, { - "$id": "385", + "$id": "396", "kind": "model", "name": "Friend", "apiVersions": [ @@ -4586,7 +4714,7 @@ "isExactName": false, "properties": [ { - "$id": "386", + "$id": "397", "kind": "property", "name": "name", "apiVersions": [ @@ -4596,7 +4724,7 @@ "serializedName": "name", "doc": "name of the NotFriend", "type": { - "$id": "387", + "$id": "398", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4619,7 +4747,7 @@ ] }, { - "$id": "388", + "$id": "399", "kind": "model", "name": "RenamedModel", "apiVersions": [ @@ -4639,7 +4767,7 @@ "isExactName": false, "properties": [ { - "$id": "389", + "$id": "400", "kind": "property", "name": "otherName", "apiVersions": [ @@ -4649,7 +4777,7 @@ "serializedName": "otherName", "doc": "name of the ModelWithClientName", "type": { - "$id": "390", + "$id": "401", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4672,7 +4800,7 @@ ] }, { - "$id": "391", + "$id": "402", "kind": "model", "name": "ReturnsAnonymousModelResponse", "apiVersions": [ @@ -4692,7 +4820,7 @@ "properties": [] }, { - "$id": "392", + "$id": "403", "kind": "model", "name": "ListWithNextLinkResponse", "apiVersions": [ @@ -4711,7 +4839,7 @@ "isExactName": false, "properties": [ { - "$id": "393", + "$id": "404", "kind": "property", "name": "things", "apiVersions": [ @@ -4720,11 +4848,11 @@ ], "serializedName": "things", "type": { - "$id": "394", + "$id": "405", "kind": "array", "name": "ArrayThing", "valueType": { - "$ref": "294" + "$ref": "305" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -4744,7 +4872,7 @@ "isExactName": false }, { - "$id": "395", + "$id": "406", "kind": "property", "name": "next", "apiVersions": [ @@ -4753,7 +4881,7 @@ ], "serializedName": "next", "type": { - "$id": "396", + "$id": "407", "kind": "url", "name": "url", "crossLanguageDefinitionId": "TypeSpec.url", @@ -4776,7 +4904,7 @@ ] }, { - "$id": "397", + "$id": "408", "kind": "model", "name": "ListWithStringNextLinkResponse", "apiVersions": [ @@ -4795,7 +4923,7 @@ "isExactName": false, "properties": [ { - "$id": "398", + "$id": "409", "kind": "property", "name": "things", "apiVersions": [ @@ -4804,7 +4932,7 @@ ], "serializedName": "things", "type": { - "$ref": "394" + "$ref": "405" }, "optional": false, "readOnly": false, @@ -4821,7 +4949,7 @@ "isExactName": false }, { - "$id": "399", + "$id": "410", "kind": "property", "name": "next", "apiVersions": [ @@ -4830,7 +4958,7 @@ ], "serializedName": "next", "type": { - "$id": "400", + "$id": "411", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4853,7 +4981,7 @@ ] }, { - "$id": "401", + "$id": "412", "kind": "model", "name": "ListWithContinuationTokenResponse", "apiVersions": [ @@ -4872,7 +5000,7 @@ "isExactName": false, "properties": [ { - "$id": "402", + "$id": "413", "kind": "property", "name": "things", "apiVersions": [ @@ -4881,7 +5009,7 @@ ], "serializedName": "things", "type": { - "$ref": "394" + "$ref": "405" }, "optional": false, "readOnly": false, @@ -4898,7 +5026,7 @@ "isExactName": false }, { - "$id": "403", + "$id": "414", "kind": "property", "name": "nextToken", "apiVersions": [ @@ -4907,7 +5035,7 @@ ], "serializedName": "nextToken", "type": { - "$id": "404", + "$id": "415", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -4930,7 +5058,7 @@ ] }, { - "$id": "405", + "$id": "416", "kind": "model", "name": "ListWithContinuationTokenHeaderResponseResponse", "apiVersions": [], @@ -4946,7 +5074,7 @@ "isExactName": false, "properties": [ { - "$id": "406", + "$id": "417", "kind": "property", "name": "things", "apiVersions": [ @@ -4955,7 +5083,7 @@ ], "serializedName": "things", "type": { - "$ref": "394" + "$ref": "405" }, "optional": false, "readOnly": false, @@ -4974,7 +5102,7 @@ ] }, { - "$id": "407", + "$id": "418", "kind": "model", "name": "PageThing", "apiVersions": [ @@ -4993,7 +5121,7 @@ "isExactName": false, "properties": [ { - "$id": "408", + "$id": "419", "kind": "property", "name": "items", "apiVersions": [ @@ -5002,7 +5130,7 @@ ], "serializedName": "items", "type": { - "$ref": "394" + "$ref": "405" }, "optional": false, "readOnly": false, @@ -5021,7 +5149,7 @@ ] }, { - "$id": "409", + "$id": "420", "kind": "model", "name": "ModelWithEmbeddedNonBodyParameters", "apiVersions": [ @@ -5040,7 +5168,7 @@ "isExactName": false, "properties": [ { - "$id": "410", + "$id": "421", "kind": "property", "name": "name", "apiVersions": [ @@ -5050,7 +5178,7 @@ "serializedName": "name", "doc": "name of the ModelWithEmbeddedNonBodyParameters", "type": { - "$id": "411", + "$id": "422", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5071,7 +5199,7 @@ "isExactName": false }, { - "$id": "412", + "$id": "423", "kind": "property", "name": "requiredHeader", "apiVersions": [ @@ -5081,7 +5209,7 @@ "serializedName": "requiredHeader", "doc": "required header parameter", "type": { - "$id": "413", + "$id": "424", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5102,7 +5230,7 @@ "isExactName": false }, { - "$id": "414", + "$id": "425", "kind": "property", "name": "optionalHeader", "apiVersions": [ @@ -5112,7 +5240,7 @@ "serializedName": "optionalHeader", "doc": "optional header parameter", "type": { - "$id": "415", + "$id": "426", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5133,7 +5261,7 @@ "isExactName": false }, { - "$id": "416", + "$id": "427", "kind": "property", "name": "requiredQuery", "apiVersions": [ @@ -5143,7 +5271,7 @@ "serializedName": "requiredQuery", "doc": "required query parameter", "type": { - "$id": "417", + "$id": "428", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5164,7 +5292,7 @@ "isExactName": false }, { - "$id": "418", + "$id": "429", "kind": "property", "name": "optionalQuery", "apiVersions": [ @@ -5174,7 +5302,7 @@ "serializedName": "optionalQuery", "doc": "optional query parameter", "type": { - "$id": "419", + "$id": "430", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5197,7 +5325,7 @@ ] }, { - "$id": "420", + "$id": "431", "kind": "model", "name": "DynamicModel", "apiVersions": [ @@ -5222,7 +5350,7 @@ "isExactName": false, "properties": [ { - "$id": "421", + "$id": "432", "kind": "property", "name": "name", "apiVersions": [ @@ -5231,7 +5359,7 @@ ], "serializedName": "name", "type": { - "$id": "422", + "$id": "433", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5252,7 +5380,7 @@ "isExactName": false }, { - "$id": "423", + "$id": "434", "kind": "property", "name": "optionalUnknown", "apiVersions": [ @@ -5261,7 +5389,7 @@ ], "serializedName": "optionalUnknown", "type": { - "$id": "424", + "$id": "435", "kind": "unknown", "name": "unknown", "crossLanguageDefinitionId": "", @@ -5282,7 +5410,7 @@ "isExactName": false }, { - "$id": "425", + "$id": "436", "kind": "property", "name": "optionalInt", "apiVersions": [ @@ -5291,7 +5419,7 @@ ], "serializedName": "optionalInt", "type": { - "$id": "426", + "$id": "437", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -5312,7 +5440,7 @@ "isExactName": false }, { - "$id": "427", + "$id": "438", "kind": "property", "name": "optionalNullableList", "apiVersions": [ @@ -5321,10 +5449,10 @@ ], "serializedName": "optionalNullableList", "type": { - "$id": "428", + "$id": "439", "kind": "nullable", "type": { - "$ref": "323" + "$ref": "334" }, "namespace": "SampleTypeSpec" }, @@ -5343,7 +5471,7 @@ "isExactName": false }, { - "$id": "429", + "$id": "440", "kind": "property", "name": "requiredNullableList", "apiVersions": [ @@ -5352,10 +5480,10 @@ ], "serializedName": "requiredNullableList", "type": { - "$id": "430", + "$id": "441", "kind": "nullable", "type": { - "$ref": "323" + "$ref": "334" }, "namespace": "SampleTypeSpec" }, @@ -5374,7 +5502,7 @@ "isExactName": false }, { - "$id": "431", + "$id": "442", "kind": "property", "name": "optionalNullableDictionary", "apiVersions": [ @@ -5383,20 +5511,20 @@ ], "serializedName": "optionalNullableDictionary", "type": { - "$id": "432", + "$id": "443", "kind": "nullable", "type": { - "$id": "433", + "$id": "444", "kind": "dict", "keyType": { - "$id": "434", + "$id": "445", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "435", + "$id": "446", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -5421,7 +5549,7 @@ "isExactName": false }, { - "$id": "436", + "$id": "447", "kind": "property", "name": "requiredNullableDictionary", "apiVersions": [ @@ -5430,10 +5558,10 @@ ], "serializedName": "requiredNullableDictionary", "type": { - "$id": "437", + "$id": "448", "kind": "nullable", "type": { - "$ref": "433" + "$ref": "444" }, "namespace": "SampleTypeSpec" }, @@ -5452,7 +5580,7 @@ "isExactName": false }, { - "$id": "438", + "$id": "449", "kind": "property", "name": "primitiveDictionary", "apiVersions": [ @@ -5461,7 +5589,7 @@ ], "serializedName": "primitiveDictionary", "type": { - "$ref": "433" + "$ref": "444" }, "optional": false, "readOnly": false, @@ -5478,7 +5606,7 @@ "isExactName": false }, { - "$id": "439", + "$id": "450", "kind": "property", "name": "foo", "apiVersions": [ @@ -5487,7 +5615,7 @@ ], "serializedName": "foo", "type": { - "$id": "440", + "$id": "451", "kind": "model", "name": "AnotherDynamicModel", "apiVersions": [ @@ -5512,7 +5640,7 @@ "isExactName": false, "properties": [ { - "$id": "441", + "$id": "452", "kind": "property", "name": "bar", "apiVersions": [ @@ -5521,7 +5649,7 @@ ], "serializedName": "bar", "type": { - "$id": "442", + "$id": "453", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5558,7 +5686,7 @@ "isExactName": false }, { - "$id": "443", + "$id": "454", "kind": "property", "name": "listFoo", "apiVersions": [ @@ -5567,11 +5695,11 @@ ], "serializedName": "listFoo", "type": { - "$id": "444", + "$id": "455", "kind": "array", "name": "ArrayAnotherDynamicModel", "valueType": { - "$ref": "440" + "$ref": "451" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -5591,7 +5719,7 @@ "isExactName": false }, { - "$id": "445", + "$id": "456", "kind": "property", "name": "listOfListFoo", "apiVersions": [ @@ -5600,11 +5728,11 @@ ], "serializedName": "listOfListFoo", "type": { - "$id": "446", + "$id": "457", "kind": "array", "name": "ArrayArray", "valueType": { - "$ref": "444" + "$ref": "455" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -5624,7 +5752,7 @@ "isExactName": false }, { - "$id": "447", + "$id": "458", "kind": "property", "name": "dictionaryFoo", "apiVersions": [ @@ -5633,17 +5761,17 @@ ], "serializedName": "dictionaryFoo", "type": { - "$id": "448", + "$id": "459", "kind": "dict", "keyType": { - "$id": "449", + "$id": "460", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$ref": "440" + "$ref": "451" }, "decorators": [] }, @@ -5662,7 +5790,7 @@ "isExactName": false }, { - "$id": "450", + "$id": "461", "kind": "property", "name": "dictionaryOfDictionaryFoo", "apiVersions": [ @@ -5671,17 +5799,17 @@ ], "serializedName": "dictionaryOfDictionaryFoo", "type": { - "$id": "451", + "$id": "462", "kind": "dict", "keyType": { - "$id": "452", + "$id": "463", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$ref": "448" + "$ref": "459" }, "decorators": [] }, @@ -5700,7 +5828,7 @@ "isExactName": false }, { - "$id": "453", + "$id": "464", "kind": "property", "name": "dictionaryListFoo", "apiVersions": [ @@ -5709,17 +5837,17 @@ ], "serializedName": "dictionaryListFoo", "type": { - "$id": "454", + "$id": "465", "kind": "dict", "keyType": { - "$id": "455", + "$id": "466", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$ref": "444" + "$ref": "455" }, "decorators": [] }, @@ -5738,7 +5866,7 @@ "isExactName": false }, { - "$id": "456", + "$id": "467", "kind": "property", "name": "listOfDictionaryFoo", "apiVersions": [ @@ -5747,11 +5875,11 @@ ], "serializedName": "listOfDictionaryFoo", "type": { - "$id": "457", + "$id": "468", "kind": "array", "name": "ArrayRecord", "valueType": { - "$ref": "448" + "$ref": "459" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -5773,10 +5901,10 @@ ] }, { - "$ref": "440" + "$ref": "451" }, { - "$id": "458", + "$id": "469", "kind": "model", "name": "XmlAdvancedModel", "apiVersions": [ @@ -5805,7 +5933,7 @@ "isExactName": false, "properties": [ { - "$id": "459", + "$id": "470", "kind": "property", "name": "name", "apiVersions": [ @@ -5815,7 +5943,7 @@ "serializedName": "name", "doc": "A simple string property", "type": { - "$id": "460", + "$id": "471", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5838,7 +5966,7 @@ "isExactName": false }, { - "$id": "461", + "$id": "472", "kind": "property", "name": "age", "apiVersions": [ @@ -5848,7 +5976,7 @@ "serializedName": "age", "doc": "An integer property", "type": { - "$id": "462", + "$id": "473", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -5871,7 +5999,7 @@ "isExactName": false }, { - "$id": "463", + "$id": "474", "kind": "property", "name": "enabled", "apiVersions": [ @@ -5881,7 +6009,7 @@ "serializedName": "enabled", "doc": "A boolean property", "type": { - "$id": "464", + "$id": "475", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -5904,7 +6032,7 @@ "isExactName": false }, { - "$id": "465", + "$id": "476", "kind": "property", "name": "score", "apiVersions": [ @@ -5914,7 +6042,7 @@ "serializedName": "score", "doc": "A float property", "type": { - "$id": "466", + "$id": "477", "kind": "float32", "name": "float32", "crossLanguageDefinitionId": "TypeSpec.float32", @@ -5937,7 +6065,7 @@ "isExactName": false }, { - "$id": "467", + "$id": "478", "kind": "property", "name": "optionalString", "apiVersions": [ @@ -5947,7 +6075,7 @@ "serializedName": "optionalString", "doc": "An optional string", "type": { - "$id": "468", + "$id": "479", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -5970,7 +6098,7 @@ "isExactName": false }, { - "$id": "469", + "$id": "480", "kind": "property", "name": "optionalInt", "apiVersions": [ @@ -5980,7 +6108,7 @@ "serializedName": "optionalInt", "doc": "An optional integer", "type": { - "$id": "470", + "$id": "481", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -6003,7 +6131,7 @@ "isExactName": false }, { - "$id": "471", + "$id": "482", "kind": "property", "name": "nullableString", "apiVersions": [ @@ -6013,10 +6141,10 @@ "serializedName": "nullableString", "doc": "A nullable string", "type": { - "$id": "472", + "$id": "483", "kind": "nullable", "type": { - "$id": "473", + "$id": "484", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6041,7 +6169,7 @@ "isExactName": false }, { - "$id": "474", + "$id": "485", "kind": "property", "name": "id", "apiVersions": [ @@ -6051,7 +6179,7 @@ "serializedName": "id", "doc": "A string as XML attribute", "type": { - "$id": "475", + "$id": "486", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6079,7 +6207,7 @@ "isExactName": false }, { - "$id": "476", + "$id": "487", "kind": "property", "name": "version", "apiVersions": [ @@ -6089,7 +6217,7 @@ "serializedName": "version", "doc": "An integer as XML attribute", "type": { - "$id": "477", + "$id": "488", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -6117,7 +6245,7 @@ "isExactName": false }, { - "$id": "478", + "$id": "489", "kind": "property", "name": "isActive", "apiVersions": [ @@ -6127,7 +6255,7 @@ "serializedName": "isActive", "doc": "A boolean as XML attribute", "type": { - "$id": "479", + "$id": "490", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -6155,7 +6283,7 @@ "isExactName": false }, { - "$id": "480", + "$id": "491", "kind": "property", "name": "originalName", "apiVersions": [ @@ -6165,7 +6293,7 @@ "serializedName": "RenamedProperty", "doc": "A property with a custom XML element name", "type": { - "$id": "481", + "$id": "492", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6195,7 +6323,7 @@ "isExactName": false }, { - "$id": "482", + "$id": "493", "kind": "property", "name": "xmlIdentifier", "apiVersions": [ @@ -6205,7 +6333,7 @@ "serializedName": "xml-id", "doc": "An attribute with a custom XML name", "type": { - "$id": "483", + "$id": "494", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6239,7 +6367,7 @@ "isExactName": false }, { - "$id": "484", + "$id": "495", "kind": "property", "name": "content", "apiVersions": [ @@ -6249,7 +6377,7 @@ "serializedName": "content", "doc": "Text content in the element (unwrapped string)", "type": { - "$id": "485", + "$id": "496", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6277,7 +6405,7 @@ "isExactName": false }, { - "$id": "486", + "$id": "497", "kind": "property", "name": "unwrappedStrings", "apiVersions": [ @@ -6287,7 +6415,7 @@ "serializedName": "unwrappedStrings", "doc": "An unwrapped array of strings - items appear directly without wrapper", "type": { - "$ref": "300" + "$ref": "311" }, "optional": false, "readOnly": false, @@ -6312,7 +6440,7 @@ "isExactName": false }, { - "$id": "487", + "$id": "498", "kind": "property", "name": "unwrappedCounts", "apiVersions": [ @@ -6322,7 +6450,7 @@ "serializedName": "unwrappedCounts", "doc": "An unwrapped array of integers", "type": { - "$ref": "323" + "$ref": "334" }, "optional": false, "readOnly": false, @@ -6347,7 +6475,7 @@ "isExactName": false }, { - "$id": "488", + "$id": "499", "kind": "property", "name": "unwrappedItems", "apiVersions": [ @@ -6357,11 +6485,11 @@ "serializedName": "unwrappedItems", "doc": "An unwrapped array of models", "type": { - "$id": "489", + "$id": "500", "kind": "array", "name": "ArrayXmlItem", "valueType": { - "$id": "490", + "$id": "501", "kind": "model", "name": "XmlItem", "apiVersions": [ @@ -6390,7 +6518,7 @@ "isExactName": false, "properties": [ { - "$id": "491", + "$id": "502", "kind": "property", "name": "itemName", "apiVersions": [ @@ -6400,7 +6528,7 @@ "serializedName": "itemName", "doc": "The item name", "type": { - "$id": "492", + "$id": "503", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6423,7 +6551,7 @@ "isExactName": false }, { - "$id": "493", + "$id": "504", "kind": "property", "name": "itemValue", "apiVersions": [ @@ -6433,7 +6561,7 @@ "serializedName": "itemValue", "doc": "The item value", "type": { - "$id": "494", + "$id": "505", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -6456,7 +6584,7 @@ "isExactName": false }, { - "$id": "495", + "$id": "506", "kind": "property", "name": "itemId", "apiVersions": [ @@ -6466,7 +6594,7 @@ "serializedName": "itemId", "doc": "Item ID as attribute", "type": { - "$id": "496", + "$id": "507", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6521,7 +6649,7 @@ "isExactName": false }, { - "$id": "497", + "$id": "508", "kind": "property", "name": "wrappedColors", "apiVersions": [ @@ -6531,7 +6659,7 @@ "serializedName": "wrappedColors", "doc": "A wrapped array of strings (default)", "type": { - "$ref": "300" + "$ref": "311" }, "optional": false, "readOnly": false, @@ -6551,7 +6679,7 @@ "isExactName": false }, { - "$id": "498", + "$id": "509", "kind": "property", "name": "items", "apiVersions": [ @@ -6561,7 +6689,7 @@ "serializedName": "ItemCollection", "doc": "A wrapped array with custom wrapper name", "type": { - "$ref": "489" + "$ref": "500" }, "optional": false, "readOnly": false, @@ -6588,7 +6716,7 @@ "isExactName": false }, { - "$id": "499", + "$id": "510", "kind": "property", "name": "nestedModel", "apiVersions": [ @@ -6598,7 +6726,7 @@ "serializedName": "nestedModel", "doc": "A nested model property", "type": { - "$id": "500", + "$id": "511", "kind": "model", "name": "XmlNestedModel", "apiVersions": [ @@ -6620,7 +6748,7 @@ "isExactName": false, "properties": [ { - "$id": "501", + "$id": "512", "kind": "property", "name": "value", "apiVersions": [ @@ -6630,7 +6758,7 @@ "serializedName": "value", "doc": "The value of the nested model", "type": { - "$id": "502", + "$id": "513", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6653,7 +6781,7 @@ "isExactName": false }, { - "$id": "503", + "$id": "514", "kind": "property", "name": "nestedId", "apiVersions": [ @@ -6663,7 +6791,7 @@ "serializedName": "nestedId", "doc": "An attribute on the nested model", "type": { - "$id": "504", + "$id": "515", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -6709,7 +6837,7 @@ "isExactName": false }, { - "$id": "505", + "$id": "516", "kind": "property", "name": "optionalNestedModel", "apiVersions": [ @@ -6719,7 +6847,7 @@ "serializedName": "optionalNestedModel", "doc": "An optional nested model", "type": { - "$ref": "500" + "$ref": "511" }, "optional": true, "readOnly": false, @@ -6738,7 +6866,7 @@ "isExactName": false }, { - "$id": "506", + "$id": "517", "kind": "property", "name": "metadata", "apiVersions": [ @@ -6748,17 +6876,17 @@ "serializedName": "metadata", "doc": "A dictionary property", "type": { - "$id": "507", + "$id": "518", "kind": "dict", "keyType": { - "$id": "508", + "$id": "519", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "509", + "$id": "520", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6783,7 +6911,7 @@ "isExactName": false }, { - "$id": "510", + "$id": "521", "kind": "property", "name": "createdAt", "apiVersions": [ @@ -6793,12 +6921,12 @@ "serializedName": "createdAt", "doc": "A date-time property", "type": { - "$id": "511", + "$id": "522", "kind": "utcDateTime", "name": "utcDateTime", "encode": "rfc3339", "wireType": { - "$id": "512", + "$id": "523", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6824,7 +6952,7 @@ "isExactName": false }, { - "$id": "513", + "$id": "524", "kind": "property", "name": "duration", "apiVersions": [ @@ -6834,12 +6962,12 @@ "serializedName": "duration", "doc": "A duration property", "type": { - "$id": "514", + "$id": "525", "kind": "duration", "name": "duration", "encode": "ISO8601", "wireType": { - "$id": "515", + "$id": "526", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -6865,7 +6993,7 @@ "isExactName": false }, { - "$id": "516", + "$id": "527", "kind": "property", "name": "data", "apiVersions": [ @@ -6875,7 +7003,7 @@ "serializedName": "data", "doc": "A bytes property", "type": { - "$id": "517", + "$id": "528", "kind": "bytes", "name": "bytes", "encode": "base64", @@ -6899,7 +7027,7 @@ "isExactName": false }, { - "$id": "518", + "$id": "529", "kind": "property", "name": "optionalRecordUnknown", "apiVersions": [ @@ -6909,7 +7037,7 @@ "serializedName": "optionalRecordUnknown", "doc": "optional record of unknown", "type": { - "$ref": "360" + "$ref": "371" }, "optional": true, "readOnly": false, @@ -6928,7 +7056,7 @@ "isExactName": false }, { - "$id": "519", + "$id": "530", "kind": "property", "name": "fixedEnum", "apiVersions": [ @@ -6957,7 +7085,7 @@ "isExactName": false }, { - "$id": "520", + "$id": "531", "kind": "property", "name": "extensibleEnum", "apiVersions": [ @@ -6986,7 +7114,7 @@ "isExactName": false }, { - "$id": "521", + "$id": "532", "kind": "property", "name": "optionalFixedEnum", "apiVersions": [ @@ -7015,7 +7143,7 @@ "isExactName": false }, { - "$id": "522", + "$id": "533", "kind": "property", "name": "optionalExtensibleEnum", "apiVersions": [ @@ -7044,7 +7172,7 @@ "isExactName": false }, { - "$id": "523", + "$id": "534", "kind": "property", "name": "label", "apiVersions": [ @@ -7053,7 +7181,7 @@ ], "serializedName": "label", "type": { - "$id": "524", + "$id": "535", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7068,14 +7196,14 @@ "name": "TypeSpec.Xml.@ns", "arguments": { "ns": { - "$id": "525", + "$id": "536", "kind": "enumvalue", "decorators": [], "name": "ns1", "isExactName": false, "value": "https://example.com/ns1", "enumType": { - "$id": "526", + "$id": "537", "kind": "enum", "decorators": [ { @@ -7088,7 +7216,7 @@ "isExactName": false, "namespace": "SampleTypeSpec", "valueType": { - "$id": "527", + "$id": "538", "kind": "string", "decorators": [], "doc": "A sequence of textual characters.", @@ -7097,32 +7225,32 @@ }, "values": [ { - "$id": "528", + "$id": "539", "kind": "enumvalue", "decorators": [], "name": "ns1", "isExactName": false, "value": "https://example.com/ns1", "enumType": { - "$ref": "526" + "$ref": "537" }, "valueType": { - "$ref": "527" + "$ref": "538" }, "crossLanguageDefinitionId": "SampleTypeSpec.XmlNamespaces.ns1" }, { - "$id": "529", + "$id": "540", "kind": "enumvalue", "decorators": [], "name": "ns2", "isExactName": false, "value": "https://example.com/ns2", "enumType": { - "$ref": "526" + "$ref": "537" }, "valueType": { - "$ref": "527" + "$ref": "538" }, "crossLanguageDefinitionId": "SampleTypeSpec.XmlNamespaces.ns2" } @@ -7140,7 +7268,7 @@ "__accessSet": true }, "valueType": { - "$ref": "527" + "$ref": "538" }, "crossLanguageDefinitionId": "SampleTypeSpec.XmlNamespaces.ns1" } @@ -7167,7 +7295,7 @@ "isExactName": false }, { - "$id": "530", + "$id": "541", "kind": "property", "name": "daysUsed", "apiVersions": [ @@ -7176,7 +7304,7 @@ ], "serializedName": "daysUsed", "type": { - "$id": "531", + "$id": "542", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -7191,17 +7319,17 @@ "name": "TypeSpec.Xml.@ns", "arguments": { "ns": { - "$id": "532", + "$id": "543", "kind": "enumvalue", "decorators": [], "name": "ns2", "isExactName": false, "value": "https://example.com/ns2", "enumType": { - "$ref": "526" + "$ref": "537" }, "valueType": { - "$ref": "527" + "$ref": "538" }, "crossLanguageDefinitionId": "SampleTypeSpec.XmlNamespaces.ns2" } @@ -7224,7 +7352,7 @@ "isExactName": false }, { - "$id": "533", + "$id": "544", "kind": "property", "name": "fooItems", "apiVersions": [ @@ -7233,7 +7361,7 @@ ], "serializedName": "fooItems", "type": { - "$ref": "300" + "$ref": "311" }, "optional": false, "readOnly": false, @@ -7265,7 +7393,7 @@ "isExactName": false }, { - "$id": "534", + "$id": "545", "kind": "property", "name": "anotherModel", "apiVersions": [ @@ -7274,7 +7402,7 @@ ], "serializedName": "anotherModel", "type": { - "$ref": "500" + "$ref": "511" }, "optional": false, "readOnly": false, @@ -7305,7 +7433,7 @@ "isExactName": false }, { - "$id": "535", + "$id": "546", "kind": "property", "name": "modelsWithNamespaces", "apiVersions": [ @@ -7314,11 +7442,11 @@ ], "serializedName": "modelsWithNamespaces", "type": { - "$id": "536", + "$id": "547", "kind": "array", "name": "ArrayXmlModelWithNamespace", "valueType": { - "$id": "537", + "$id": "548", "kind": "model", "name": "XmlModelWithNamespace", "apiVersions": [ @@ -7351,7 +7479,7 @@ "isExactName": false, "properties": [ { - "$id": "538", + "$id": "549", "kind": "property", "name": "foo", "apiVersions": [ @@ -7360,7 +7488,7 @@ ], "serializedName": "foo", "type": { - "$id": "539", + "$id": "550", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7409,7 +7537,7 @@ "isExactName": false }, { - "$id": "540", + "$id": "551", "kind": "property", "name": "unwrappedModelsWithNamespaces", "apiVersions": [ @@ -7418,7 +7546,7 @@ ], "serializedName": "unwrappedModelsWithNamespaces", "type": { - "$ref": "536" + "$ref": "547" }, "optional": false, "readOnly": false, @@ -7443,7 +7571,7 @@ "isExactName": false }, { - "$id": "541", + "$id": "552", "kind": "property", "name": "listOfListFoo", "apiVersions": [ @@ -7452,11 +7580,11 @@ ], "serializedName": "listOfListFoo", "type": { - "$id": "542", + "$id": "553", "kind": "array", "name": "ArrayArray1", "valueType": { - "$ref": "489" + "$ref": "500" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -7479,7 +7607,7 @@ "isExactName": false }, { - "$id": "543", + "$id": "554", "kind": "property", "name": "dictionaryFoo", "apiVersions": [ @@ -7488,17 +7616,17 @@ ], "serializedName": "dictionaryFoo", "type": { - "$id": "544", + "$id": "555", "kind": "dict", "keyType": { - "$id": "545", + "$id": "556", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$ref": "490" + "$ref": "501" }, "decorators": [] }, @@ -7519,7 +7647,7 @@ "isExactName": false }, { - "$id": "546", + "$id": "557", "kind": "property", "name": "dictionaryOfDictionaryFoo", "apiVersions": [ @@ -7528,17 +7656,17 @@ ], "serializedName": "dictionaryOfDictionaryFoo", "type": { - "$id": "547", + "$id": "558", "kind": "dict", "keyType": { - "$id": "548", + "$id": "559", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$ref": "544" + "$ref": "555" }, "decorators": [] }, @@ -7559,7 +7687,7 @@ "isExactName": false }, { - "$id": "549", + "$id": "560", "kind": "property", "name": "dictionaryListFoo", "apiVersions": [ @@ -7568,17 +7696,17 @@ ], "serializedName": "dictionaryListFoo", "type": { - "$id": "550", + "$id": "561", "kind": "dict", "keyType": { - "$id": "551", + "$id": "562", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$ref": "489" + "$ref": "500" }, "decorators": [] }, @@ -7599,7 +7727,7 @@ "isExactName": false }, { - "$id": "552", + "$id": "563", "kind": "property", "name": "listOfDictionaryFoo", "apiVersions": [ @@ -7608,11 +7736,11 @@ ], "serializedName": "listOfDictionaryFoo", "type": { - "$id": "553", + "$id": "564", "kind": "array", "name": "ArrayRecord1", "valueType": { - "$ref": "544" + "$ref": "555" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -7637,16 +7765,16 @@ ] }, { - "$ref": "490" + "$ref": "501" }, { - "$ref": "500" + "$ref": "511" }, { - "$ref": "537" + "$ref": "548" }, { - "$id": "554", + "$id": "565", "kind": "model", "name": "Cat", "apiVersions": [ @@ -7661,7 +7789,7 @@ "isExactName": false, "properties": [ { - "$id": "555", + "$id": "566", "kind": "property", "name": "id", "apiVersions": [ @@ -7670,7 +7798,7 @@ ], "serializedName": "id", "type": { - "$id": "556", + "$id": "567", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -7697,7 +7825,7 @@ "isExactName": false }, { - "$id": "557", + "$id": "568", "kind": "property", "name": "boolPart", "apiVersions": [ @@ -7706,7 +7834,7 @@ ], "serializedName": "boolPart", "type": { - "$id": "558", + "$id": "569", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -7733,7 +7861,7 @@ "isExactName": false }, { - "$id": "559", + "$id": "570", "kind": "property", "name": "int32Part", "apiVersions": [ @@ -7742,7 +7870,7 @@ ], "serializedName": "int32Part", "type": { - "$id": "560", + "$id": "571", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -7769,7 +7897,7 @@ "isExactName": false }, { - "$id": "561", + "$id": "572", "kind": "property", "name": "int64Part", "apiVersions": [ @@ -7778,7 +7906,7 @@ ], "serializedName": "int64Part", "type": { - "$id": "562", + "$id": "573", "kind": "int64", "name": "int64", "crossLanguageDefinitionId": "TypeSpec.int64", @@ -7805,7 +7933,7 @@ "isExactName": false }, { - "$id": "563", + "$id": "574", "kind": "property", "name": "float32Part", "apiVersions": [ @@ -7814,7 +7942,7 @@ ], "serializedName": "float32Part", "type": { - "$id": "564", + "$id": "575", "kind": "float32", "name": "float32", "crossLanguageDefinitionId": "TypeSpec.float32", @@ -7841,7 +7969,7 @@ "isExactName": false }, { - "$id": "565", + "$id": "576", "kind": "property", "name": "float64Part", "apiVersions": [ @@ -7850,7 +7978,7 @@ ], "serializedName": "float64Part", "type": { - "$id": "566", + "$id": "577", "kind": "float64", "name": "float64", "crossLanguageDefinitionId": "TypeSpec.float64", @@ -7877,7 +8005,7 @@ "isExactName": false }, { - "$id": "567", + "$id": "578", "kind": "property", "name": "decimalPart", "apiVersions": [ @@ -7886,7 +8014,7 @@ ], "serializedName": "decimalPart", "type": { - "$id": "568", + "$id": "579", "kind": "decimal128", "name": "decimal128", "crossLanguageDefinitionId": "TypeSpec.decimal128", @@ -7913,7 +8041,7 @@ "isExactName": false }, { - "$id": "569", + "$id": "580", "kind": "property", "name": "int8Part", "apiVersions": [ @@ -7922,7 +8050,7 @@ ], "serializedName": "int8Part", "type": { - "$id": "570", + "$id": "581", "kind": "int8", "name": "int8", "crossLanguageDefinitionId": "TypeSpec.int8", @@ -7949,7 +8077,7 @@ "isExactName": false }, { - "$id": "571", + "$id": "582", "kind": "property", "name": "uint8Part", "apiVersions": [ @@ -7958,7 +8086,7 @@ ], "serializedName": "uint8Part", "type": { - "$id": "572", + "$id": "583", "kind": "uint8", "name": "uint8", "crossLanguageDefinitionId": "TypeSpec.uint8", @@ -7985,7 +8113,7 @@ "isExactName": false }, { - "$id": "573", + "$id": "584", "kind": "property", "name": "dictionaryPart", "apiVersions": [ @@ -7994,7 +8122,7 @@ ], "serializedName": "dictionaryPart", "type": { - "$ref": "507" + "$ref": "518" }, "optional": false, "readOnly": false, @@ -8017,7 +8145,7 @@ "isExactName": false }, { - "$id": "574", + "$id": "585", "kind": "property", "name": "dictionaryModelPart", "apiVersions": [ @@ -8026,17 +8154,17 @@ ], "serializedName": "dictionaryModelPart", "type": { - "$id": "575", + "$id": "586", "kind": "dict", "keyType": { - "$id": "576", + "$id": "587", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$ref": "294" + "$ref": "305" }, "decorators": [] }, @@ -8061,7 +8189,7 @@ "isExactName": false }, { - "$id": "577", + "$id": "588", "kind": "property", "name": "listPart", "apiVersions": [ @@ -8070,7 +8198,7 @@ ], "serializedName": "listPart", "type": { - "$ref": "300" + "$ref": "311" }, "optional": false, "readOnly": false, @@ -8093,7 +8221,7 @@ "isExactName": false }, { - "$id": "578", + "$id": "589", "kind": "property", "name": "listModelPart", "apiVersions": [ @@ -8102,7 +8230,7 @@ ], "serializedName": "listModelPart", "type": { - "$ref": "394" + "$ref": "405" }, "optional": false, "readOnly": false, @@ -8125,7 +8253,7 @@ "isExactName": false }, { - "$id": "579", + "$id": "590", "kind": "property", "name": "multipleListPart", "apiVersions": [ @@ -8134,11 +8262,11 @@ ], "serializedName": "multipleListPart", "type": { - "$id": "580", + "$id": "591", "kind": "array", "name": "ArrayHttpPart", "valueType": { - "$id": "581", + "$id": "592", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -8168,7 +8296,7 @@ "isExactName": false }, { - "$id": "582", + "$id": "593", "kind": "property", "name": "profileImage", "apiVersions": [ @@ -8177,7 +8305,7 @@ ], "serializedName": "profileImage", "type": { - "$id": "583", + "$id": "594", "kind": "model", "name": "File", "apiVersions": [], @@ -8192,14 +8320,14 @@ "isFileType": true, "properties": [ { - "$id": "584", + "$id": "595", "kind": "property", "name": "contentType", "apiVersions": [], "summary": "The allowed media (MIME) types of the file contents.", "doc": "The allowed media (MIME) types of the file contents.\n\nIn file bodies, this value comes from the `Content-Type` header of the request or response. In JSON bodies,\nthis value is serialized as a field in the response.\n\nNOTE: this is not _necessarily_ the same as the `Content-Type` header of the request or response, but\nit will be for file bodies. It may be different if the file is serialized as a JSON object. It always refers to the\n_contents_ of the file, and not necessarily the way the file itself is transmitted or serialized.", "type": { - "$id": "585", + "$id": "596", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -8216,14 +8344,14 @@ "isExactName": false }, { - "$id": "586", + "$id": "597", "kind": "property", "name": "filename", "apiVersions": [], "summary": "The name of the file, if any.", "doc": "The name of the file, if any.\n\nIn file bodies, this value comes from the `filename` parameter of the `Content-Disposition` header of the response\nor multipart payload. In JSON bodies, this value is serialized as a field in the response.\n\nNOTE: By default, `filename` cannot be sent in request payloads and can only be sent in responses and multipart\npayloads, as the `Content-Disposition` header is not valid in requests. If you want to send the `filename` in a request,\nyou must extend the `File` model and override the `filename` property with a different location defined by HTTP metadata\ndecorators.", "type": { - "$id": "587", + "$id": "598", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -8240,14 +8368,14 @@ "isExactName": false }, { - "$id": "588", + "$id": "599", "kind": "property", "name": "contents", "apiVersions": [], "summary": "The contents of the file.", "doc": "The contents of the file.\n\nIn file bodies, this value comes from the body of the request, response, or multipart payload. In JSON bodies,\nthis value is serialized as a field in the response.", "type": { - "$id": "589", + "$id": "600", "kind": "bytes", "name": "bytes", "encode": "base64", @@ -8277,12 +8405,12 @@ "isFilePart": true, "isMulti": false, "filename": { - "$id": "590", + "$id": "601", "doc": "The name of the file, if any.\n\nIn file bodies, this value comes from the `filename` parameter of the `Content-Disposition` header of the response\nor multipart payload. In JSON bodies, this value is serialized as a field in the response.\n\nNOTE: By default, `filename` cannot be sent in request payloads and can only be sent in responses and multipart\npayloads, as the `Content-Disposition` header is not valid in requests. If you want to send the `filename` in a request,\nyou must extend the `File` model and override the `filename` property with a different location defined by HTTP metadata\ndecorators.", "summary": "The name of the file, if any.", "apiVersions": [], "type": { - "$id": "591", + "$id": "602", "kind": "string", "decorators": [], "doc": "A sequence of textual characters.", @@ -8313,12 +8441,12 @@ "serializationOptions": {} }, "contentType": { - "$id": "592", + "$id": "603", "doc": "The allowed media (MIME) types of the file contents.\n\nIn file bodies, this value comes from the `Content-Type` header of the request or response. In JSON bodies,\nthis value is serialized as a field in the response.\n\nNOTE: this is not _necessarily_ the same as the `Content-Type` header of the request or response, but\nit will be for file bodies. It may be different if the file is serialized as a JSON object. It always refers to the\n_contents_ of the file, and not necessarily the way the file itself is transmitted or serialized.", "summary": "The allowed media (MIME) types of the file contents.", "apiVersions": [], "type": { - "$id": "593", + "$id": "604", "kind": "string", "decorators": [], "doc": "A sequence of textual characters.", @@ -8359,7 +8487,7 @@ "isExactName": false }, { - "$id": "594", + "$id": "605", "kind": "property", "name": "extensibleEnumPart", "apiVersions": [ @@ -8391,7 +8519,7 @@ "isExactName": false }, { - "$id": "595", + "$id": "606", "kind": "property", "name": "fixedEnumPart", "apiVersions": [ @@ -8423,7 +8551,7 @@ "isExactName": false }, { - "$id": "596", + "$id": "607", "kind": "property", "name": "intExtensibleEnumPart", "apiVersions": [ @@ -8455,7 +8583,7 @@ "isExactName": false }, { - "$id": "597", + "$id": "608", "kind": "property", "name": "intFixedEnumPart", "apiVersions": [ @@ -8489,7 +8617,7 @@ ] }, { - "$id": "598", + "$id": "609", "kind": "model", "name": "File", "apiVersions": [], @@ -8504,18 +8632,18 @@ "isFileType": true, "properties": [ { - "$ref": "584" + "$ref": "595" }, { - "$ref": "586" + "$ref": "597" }, { - "$ref": "588" + "$ref": "599" } ] }, { - "$id": "599", + "$id": "610", "kind": "model", "name": "StreamingItem", "apiVersions": [ @@ -8534,7 +8662,7 @@ "isExactName": false, "properties": [ { - "$id": "600", + "$id": "611", "kind": "property", "name": "message", "apiVersions": [ @@ -8543,7 +8671,7 @@ ], "serializedName": "message", "type": { - "$id": "601", + "$id": "612", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -8566,7 +8694,7 @@ ] }, { - "$id": "602", + "$id": "613", "kind": "model", "name": "PreviewDetails", "apiVersions": [ @@ -8585,7 +8713,7 @@ "isExactName": false, "properties": [ { - "$id": "603", + "$id": "614", "kind": "property", "name": "choice", "apiVersions": [ @@ -8619,7 +8747,7 @@ } }, { - "$id": "604", + "$id": "615", "kind": "model", "name": "LifecycleModel", "apiVersions": [ @@ -8638,7 +8766,7 @@ "isExactName": false, "properties": [ { - "$id": "605", + "$id": "616", "kind": "property", "name": "preview", "apiVersions": [ @@ -8647,7 +8775,7 @@ ], "serializedName": "preview", "type": { - "$ref": "602" + "$ref": "613" }, "optional": true, "readOnly": false, @@ -8670,7 +8798,7 @@ } }, { - "$id": "606", + "$id": "617", "kind": "property", "name": "choice", "apiVersions": [ @@ -8698,7 +8826,7 @@ ] }, { - "$id": "607", + "$id": "618", "kind": "model", "name": "PagePreviewDetails", "apiVersions": [ @@ -8717,7 +8845,7 @@ "isExactName": false, "properties": [ { - "$id": "608", + "$id": "619", "kind": "property", "name": "items", "apiVersions": [ @@ -8726,11 +8854,11 @@ ], "serializedName": "items", "type": { - "$id": "609", + "$id": "620", "kind": "array", "name": "ArrayPreviewDetails", "valueType": { - "$ref": "602" + "$ref": "613" }, "crossLanguageDefinitionId": "TypeSpec.Array", "decorators": [] @@ -8752,7 +8880,7 @@ ] }, { - "$id": "610", + "$id": "621", "kind": "model", "name": "Animal", "apiVersions": [ @@ -8771,7 +8899,7 @@ }, "isExactName": false, "discriminatorProperty": { - "$id": "611", + "$id": "622", "kind": "property", "name": "kind", "apiVersions": [ @@ -8781,7 +8909,7 @@ "serializedName": "kind", "doc": "The kind of animal", "type": { - "$id": "612", + "$id": "623", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -8803,10 +8931,10 @@ }, "properties": [ { - "$ref": "611" + "$ref": "622" }, { - "$id": "613", + "$id": "624", "kind": "property", "name": "name", "apiVersions": [ @@ -8816,7 +8944,7 @@ "serializedName": "name", "doc": "Name of the animal", "type": { - "$id": "614", + "$id": "625", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -8839,7 +8967,7 @@ ], "discriminatedSubtypes": { "pet": { - "$id": "615", + "$id": "626", "kind": "model", "name": "Pet", "apiVersions": [ @@ -8859,7 +8987,7 @@ }, "isExactName": false, "discriminatorProperty": { - "$id": "616", + "$id": "627", "kind": "property", "name": "kind", "apiVersions": [ @@ -8868,7 +8996,7 @@ ], "serializedName": "kind", "type": { - "$ref": "110" + "$ref": "117" }, "optional": false, "readOnly": false, @@ -8885,14 +9013,14 @@ "isExactName": false }, "baseModel": { - "$ref": "610" + "$ref": "621" }, "properties": [ { - "$ref": "616" + "$ref": "627" }, { - "$id": "617", + "$id": "628", "kind": "property", "name": "trained", "apiVersions": [ @@ -8902,7 +9030,7 @@ "serializedName": "trained", "doc": "Whether the pet is trained", "type": { - "$id": "618", + "$id": "629", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -8925,7 +9053,7 @@ ], "discriminatedSubtypes": { "dog": { - "$id": "619", + "$id": "630", "kind": "model", "name": "Dog", "apiVersions": [ @@ -8945,11 +9073,11 @@ }, "isExactName": false, "baseModel": { - "$ref": "615" + "$ref": "626" }, "properties": [ { - "$id": "620", + "$id": "631", "kind": "property", "name": "kind", "apiVersions": [ @@ -8958,7 +9086,7 @@ ], "serializedName": "kind", "type": { - "$ref": "112" + "$ref": "119" }, "optional": false, "readOnly": false, @@ -8975,7 +9103,7 @@ "isExactName": false }, { - "$id": "621", + "$id": "632", "kind": "property", "name": "breed", "apiVersions": [ @@ -8985,7 +9113,7 @@ "serializedName": "breed", "doc": "The breed of the dog", "type": { - "$id": "622", + "$id": "633", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -9010,18 +9138,18 @@ } }, "dog": { - "$ref": "619" + "$ref": "630" } } }, { - "$ref": "615" + "$ref": "626" }, { - "$ref": "619" + "$ref": "630" }, { - "$id": "623", + "$id": "634", "kind": "model", "name": "Tree", "apiVersions": [ @@ -9046,7 +9174,7 @@ }, "isExactName": false, "baseModel": { - "$id": "624", + "$id": "635", "kind": "model", "name": "Plant", "apiVersions": [ @@ -9070,7 +9198,7 @@ }, "isExactName": false, "discriminatorProperty": { - "$id": "625", + "$id": "636", "kind": "property", "name": "species", "apiVersions": [ @@ -9080,7 +9208,7 @@ "serializedName": "species", "doc": "The species of plant", "type": { - "$id": "626", + "$id": "637", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -9107,10 +9235,10 @@ }, "properties": [ { - "$ref": "625" + "$ref": "636" }, { - "$id": "627", + "$id": "638", "kind": "property", "name": "id", "apiVersions": [ @@ -9120,7 +9248,7 @@ "serializedName": "id", "doc": "The unique identifier of the plant", "type": { - "$id": "628", + "$id": "639", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -9146,7 +9274,7 @@ "isExactName": false }, { - "$id": "629", + "$id": "640", "kind": "property", "name": "height", "apiVersions": [ @@ -9156,7 +9284,7 @@ "serializedName": "height", "doc": "The height of the plant in centimeters", "type": { - "$id": "630", + "$id": "641", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -9184,13 +9312,13 @@ ], "discriminatedSubtypes": { "tree": { - "$ref": "623" + "$ref": "634" } } }, "properties": [ { - "$id": "631", + "$id": "642", "kind": "property", "name": "species", "apiVersions": [ @@ -9199,7 +9327,7 @@ ], "serializedName": "species", "type": { - "$ref": "114" + "$ref": "121" }, "optional": false, "readOnly": false, @@ -9221,7 +9349,7 @@ "isExactName": false }, { - "$id": "632", + "$id": "643", "kind": "property", "name": "age", "apiVersions": [ @@ -9231,7 +9359,7 @@ "serializedName": "age", "doc": "The age of the tree in years", "type": { - "$id": "633", + "$id": "644", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -9257,7 +9385,7 @@ "isExactName": false }, { - "$id": "634", + "$id": "645", "kind": "property", "name": "nullableText", "apiVersions": [ @@ -9266,10 +9394,10 @@ ], "serializedName": "nullableText", "type": { - "$id": "635", + "$id": "646", "kind": "nullable", "type": { - "$id": "636", + "$id": "647", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -9297,7 +9425,7 @@ "isExactName": false }, { - "$id": "637", + "$id": "648", "kind": "property", "name": "nullableLabels", "apiVersions": [ @@ -9306,10 +9434,10 @@ ], "serializedName": "nullableLabels", "type": { - "$id": "638", + "$id": "649", "kind": "nullable", "type": { - "$ref": "507" + "$ref": "518" }, "namespace": "SampleTypeSpec" }, @@ -9335,10 +9463,10 @@ ] }, { - "$ref": "624" + "$ref": "635" }, { - "$id": "639", + "$id": "650", "kind": "model", "name": "GetWidgetMetricsResponse", "apiVersions": [ @@ -9357,7 +9485,7 @@ "isExactName": false, "properties": [ { - "$id": "640", + "$id": "651", "kind": "property", "name": "numSold", "apiVersions": [ @@ -9366,7 +9494,7 @@ ], "serializedName": "numSold", "type": { - "$id": "641", + "$id": "652", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -9387,7 +9515,7 @@ "isExactName": false }, { - "$id": "642", + "$id": "653", "kind": "property", "name": "averagePrice", "apiVersions": [ @@ -9396,7 +9524,7 @@ ], "serializedName": "averagePrice", "type": { - "$id": "643", + "$id": "654", "kind": "float32", "name": "float32", "crossLanguageDefinitionId": "TypeSpec.float32", @@ -9419,7 +9547,7 @@ ] }, { - "$id": "644", + "$id": "655", "kind": "model", "name": "GetNotebookResponse", "apiVersions": [ @@ -9438,7 +9566,7 @@ "isExactName": false, "properties": [ { - "$id": "645", + "$id": "656", "kind": "property", "name": "name", "apiVersions": [ @@ -9447,7 +9575,7 @@ ], "serializedName": "name", "type": { - "$id": "646", + "$id": "657", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -9468,7 +9596,7 @@ "isExactName": false }, { - "$id": "647", + "$id": "658", "kind": "property", "name": "content", "apiVersions": [ @@ -9477,7 +9605,7 @@ ], "serializedName": "content", "type": { - "$id": "648", + "$id": "659", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -9500,7 +9628,138 @@ ] }, { - "$id": "649", + "$id": "660", + "kind": "model", + "name": "LegacyDetails", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "namespace": "SampleTypeSpec", + "crossLanguageDefinitionId": "SampleTypeSpec.LegacyDetails", + "usage": "Output,Json", + "deprecation": "Use \"CurrentDetails\" instead.\nSee C:\\sdk.", + "decorators": [], + "serializationOptions": { + "json": { + "name": "LegacyDetails" + } + }, + "isExactName": false, + "properties": [ + { + "$id": "661", + "kind": "property", + "name": "choice", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "serializedName": "choice", + "type": { + "$ref": "87" + }, + "optional": false, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.LegacyDetails.choice", + "serializationOptions": { + "json": { + "name": "choice" + } + }, + "isHttpMetadata": false, + "isExactName": false + }, + { + "$id": "662", + "kind": "property", + "name": "extensibleChoice", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "serializedName": "extensibleChoice", + "type": { + "$ref": "91" + }, + "optional": false, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.LegacyDetails.extensibleChoice", + "serializationOptions": { + "json": { + "name": "extensibleChoice" + } + }, + "isHttpMetadata": false, + "isExactName": false + } + ] + }, + { + "$id": "663", + "kind": "model", + "name": "CurrentDetails", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "namespace": "SampleTypeSpec", + "crossLanguageDefinitionId": "SampleTypeSpec.CurrentDetails", + "usage": "Output,Json", + "decorators": [], + "serializationOptions": { + "json": { + "name": "CurrentDetails" + } + }, + "isExactName": false, + "baseModel": { + "$ref": "660" + }, + "properties": [ + { + "$id": "664", + "kind": "property", + "name": "previous", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "serializedName": "previous", + "type": { + "$id": "665", + "kind": "array", + "name": "ArrayLegacyDetails", + "valueType": { + "$ref": "660" + }, + "crossLanguageDefinitionId": "TypeSpec.Array", + "decorators": [] + }, + "optional": true, + "readOnly": false, + "discriminator": false, + "flatten": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.CurrentDetails.previous", + "serializationOptions": { + "json": { + "name": "previous" + } + }, + "isHttpMetadata": false, + "isExactName": false + } + ] + }, + { + "$id": "666", "kind": "model", "name": "NullableDynamicModel", "apiVersions": [ @@ -9525,7 +9784,7 @@ "isExactName": false, "properties": [ { - "$id": "650", + "$id": "667", "kind": "property", "name": "modelValue", "apiVersions": [ @@ -9534,10 +9793,10 @@ ], "serializedName": "modelValue", "type": { - "$id": "651", + "$id": "668", "kind": "nullable", "type": { - "$ref": "440" + "$ref": "451" }, "namespace": "SampleTypeSpec" }, @@ -9556,7 +9815,7 @@ "isExactName": false }, { - "$id": "652", + "$id": "669", "kind": "property", "name": "children", "apiVersions": [ @@ -9565,17 +9824,17 @@ ], "serializedName": "children", "type": { - "$id": "653", + "$id": "670", "kind": "nullable", "type": { - "$id": "654", + "$id": "671", "kind": "array", "name": "Array2", "valueType": { - "$id": "655", + "$id": "672", "kind": "nullable", "type": { - "$ref": "440" + "$ref": "451" }, "namespace": "SampleTypeSpec" }, @@ -9599,7 +9858,7 @@ "isExactName": false }, { - "$id": "656", + "$id": "673", "kind": "property", "name": "childDictionary", "apiVersions": [ @@ -9608,23 +9867,23 @@ ], "serializedName": "childDictionary", "type": { - "$id": "657", + "$id": "674", "kind": "nullable", "type": { - "$id": "658", + "$id": "675", "kind": "dict", "keyType": { - "$id": "659", + "$id": "676", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "660", + "$id": "677", "kind": "nullable", "type": { - "$ref": "440" + "$ref": "451" }, "namespace": "SampleTypeSpec" }, @@ -9647,7 +9906,7 @@ "isExactName": false }, { - "$id": "661", + "$id": "678", "kind": "property", "name": "nestedChildren", "apiVersions": [ @@ -9656,24 +9915,24 @@ ], "serializedName": "nestedChildren", "type": { - "$id": "662", + "$id": "679", "kind": "nullable", "type": { - "$id": "663", + "$id": "680", "kind": "array", "name": "Array3", "valueType": { - "$id": "664", + "$id": "681", "kind": "nullable", "type": { - "$id": "665", + "$id": "682", "kind": "array", "name": "Array4", "valueType": { - "$id": "666", + "$id": "683", "kind": "nullable", "type": { - "$ref": "440" + "$ref": "451" }, "namespace": "SampleTypeSpec" }, @@ -9702,7 +9961,7 @@ "isExactName": false }, { - "$id": "667", + "$id": "684", "kind": "property", "name": "nestedChildDictionary", "apiVersions": [ @@ -9711,36 +9970,36 @@ ], "serializedName": "nestedChildDictionary", "type": { - "$id": "668", + "$id": "685", "kind": "nullable", "type": { - "$id": "669", + "$id": "686", "kind": "dict", "keyType": { - "$id": "670", + "$id": "687", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "671", + "$id": "688", "kind": "nullable", "type": { - "$id": "672", + "$id": "689", "kind": "dict", "keyType": { - "$id": "673", + "$id": "690", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "674", + "$id": "691", "kind": "nullable", "type": { - "$ref": "440" + "$ref": "451" }, "namespace": "SampleTypeSpec" }, @@ -9767,7 +10026,7 @@ "isExactName": false }, { - "$id": "675", + "$id": "692", "kind": "property", "name": "dictionaryChildren", "apiVersions": [ @@ -9776,30 +10035,30 @@ ], "serializedName": "dictionaryChildren", "type": { - "$id": "676", + "$id": "693", "kind": "nullable", "type": { - "$id": "677", + "$id": "694", "kind": "dict", "keyType": { - "$id": "678", + "$id": "695", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "679", + "$id": "696", "kind": "nullable", "type": { - "$id": "680", + "$id": "697", "kind": "array", "name": "Array5", "valueType": { - "$id": "681", + "$id": "698", "kind": "nullable", "type": { - "$ref": "440" + "$ref": "451" }, "namespace": "SampleTypeSpec" }, @@ -9827,7 +10086,7 @@ "isExactName": false }, { - "$id": "682", + "$id": "699", "kind": "property", "name": "listOfDictionaries", "apiVersions": [ @@ -9836,30 +10095,30 @@ ], "serializedName": "listOfDictionaries", "type": { - "$id": "683", + "$id": "700", "kind": "nullable", "type": { - "$id": "684", + "$id": "701", "kind": "array", "name": "Array6", "valueType": { - "$id": "685", + "$id": "702", "kind": "nullable", "type": { - "$id": "686", + "$id": "703", "kind": "dict", "keyType": { - "$id": "687", + "$id": "704", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "688", + "$id": "705", "kind": "nullable", "type": { - "$ref": "440" + "$ref": "451" }, "namespace": "SampleTypeSpec" }, @@ -9889,7 +10148,7 @@ ] }, { - "$id": "689", + "$id": "706", "kind": "model", "name": "OptionalNullableDynamicProperties", "apiVersions": [ @@ -9913,7 +10172,7 @@ }, "isExactName": false, "baseModel": { - "$id": "690", + "$id": "707", "kind": "model", "name": "OptionalNullableBase", "apiVersions": [ @@ -9933,7 +10192,7 @@ "isExactName": false, "properties": [ { - "$id": "691", + "$id": "708", "kind": "property", "name": "inheritedNullable", "apiVersions": [ @@ -9942,10 +10201,10 @@ ], "serializedName": "inheritedNullable", "type": { - "$id": "692", + "$id": "709", "kind": "nullable", "type": { - "$id": "693", + "$id": "710", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -9972,10 +10231,10 @@ "properties": [] }, { - "$ref": "690" + "$ref": "707" }, { - "$id": "694", + "$id": "711", "kind": "model", "name": "OptionalNullableChild", "apiVersions": [ @@ -9995,7 +10254,7 @@ "isExactName": false, "properties": [ { - "$id": "695", + "$id": "712", "kind": "property", "name": "value", "apiVersions": [ @@ -10004,7 +10263,7 @@ ], "serializedName": "value", "type": { - "$id": "696", + "$id": "713", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10027,7 +10286,7 @@ ] }, { - "$id": "697", + "$id": "714", "kind": "model", "name": "OptionalNullableProperties", "apiVersions": [ @@ -10046,11 +10305,11 @@ }, "isExactName": false, "baseModel": { - "$ref": "690" + "$ref": "707" }, "properties": [ { - "$id": "698", + "$id": "715", "kind": "property", "name": "nullableModel", "apiVersions": [ @@ -10059,10 +10318,10 @@ ], "serializedName": "nullableModel", "type": { - "$id": "699", + "$id": "716", "kind": "nullable", "type": { - "$ref": "694" + "$ref": "711" }, "namespace": "SampleTypeSpec" }, @@ -10081,7 +10340,7 @@ "isExactName": false }, { - "$id": "700", + "$id": "717", "kind": "property", "name": "nullableString", "apiVersions": [ @@ -10090,10 +10349,10 @@ ], "serializedName": "nullableString", "type": { - "$id": "701", + "$id": "718", "kind": "nullable", "type": { - "$id": "702", + "$id": "719", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10116,7 +10375,7 @@ "isExactName": false }, { - "$id": "703", + "$id": "720", "kind": "property", "name": "nullableInt", "apiVersions": [ @@ -10125,10 +10384,10 @@ ], "serializedName": "nullableInt", "type": { - "$id": "704", + "$id": "721", "kind": "nullable", "type": { - "$id": "705", + "$id": "722", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -10151,7 +10410,7 @@ "isExactName": false }, { - "$id": "706", + "$id": "723", "kind": "property", "name": "nullableBoolean", "apiVersions": [ @@ -10160,10 +10419,10 @@ ], "serializedName": "nullableBoolean", "type": { - "$id": "707", + "$id": "724", "kind": "nullable", "type": { - "$id": "708", + "$id": "725", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -10186,7 +10445,7 @@ "isExactName": false }, { - "$id": "709", + "$id": "726", "kind": "property", "name": "nullableEnum", "apiVersions": [ @@ -10195,7 +10454,7 @@ ], "serializedName": "nullableEnum", "type": { - "$id": "710", + "$id": "727", "kind": "nullable", "type": { "$ref": "17" @@ -10217,7 +10476,7 @@ "isExactName": false }, { - "$id": "711", + "$id": "728", "kind": "property", "name": "nullableDateTime", "apiVersions": [ @@ -10226,15 +10485,15 @@ ], "serializedName": "nullableDateTime", "type": { - "$id": "712", + "$id": "729", "kind": "nullable", "type": { - "$id": "713", + "$id": "730", "kind": "utcDateTime", "name": "utcDateTime", "encode": "rfc3339", "wireType": { - "$id": "714", + "$id": "731", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10260,7 +10519,7 @@ "isExactName": false }, { - "$id": "715", + "$id": "732", "kind": "property", "name": "nullableBytes", "apiVersions": [ @@ -10269,10 +10528,10 @@ ], "serializedName": "nullableBytes", "type": { - "$id": "716", + "$id": "733", "kind": "nullable", "type": { - "$id": "717", + "$id": "734", "kind": "bytes", "name": "bytes", "encode": "base64", @@ -10296,7 +10555,7 @@ "isExactName": false }, { - "$id": "718", + "$id": "735", "kind": "property", "name": "nullableList", "apiVersions": [ @@ -10305,17 +10564,17 @@ ], "serializedName": "nullableList", "type": { - "$id": "719", + "$id": "736", "kind": "nullable", "type": { - "$id": "720", + "$id": "737", "kind": "array", "name": "Array7", "valueType": { - "$id": "721", + "$id": "738", "kind": "nullable", "type": { - "$id": "722", + "$id": "739", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10343,7 +10602,7 @@ "isExactName": false }, { - "$id": "723", + "$id": "740", "kind": "property", "name": "nullableDictionary", "apiVersions": [ @@ -10352,23 +10611,23 @@ ], "serializedName": "nullableDictionary", "type": { - "$id": "724", + "$id": "741", "kind": "nullable", "type": { - "$id": "725", + "$id": "742", "kind": "dict", "keyType": { - "$id": "726", + "$id": "743", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, "valueType": { - "$id": "727", + "$id": "744", "kind": "nullable", "type": { - "$id": "728", + "$id": "745", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -10395,7 +10654,7 @@ "isExactName": false }, { - "$id": "729", + "$id": "746", "kind": "property", "name": "readOnlyNullable", "apiVersions": [ @@ -10404,10 +10663,10 @@ ], "serializedName": "readOnlyNullable", "type": { - "$id": "730", + "$id": "747", "kind": "nullable", "type": { - "$id": "731", + "$id": "748", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10430,7 +10689,7 @@ "isExactName": false }, { - "$id": "732", + "$id": "749", "kind": "property", "name": "requiredNullable", "apiVersions": [ @@ -10439,10 +10698,10 @@ ], "serializedName": "requiredNullable", "type": { - "$id": "733", + "$id": "750", "kind": "nullable", "type": { - "$id": "734", + "$id": "751", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10465,7 +10724,7 @@ "isExactName": false }, { - "$id": "735", + "$id": "752", "kind": "property", "name": "optionalNonNullable", "apiVersions": [ @@ -10474,7 +10733,7 @@ ], "serializedName": "optionalNonNullable", "type": { - "$id": "736", + "$id": "753", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10495,7 +10754,7 @@ "isExactName": false }, { - "$id": "737", + "$id": "754", "kind": "property", "name": "optionalNonNullableInt", "apiVersions": [ @@ -10504,7 +10763,7 @@ ], "serializedName": "optionalNonNullableInt", "type": { - "$id": "738", + "$id": "755", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -10527,7 +10786,7 @@ ] }, { - "$id": "739", + "$id": "756", "kind": "model", "name": "OptionalNullableContainer", "apiVersions": [ @@ -10547,7 +10806,7 @@ "isExactName": false, "properties": [ { - "$id": "740", + "$id": "757", "kind": "property", "name": "child", "apiVersions": [ @@ -10556,7 +10815,7 @@ ], "serializedName": "child", "type": { - "$ref": "697" + "$ref": "714" }, "optional": false, "readOnly": false, @@ -10575,7 +10834,7 @@ ] }, { - "$id": "741", + "$id": "758", "kind": "model", "name": "OptionalNullableFieldNames", "apiVersions": [ @@ -10594,10 +10853,10 @@ }, "isExactName": false, "additionalProperties": { - "$id": "742", + "$id": "759", "kind": "nullable", "type": { - "$id": "743", + "$id": "760", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10607,7 +10866,7 @@ }, "properties": [ { - "$id": "744", + "$id": "761", "kind": "property", "name": "additionalStringProperties", "apiVersions": [ @@ -10616,10 +10875,10 @@ ], "serializedName": "additionalStringProperties", "type": { - "$id": "745", + "$id": "762", "kind": "nullable", "type": { - "$id": "746", + "$id": "763", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10642,7 +10901,7 @@ "isExactName": false }, { - "$id": "747", + "$id": "764", "kind": "property", "name": "additionalStringPropertiesIsDefined", "apiVersions": [ @@ -10651,10 +10910,10 @@ ], "serializedName": "additionalStringPropertiesIsDefined", "type": { - "$id": "748", + "$id": "765", "kind": "nullable", "type": { - "$id": "749", + "$id": "766", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10679,7 +10938,7 @@ ] }, { - "$id": "750", + "$id": "767", "kind": "model", "name": "UnionAdditionalProperties", "apiVersions": [ @@ -10698,29 +10957,29 @@ }, "isExactName": false, "additionalProperties": { - "$id": "751", + "$id": "768", "kind": "nullable", "type": { - "$id": "752", + "$id": "769", "kind": "union", "name": "UnionAdditionalPropertiesAdditionalProperty", "variantTypes": [ { - "$id": "753", + "$id": "770", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", "decorators": [] }, { - "$id": "754", + "$id": "771", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", "decorators": [] }, { - "$id": "755", + "$id": "772", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -10736,7 +10995,7 @@ "properties": [] }, { - "$id": "756", + "$id": "773", "kind": "model", "name": "JsonlStreamStreamingItem", "apiVersions": [], @@ -10749,7 +11008,7 @@ "isExactName": false, "properties": [ { - "$id": "757", + "$id": "774", "kind": "property", "name": "contentType", "apiVersions": [ @@ -10757,7 +11016,7 @@ "2024-08-16-preview" ], "type": { - "$ref": "226" + "$ref": "233" }, "optional": false, "readOnly": false, @@ -10770,7 +11029,7 @@ "isExactName": false }, { - "$id": "758", + "$id": "775", "kind": "property", "name": "body", "apiVersions": [ @@ -10778,7 +11037,7 @@ "2024-08-16-preview" ], "type": { - "$id": "759", + "$id": "776", "kind": "bytes", "name": "bytes", "crossLanguageDefinitionId": "", @@ -10799,7 +11058,7 @@ ], "clients": [ { - "$id": "760", + "$id": "777", "kind": "client", "name": "SampleTypeSpecClient", "isExactName": false, @@ -10807,7 +11066,7 @@ "doc": "This is a sample typespec project.", "methods": [ { - "$id": "761", + "$id": "778", "kind": "basic", "name": "sayHi", "isExactName": false, @@ -10818,19 +11077,19 @@ ], "doc": "Return hi", "operation": { - "$id": "762", + "$id": "779", "name": "sayHi", "isExactName": false, "doc": "Return hi", "accessibility": "public", "parameters": [ { - "$id": "763", + "$id": "780", "kind": "header", "name": "headParameter", "serializedName": "head-parameter", "type": { - "$id": "764", + "$id": "781", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10845,12 +11104,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.sayHi.headParameter", "methodParameterSegments": [ { - "$id": "765", + "$id": "782", "kind": "method", "name": "headParameter", "serializedName": "head-parameter", "type": { - "$id": "766", + "$id": "783", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10870,12 +11129,12 @@ "isExactName": false }, { - "$id": "767", + "$id": "784", "kind": "query", "name": "queryParameter", "serializedName": "queryParameter", "type": { - "$id": "768", + "$id": "785", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10890,12 +11149,12 @@ "readOnly": false, "methodParameterSegments": [ { - "$id": "769", + "$id": "786", "kind": "method", "name": "queryParameter", "serializedName": "queryParameter", "type": { - "$id": "770", + "$id": "787", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10915,12 +11174,12 @@ "isExactName": false }, { - "$id": "771", + "$id": "788", "kind": "query", "name": "optionalQuery", "serializedName": "optionalQuery", "type": { - "$id": "772", + "$id": "789", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10935,12 +11194,12 @@ "readOnly": false, "methodParameterSegments": [ { - "$id": "773", + "$id": "790", "kind": "method", "name": "optionalQuery", "serializedName": "optionalQuery", "type": { - "$id": "774", + "$id": "791", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -10960,12 +11219,12 @@ "isExactName": false }, { - "$id": "775", + "$id": "792", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "116" + "$ref": "123" }, "isApiVersion": false, "optional": false, @@ -10976,12 +11235,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.sayHi.accept", "methodParameterSegments": [ { - "$id": "776", + "$id": "793", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "116" + "$ref": "123" }, "location": "Header", "isApiVersion": false, @@ -11003,7 +11262,7 @@ 200 ], "bodyType": { - "$ref": "294" + "$ref": "305" }, "headers": [], "isErrorResponse": false, @@ -11029,21 +11288,21 @@ }, "parameters": [ { - "$ref": "765" + "$ref": "782" }, { - "$ref": "769" + "$ref": "786" }, { - "$ref": "773" + "$ref": "790" }, { - "$ref": "776" + "$ref": "793" } ], "response": { "type": { - "$ref": "294" + "$ref": "305" } }, "isOverride": false, @@ -11052,7 +11311,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.sayHi" }, { - "$id": "777", + "$id": "794", "kind": "basic", "name": "helloAgain", "isExactName": false, @@ -11063,19 +11322,19 @@ ], "doc": "Return hi again", "operation": { - "$id": "778", + "$id": "795", "name": "helloAgain", "isExactName": false, "doc": "Return hi again", "accessibility": "public", "parameters": [ { - "$id": "779", + "$id": "796", "kind": "header", "name": "p1", "serializedName": "p1", "type": { - "$id": "780", + "$id": "797", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -11090,12 +11349,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain.p1", "methodParameterSegments": [ { - "$id": "781", + "$id": "798", "kind": "method", "name": "p1", "serializedName": "p1", "type": { - "$id": "782", + "$id": "799", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -11115,12 +11374,12 @@ "isExactName": false }, { - "$id": "783", + "$id": "800", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "118" + "$ref": "125" }, "isApiVersion": false, "optional": false, @@ -11131,12 +11390,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain.contentType", "methodParameterSegments": [ { - "$id": "784", + "$id": "801", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "118" + "$ref": "125" }, "location": "Header", "isApiVersion": false, @@ -11152,12 +11411,12 @@ "isExactName": false }, { - "$id": "785", + "$id": "802", "kind": "path", "name": "p2", "serializedName": "p2", "type": { - "$id": "786", + "$id": "803", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -11175,12 +11434,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain.p2", "methodParameterSegments": [ { - "$id": "787", + "$id": "804", "kind": "method", "name": "p2", "serializedName": "p2", "type": { - "$id": "788", + "$id": "805", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -11200,12 +11459,12 @@ "isExactName": false }, { - "$id": "789", + "$id": "806", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "122" + "$ref": "129" }, "isApiVersion": false, "optional": false, @@ -11216,12 +11475,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain.accept", "methodParameterSegments": [ { - "$id": "790", + "$id": "807", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "122" + "$ref": "129" }, "location": "Header", "isApiVersion": false, @@ -11237,12 +11496,12 @@ "isExactName": false }, { - "$id": "791", + "$id": "808", "kind": "body", "name": "action", "serializedName": "action", "type": { - "$ref": "329" + "$ref": "340" }, "isApiVersion": false, "contentTypes": [ @@ -11256,12 +11515,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain.action", "methodParameterSegments": [ { - "$id": "792", + "$id": "809", "kind": "method", "name": "action", "serializedName": "action", "type": { - "$ref": "329" + "$ref": "340" }, "location": "Body", "isApiVersion": false, @@ -11284,7 +11543,7 @@ 200 ], "bodyType": { - "$ref": "329" + "$ref": "340" }, "headers": [], "isErrorResponse": false, @@ -11313,24 +11572,24 @@ }, "parameters": [ { - "$ref": "781" + "$ref": "798" }, { - "$ref": "792" + "$ref": "809" }, { - "$ref": "784" + "$ref": "801" }, { - "$ref": "787" + "$ref": "804" }, { - "$ref": "790" + "$ref": "807" } ], "response": { "type": { - "$ref": "329" + "$ref": "340" } }, "isOverride": false, @@ -11339,7 +11598,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloAgain" }, { - "$id": "793", + "$id": "810", "kind": "basic", "name": "noContentType", "isExactName": false, @@ -11350,19 +11609,19 @@ ], "doc": "Return hi again", "operation": { - "$id": "794", + "$id": "811", "name": "noContentType", "isExactName": false, "doc": "Return hi again", "accessibility": "public", "parameters": [ { - "$id": "795", + "$id": "812", "kind": "header", "name": "p1", "serializedName": "p1", "type": { - "$id": "796", + "$id": "813", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -11377,12 +11636,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType.p1", "methodParameterSegments": [ { - "$id": "797", + "$id": "814", "kind": "method", "name": "info", "serializedName": "info", "type": { - "$ref": "379" + "$ref": "390" }, "location": "", "isApiVersion": false, @@ -11395,13 +11654,13 @@ "isExactName": false }, { - "$id": "798", + "$id": "815", "kind": "method", "name": "p1", "serializedName": "p1", "doc": "header parameter", "type": { - "$ref": "381" + "$ref": "392" }, "location": "", "isApiVersion": false, @@ -11417,12 +11676,12 @@ "isExactName": false }, { - "$id": "799", + "$id": "816", "kind": "path", "name": "p2", "serializedName": "p2", "type": { - "$id": "800", + "$id": "817", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -11440,16 +11699,16 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType.p2", "methodParameterSegments": [ { - "$ref": "797" + "$ref": "814" }, { - "$id": "801", + "$id": "818", "kind": "method", "name": "p2", "serializedName": "p2", "doc": "path parameter", "type": { - "$ref": "384" + "$ref": "395" }, "location": "", "isApiVersion": false, @@ -11465,13 +11724,13 @@ "isExactName": false }, { - "$id": "802", + "$id": "819", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "124" + "$ref": "131" }, "isApiVersion": false, "optional": false, @@ -11482,13 +11741,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType.contentType", "methodParameterSegments": [ { - "$id": "803", + "$id": "820", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "124" + "$ref": "131" }, "location": "Header", "isApiVersion": false, @@ -11504,12 +11763,12 @@ "isExactName": false }, { - "$id": "804", + "$id": "821", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "126" + "$ref": "133" }, "isApiVersion": false, "optional": false, @@ -11520,12 +11779,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType.accept", "methodParameterSegments": [ { - "$id": "805", + "$id": "822", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "126" + "$ref": "133" }, "location": "Header", "isApiVersion": false, @@ -11541,12 +11800,12 @@ "isExactName": false }, { - "$id": "806", + "$id": "823", "kind": "body", "name": "action", "serializedName": "action", "type": { - "$ref": "329" + "$ref": "340" }, "isApiVersion": false, "contentTypes": [ @@ -11560,16 +11819,16 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType.action", "methodParameterSegments": [ { - "$ref": "797" + "$ref": "814" }, { - "$id": "807", + "$id": "824", "kind": "method", "name": "action", "serializedName": "action", "doc": "body parameter", "type": { - "$ref": "329" + "$ref": "340" }, "location": "", "isApiVersion": false, @@ -11596,7 +11855,7 @@ 200 ], "bodyType": { - "$ref": "329" + "$ref": "340" }, "headers": [], "isErrorResponse": false, @@ -11625,18 +11884,18 @@ }, "parameters": [ { - "$ref": "797" + "$ref": "814" }, { - "$ref": "803" + "$ref": "820" }, { - "$ref": "805" + "$ref": "822" } ], "response": { "type": { - "$ref": "329" + "$ref": "340" } }, "isOverride": true, @@ -11645,7 +11904,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.noContentType" }, { - "$id": "808", + "$id": "825", "kind": "basic", "name": "helloDemo2", "isExactName": false, @@ -11656,19 +11915,19 @@ ], "doc": "Return hi in demo2", "operation": { - "$id": "809", + "$id": "826", "name": "helloDemo2", "isExactName": false, "doc": "Return hi in demo2", "accessibility": "public", "parameters": [ { - "$id": "810", + "$id": "827", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "128" + "$ref": "135" }, "isApiVersion": false, "optional": false, @@ -11679,12 +11938,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloDemo2.accept", "methodParameterSegments": [ { - "$id": "811", + "$id": "828", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "128" + "$ref": "135" }, "location": "Header", "isApiVersion": false, @@ -11706,7 +11965,7 @@ 200 ], "bodyType": { - "$ref": "294" + "$ref": "305" }, "headers": [], "isErrorResponse": false, @@ -11736,12 +11995,12 @@ }, "parameters": [ { - "$ref": "811" + "$ref": "828" } ], "response": { "type": { - "$ref": "294" + "$ref": "305" } }, "isOverride": false, @@ -11750,7 +12009,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloDemo2" }, { - "$id": "812", + "$id": "829", "kind": "basic", "name": "createLiteral", "isExactName": false, @@ -11761,20 +12020,20 @@ ], "doc": "Create with literal value", "operation": { - "$id": "813", + "$id": "830", "name": "createLiteral", "isExactName": false, "doc": "Create with literal value", "accessibility": "public", "parameters": [ { - "$id": "814", + "$id": "831", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "130" + "$ref": "137" }, "isApiVersion": false, "optional": false, @@ -11785,13 +12044,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.createLiteral.contentType", "methodParameterSegments": [ { - "$id": "815", + "$id": "832", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "130" + "$ref": "137" }, "location": "Header", "isApiVersion": false, @@ -11807,12 +12066,12 @@ "isExactName": false }, { - "$id": "816", + "$id": "833", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "132" + "$ref": "139" }, "isApiVersion": false, "optional": false, @@ -11823,12 +12082,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.createLiteral.accept", "methodParameterSegments": [ { - "$id": "817", + "$id": "834", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "132" + "$ref": "139" }, "location": "Header", "isApiVersion": false, @@ -11844,12 +12103,12 @@ "isExactName": false }, { - "$id": "818", + "$id": "835", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "294" + "$ref": "305" }, "isApiVersion": false, "contentTypes": [ @@ -11863,12 +12122,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.createLiteral.body", "methodParameterSegments": [ { - "$id": "819", + "$id": "836", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "294" + "$ref": "305" }, "location": "Body", "isApiVersion": false, @@ -11895,7 +12154,7 @@ 200 ], "bodyType": { - "$ref": "294" + "$ref": "305" }, "headers": [], "isErrorResponse": false, @@ -11924,18 +12183,18 @@ }, "parameters": [ { - "$ref": "819" + "$ref": "836" }, { - "$ref": "815" + "$ref": "832" }, { - "$ref": "817" + "$ref": "834" } ], "response": { "type": { - "$ref": "294" + "$ref": "305" } }, "isOverride": false, @@ -11944,7 +12203,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.createLiteral" }, { - "$id": "820", + "$id": "837", "kind": "basic", "name": "helloLiteral", "isExactName": false, @@ -11955,19 +12214,19 @@ ], "doc": "Send literal parameters", "operation": { - "$id": "821", + "$id": "838", "name": "helloLiteral", "isExactName": false, "doc": "Send literal parameters", "accessibility": "public", "parameters": [ { - "$id": "822", + "$id": "839", "kind": "header", "name": "p1", "serializedName": "p1", "type": { - "$ref": "134" + "$ref": "141" }, "isApiVersion": false, "optional": false, @@ -11978,12 +12237,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloLiteral.p1", "methodParameterSegments": [ { - "$id": "823", + "$id": "840", "kind": "method", "name": "p1", "serializedName": "p1", "type": { - "$ref": "136" + "$ref": "143" }, "location": "Header", "isApiVersion": false, @@ -11999,12 +12258,12 @@ "isExactName": false }, { - "$id": "824", + "$id": "841", "kind": "path", "name": "p2", "serializedName": "p2", "type": { - "$ref": "138" + "$ref": "145" }, "isApiVersion": false, "explode": false, @@ -12018,12 +12277,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloLiteral.p2", "methodParameterSegments": [ { - "$id": "825", + "$id": "842", "kind": "method", "name": "p2", "serializedName": "p2", "type": { - "$ref": "140" + "$ref": "147" }, "location": "Path", "isApiVersion": false, @@ -12039,12 +12298,12 @@ "isExactName": false }, { - "$id": "826", + "$id": "843", "kind": "query", "name": "p3", "serializedName": "p3", "type": { - "$ref": "142" + "$ref": "149" }, "isApiVersion": false, "explode": false, @@ -12055,12 +12314,12 @@ "readOnly": false, "methodParameterSegments": [ { - "$id": "827", + "$id": "844", "kind": "method", "name": "p3", "serializedName": "p3", "type": { - "$ref": "144" + "$ref": "151" }, "location": "Query", "isApiVersion": false, @@ -12076,12 +12335,12 @@ "isExactName": false }, { - "$id": "828", + "$id": "845", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "146" + "$ref": "153" }, "isApiVersion": false, "optional": false, @@ -12092,12 +12351,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloLiteral.accept", "methodParameterSegments": [ { - "$id": "829", + "$id": "846", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "146" + "$ref": "153" }, "location": "Header", "isApiVersion": false, @@ -12119,7 +12378,7 @@ 200 ], "bodyType": { - "$ref": "294" + "$ref": "305" }, "headers": [], "isErrorResponse": false, @@ -12145,21 +12404,21 @@ }, "parameters": [ { - "$ref": "823" + "$ref": "840" }, { - "$ref": "825" + "$ref": "842" }, { - "$ref": "827" + "$ref": "844" }, { - "$ref": "829" + "$ref": "846" } ], "response": { "type": { - "$ref": "294" + "$ref": "305" } }, "isOverride": false, @@ -12168,7 +12427,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.helloLiteral" }, { - "$id": "830", + "$id": "847", "kind": "basic", "name": "topAction", "isExactName": false, @@ -12179,24 +12438,24 @@ ], "doc": "top level method", "operation": { - "$id": "831", + "$id": "848", "name": "topAction", "isExactName": false, "doc": "top level method", "accessibility": "public", "parameters": [ { - "$id": "832", + "$id": "849", "kind": "path", "name": "action", "serializedName": "action", "type": { - "$id": "833", + "$id": "850", "kind": "utcDateTime", "name": "utcDateTime", "encode": "rfc3339", "wireType": { - "$id": "834", + "$id": "851", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -12217,17 +12476,17 @@ "crossLanguageDefinitionId": "SampleTypeSpec.topAction.action", "methodParameterSegments": [ { - "$id": "835", + "$id": "852", "kind": "method", "name": "action", "serializedName": "action", "type": { - "$id": "836", + "$id": "853", "kind": "utcDateTime", "name": "utcDateTime", "encode": "rfc3339", "wireType": { - "$id": "837", + "$id": "854", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -12250,12 +12509,12 @@ "isExactName": false }, { - "$id": "838", + "$id": "855", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "148" + "$ref": "155" }, "isApiVersion": false, "optional": false, @@ -12266,12 +12525,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.topAction.accept", "methodParameterSegments": [ { - "$id": "839", + "$id": "856", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "148" + "$ref": "155" }, "location": "Header", "isApiVersion": false, @@ -12293,7 +12552,7 @@ 200 ], "bodyType": { - "$ref": "294" + "$ref": "305" }, "headers": [], "isErrorResponse": false, @@ -12319,15 +12578,15 @@ }, "parameters": [ { - "$ref": "835" + "$ref": "852" }, { - "$ref": "839" + "$ref": "856" } ], "response": { "type": { - "$ref": "294" + "$ref": "305" } }, "isOverride": false, @@ -12336,7 +12595,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.topAction" }, { - "$id": "840", + "$id": "857", "kind": "basic", "name": "topAction2", "isExactName": false, @@ -12347,19 +12606,19 @@ ], "doc": "top level method2", "operation": { - "$id": "841", + "$id": "858", "name": "topAction2", "isExactName": false, "doc": "top level method2", "accessibility": "public", "parameters": [ { - "$id": "842", + "$id": "859", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "150" + "$ref": "157" }, "isApiVersion": false, "optional": false, @@ -12370,12 +12629,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.topAction2.accept", "methodParameterSegments": [ { - "$id": "843", + "$id": "860", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "150" + "$ref": "157" }, "location": "Header", "isApiVersion": false, @@ -12397,7 +12656,7 @@ 200 ], "bodyType": { - "$ref": "294" + "$ref": "305" }, "headers": [], "isErrorResponse": false, @@ -12423,12 +12682,12 @@ }, "parameters": [ { - "$ref": "843" + "$ref": "860" } ], "response": { "type": { - "$ref": "294" + "$ref": "305" } }, "isOverride": false, @@ -12437,7 +12696,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.topAction2" }, { - "$id": "844", + "$id": "861", "kind": "basic", "name": "patchAction", "isExactName": false, @@ -12448,20 +12707,20 @@ ], "doc": "top level patch", "operation": { - "$id": "845", + "$id": "862", "name": "patchAction", "isExactName": false, "doc": "top level patch", "accessibility": "public", "parameters": [ { - "$id": "846", + "$id": "863", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "152" + "$ref": "159" }, "isApiVersion": false, "optional": false, @@ -12472,13 +12731,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.patchAction.contentType", "methodParameterSegments": [ { - "$id": "847", + "$id": "864", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "152" + "$ref": "159" }, "location": "Header", "isApiVersion": false, @@ -12494,12 +12753,12 @@ "isExactName": false }, { - "$id": "848", + "$id": "865", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "154" + "$ref": "161" }, "isApiVersion": false, "optional": false, @@ -12510,12 +12769,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.patchAction.accept", "methodParameterSegments": [ { - "$id": "849", + "$id": "866", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "154" + "$ref": "161" }, "location": "Header", "isApiVersion": false, @@ -12531,12 +12790,12 @@ "isExactName": false }, { - "$id": "850", + "$id": "867", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "294" + "$ref": "305" }, "isApiVersion": false, "contentTypes": [ @@ -12550,12 +12809,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.patchAction.body", "methodParameterSegments": [ { - "$id": "851", + "$id": "868", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "294" + "$ref": "305" }, "location": "Body", "isApiVersion": false, @@ -12582,7 +12841,7 @@ 200 ], "bodyType": { - "$ref": "294" + "$ref": "305" }, "headers": [], "isErrorResponse": false, @@ -12611,18 +12870,18 @@ }, "parameters": [ { - "$ref": "851" + "$ref": "868" }, { - "$ref": "847" + "$ref": "864" }, { - "$ref": "849" + "$ref": "866" } ], "response": { "type": { - "$ref": "294" + "$ref": "305" } }, "isOverride": false, @@ -12631,7 +12890,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.patchAction" }, { - "$id": "852", + "$id": "869", "kind": "basic", "name": "anonymousBody", "isExactName": false, @@ -12642,19 +12901,19 @@ ], "doc": "body parameter without body decorator", "operation": { - "$id": "853", + "$id": "870", "name": "anonymousBody", "isExactName": false, "doc": "body parameter without body decorator", "accessibility": "public", "parameters": [ { - "$id": "854", + "$id": "871", "kind": "query", "name": "requiredQueryParam", "serializedName": "requiredQueryParam", "type": { - "$ref": "156" + "$ref": "163" }, "isApiVersion": false, "explode": false, @@ -12665,12 +12924,12 @@ "readOnly": false, "methodParameterSegments": [ { - "$id": "855", + "$id": "872", "kind": "method", "name": "requiredQueryParam", "serializedName": "requiredQueryParam", "type": { - "$ref": "158" + "$ref": "165" }, "location": "Query", "isApiVersion": false, @@ -12686,12 +12945,12 @@ "isExactName": false }, { - "$id": "856", + "$id": "873", "kind": "header", "name": "requiredHeader", "serializedName": "required-header", "type": { - "$ref": "160" + "$ref": "167" }, "isApiVersion": false, "optional": false, @@ -12702,12 +12961,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.anonymousBody.requiredHeader", "methodParameterSegments": [ { - "$id": "857", + "$id": "874", "kind": "method", "name": "requiredHeader", "serializedName": "required-header", "type": { - "$ref": "162" + "$ref": "169" }, "location": "Header", "isApiVersion": false, @@ -12723,13 +12982,13 @@ "isExactName": false }, { - "$id": "858", + "$id": "875", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "164" + "$ref": "171" }, "isApiVersion": false, "optional": false, @@ -12740,13 +12999,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.anonymousBody.contentType", "methodParameterSegments": [ { - "$id": "859", + "$id": "876", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "164" + "$ref": "171" }, "location": "Header", "isApiVersion": false, @@ -12762,12 +13021,12 @@ "isExactName": false }, { - "$id": "860", + "$id": "877", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "166" + "$ref": "173" }, "isApiVersion": false, "optional": false, @@ -12778,12 +13037,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.anonymousBody.accept", "methodParameterSegments": [ { - "$id": "861", + "$id": "878", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "166" + "$ref": "173" }, "location": "Header", "isApiVersion": false, @@ -12799,12 +13058,12 @@ "isExactName": false }, { - "$id": "862", + "$id": "879", "kind": "body", "name": "thing", "serializedName": "thing", "type": { - "$ref": "294" + "$ref": "305" }, "isApiVersion": false, "contentTypes": [ @@ -12818,13 +13077,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.anonymousBody.body", "methodParameterSegments": [ { - "$id": "863", + "$id": "880", "kind": "method", "name": "name", "serializedName": "name", "doc": "name of the Thing", "type": { - "$id": "864", + "$id": "881", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -12855,7 +13114,7 @@ 200 ], "bodyType": { - "$ref": "294" + "$ref": "305" }, "headers": [], "isErrorResponse": false, @@ -12884,16 +13143,16 @@ }, "parameters": [ { - "$ref": "863" + "$ref": "880" }, { - "$id": "865", + "$id": "882", "kind": "method", "name": "requiredUnion", "serializedName": "requiredUnion", "doc": "required Union", "type": { - "$ref": "298" + "$ref": "309" }, "location": "Body", "isApiVersion": false, @@ -12906,13 +13165,13 @@ "isExactName": false }, { - "$id": "866", + "$id": "883", "kind": "method", "name": "requiredLiteralString", "serializedName": "requiredLiteralString", "doc": "required literal string", "type": { - "$ref": "100" + "$ref": "107" }, "location": "Body", "isApiVersion": false, @@ -12925,13 +13184,13 @@ "isExactName": false }, { - "$id": "867", + "$id": "884", "kind": "method", "name": "requiredNullableString", "serializedName": "requiredNullableString", "doc": "required nullable string", "type": { - "$ref": "305" + "$ref": "316" }, "location": "Body", "isApiVersion": false, @@ -12944,13 +13203,13 @@ "isExactName": false }, { - "$id": "868", + "$id": "885", "kind": "method", "name": "optionalNullableString", "serializedName": "optionalNullableString", "doc": "required optional string", "type": { - "$ref": "308" + "$ref": "319" }, "location": "Body", "isApiVersion": false, @@ -12963,13 +13222,13 @@ "isExactName": false }, { - "$id": "869", + "$id": "886", "kind": "method", "name": "requiredLiteralInt", "serializedName": "requiredLiteralInt", "doc": "required literal int", "type": { - "$ref": "102" + "$ref": "109" }, "location": "Body", "isApiVersion": false, @@ -12982,13 +13241,13 @@ "isExactName": false }, { - "$id": "870", + "$id": "887", "kind": "method", "name": "requiredLiteralFloat", "serializedName": "requiredLiteralFloat", "doc": "required literal float", "type": { - "$ref": "104" + "$ref": "111" }, "location": "Body", "isApiVersion": false, @@ -13001,13 +13260,13 @@ "isExactName": false }, { - "$id": "871", + "$id": "888", "kind": "method", "name": "requiredLiteralBool", "serializedName": "requiredLiteralBool", "doc": "required literal bool", "type": { - "$ref": "106" + "$ref": "113" }, "location": "Body", "isApiVersion": false, @@ -13020,19 +13279,19 @@ "isExactName": false }, { - "$id": "872", + "$id": "889", "kind": "method", "name": "optionalLiteralString", "serializedName": "optionalLiteralString", "doc": "optional literal string", "type": { - "$id": "873", + "$id": "890", "kind": "enum", "name": "ThingOptionalLiteralString", "apiVersions": [], "crossLanguageDefinitionId": "", "valueType": { - "$id": "874", + "$id": "891", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -13040,12 +13299,12 @@ }, "values": [ { - "$id": "875", + "$id": "892", "kind": "enumvalue", "name": "reject", "value": "reject", "valueType": { - "$id": "876", + "$id": "893", "kind": "string", "decorators": [], "doc": "A sequence of textual characters.", @@ -13053,7 +13312,7 @@ "crossLanguageDefinitionId": "TypeSpec.string" }, "enumType": { - "$ref": "873" + "$ref": "890" }, "decorators": [], "isExactName": false @@ -13077,13 +13336,13 @@ "isExactName": false }, { - "$id": "877", + "$id": "894", "kind": "method", "name": "requiredNullableLiteralString", "serializedName": "requiredNullableLiteralString", "doc": "required nullable literal string", "type": { - "$ref": "315" + "$ref": "326" }, "location": "Body", "isApiVersion": false, @@ -13096,19 +13355,19 @@ "isExactName": false }, { - "$id": "878", + "$id": "895", "kind": "method", "name": "optionalLiteralInt", "serializedName": "optionalLiteralInt", "doc": "optional literal int", "type": { - "$id": "879", + "$id": "896", "kind": "enum", "name": "ThingOptionalLiteralInt", "apiVersions": [], "crossLanguageDefinitionId": "", "valueType": { - "$id": "880", + "$id": "897", "kind": "int32", "name": "int32", "crossLanguageDefinitionId": "TypeSpec.int32", @@ -13116,12 +13375,12 @@ }, "values": [ { - "$id": "881", + "$id": "898", "kind": "enumvalue", "name": "456", "value": 456, "valueType": { - "$id": "882", + "$id": "899", "kind": "int32", "decorators": [], "doc": "A 32-bit integer. (`-2,147,483,648` to `2,147,483,647`)", @@ -13129,7 +13388,7 @@ "crossLanguageDefinitionId": "TypeSpec.int32" }, "enumType": { - "$ref": "879" + "$ref": "896" }, "decorators": [], "isExactName": false @@ -13153,19 +13412,19 @@ "isExactName": false }, { - "$id": "883", + "$id": "900", "kind": "method", "name": "optionalLiteralFloat", "serializedName": "optionalLiteralFloat", "doc": "optional literal float", "type": { - "$id": "884", + "$id": "901", "kind": "enum", "name": "ThingOptionalLiteralFloat", "apiVersions": [], "crossLanguageDefinitionId": "", "valueType": { - "$id": "885", + "$id": "902", "kind": "float32", "name": "float32", "crossLanguageDefinitionId": "TypeSpec.float32", @@ -13173,12 +13432,12 @@ }, "values": [ { - "$id": "886", + "$id": "903", "kind": "enumvalue", "name": "4.56", "value": 4.56, "valueType": { - "$id": "887", + "$id": "904", "kind": "float32", "decorators": [], "doc": "A 32 bit floating point number. (`±1.5 x 10^−45` to `±3.4 x 10^38`)", @@ -13186,7 +13445,7 @@ "crossLanguageDefinitionId": "TypeSpec.float32" }, "enumType": { - "$ref": "884" + "$ref": "901" }, "decorators": [], "isExactName": false @@ -13210,13 +13469,13 @@ "isExactName": false }, { - "$id": "888", + "$id": "905", "kind": "method", "name": "optionalLiteralBool", "serializedName": "optionalLiteralBool", "doc": "optional literal bool", "type": { - "$ref": "108" + "$ref": "115" }, "location": "Body", "isApiVersion": false, @@ -13229,13 +13488,13 @@ "isExactName": false }, { - "$id": "889", + "$id": "906", "kind": "method", "name": "requiredBadDescription", "serializedName": "requiredBadDescription", "doc": "description with xml <|endoftext|>", "type": { - "$id": "890", + "$id": "907", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -13252,13 +13511,13 @@ "isExactName": false }, { - "$id": "891", + "$id": "908", "kind": "method", "name": "optionalNullableList", "serializedName": "optionalNullableList", "doc": "optional nullable collection", "type": { - "$ref": "322" + "$ref": "333" }, "location": "Body", "isApiVersion": false, @@ -13271,13 +13530,13 @@ "isExactName": false }, { - "$id": "892", + "$id": "909", "kind": "method", "name": "requiredNullableList", "serializedName": "requiredNullableList", "doc": "required nullable collection", "type": { - "$ref": "326" + "$ref": "337" }, "location": "Body", "isApiVersion": false, @@ -13290,13 +13549,13 @@ "isExactName": false }, { - "$id": "893", + "$id": "910", "kind": "method", "name": "propertyWithSpecialDocs", "serializedName": "propertyWithSpecialDocs", "doc": "This tests:\n- Simple bullet point. This bullet point is going to be very long to test how text wrapping is handled in bullet points within documentation comments. It should properly indent the wrapped lines.\n- Another bullet point with **bold text**. This bullet point is also intentionally long to see how the formatting is preserved when the text wraps onto multiple lines in the generated documentation.\n- Third bullet point with *italic text*. Similar to the previous points, this one is extended to ensure that the wrapping and formatting are correctly applied in the output.\n- Complex bullet point with **bold** and *italic* combined. This bullet point combines both bold and italic formatting and is long enough to test the wrapping behavior in such cases.\n- **Bold bullet point**: A bullet point that is entirely bolded. This point is also made lengthy to observe how the bold formatting is maintained across wrapped lines.\n- *Italic bullet point*: A bullet point that is entirely italicized. This final point is extended to verify that italic formatting is correctly applied even when the text spans multiple lines.", "type": { - "$id": "894", + "$id": "911", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -13313,21 +13572,21 @@ "isExactName": false }, { - "$ref": "855" + "$ref": "872" }, { - "$ref": "857" + "$ref": "874" }, { - "$ref": "859" + "$ref": "876" }, { - "$ref": "861" + "$ref": "878" } ], "response": { "type": { - "$ref": "294" + "$ref": "305" } }, "isOverride": false, @@ -13336,7 +13595,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.anonymousBody" }, { - "$id": "895", + "$id": "912", "kind": "basic", "name": "friendlyModel", "isExactName": false, @@ -13347,20 +13606,20 @@ ], "doc": "Model can have its friendly name", "operation": { - "$id": "896", + "$id": "913", "name": "friendlyModel", "isExactName": false, "doc": "Model can have its friendly name", "accessibility": "public", "parameters": [ { - "$id": "897", + "$id": "914", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "178" + "$ref": "185" }, "isApiVersion": false, "optional": false, @@ -13371,13 +13630,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.friendlyModel.contentType", "methodParameterSegments": [ { - "$id": "898", + "$id": "915", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "178" + "$ref": "185" }, "location": "Header", "isApiVersion": false, @@ -13393,12 +13652,12 @@ "isExactName": false }, { - "$id": "899", + "$id": "916", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "180" + "$ref": "187" }, "isApiVersion": false, "optional": false, @@ -13409,12 +13668,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.friendlyModel.accept", "methodParameterSegments": [ { - "$id": "900", + "$id": "917", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "180" + "$ref": "187" }, "location": "Header", "isApiVersion": false, @@ -13430,12 +13689,12 @@ "isExactName": false }, { - "$id": "901", + "$id": "918", "kind": "body", "name": "friend", "serializedName": "friend", "type": { - "$ref": "385" + "$ref": "396" }, "isApiVersion": false, "contentTypes": [ @@ -13449,13 +13708,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.friendlyModel.body", "methodParameterSegments": [ { - "$id": "902", + "$id": "919", "kind": "method", "name": "name", "serializedName": "name", "doc": "name of the NotFriend", "type": { - "$id": "903", + "$id": "920", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -13486,7 +13745,7 @@ 200 ], "bodyType": { - "$ref": "385" + "$ref": "396" }, "headers": [], "isErrorResponse": false, @@ -13515,18 +13774,18 @@ }, "parameters": [ { - "$ref": "902" + "$ref": "919" }, { - "$ref": "898" + "$ref": "915" }, { - "$ref": "900" + "$ref": "917" } ], "response": { "type": { - "$ref": "385" + "$ref": "396" } }, "isOverride": false, @@ -13535,7 +13794,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.friendlyModel" }, { - "$id": "904", + "$id": "921", "kind": "basic", "name": "addTimeHeader", "isExactName": false, @@ -13545,23 +13804,23 @@ "2024-08-16-preview" ], "operation": { - "$id": "905", + "$id": "922", "name": "addTimeHeader", "isExactName": false, "accessibility": "public", "parameters": [ { - "$id": "906", + "$id": "923", "kind": "header", "name": "repeatabilityFirstSent", "serializedName": "Repeatability-First-Sent", "type": { - "$id": "907", + "$id": "924", "kind": "utcDateTime", "name": "utcDateTime", "encode": "rfc7231", "wireType": { - "$id": "908", + "$id": "925", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -13579,17 +13838,17 @@ "crossLanguageDefinitionId": "SampleTypeSpec.addTimeHeader.repeatabilityFirstSent", "methodParameterSegments": [ { - "$id": "909", + "$id": "926", "kind": "method", "name": "repeatabilityFirstSent", "serializedName": "Repeatability-First-Sent", "type": { - "$id": "910", + "$id": "927", "kind": "utcDateTime", "name": "utcDateTime", "encode": "rfc7231", "wireType": { - "$id": "911", + "$id": "928", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -13634,7 +13893,7 @@ }, "parameters": [ { - "$ref": "909" + "$ref": "926" } ], "response": {}, @@ -13644,7 +13903,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.addTimeHeader" }, { - "$id": "912", + "$id": "929", "kind": "basic", "name": "projectedNameModel", "isExactName": false, @@ -13655,20 +13914,20 @@ ], "doc": "Model can have its projected name", "operation": { - "$id": "913", + "$id": "930", "name": "projectedNameModel", "isExactName": false, "doc": "Model can have its projected name", "accessibility": "public", "parameters": [ { - "$id": "914", + "$id": "931", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "182" + "$ref": "189" }, "isApiVersion": false, "optional": false, @@ -13679,13 +13938,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.projectedNameModel.contentType", "methodParameterSegments": [ { - "$id": "915", + "$id": "932", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "182" + "$ref": "189" }, "location": "Header", "isApiVersion": false, @@ -13701,12 +13960,12 @@ "isExactName": false }, { - "$id": "916", + "$id": "933", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "184" + "$ref": "191" }, "isApiVersion": false, "optional": false, @@ -13717,12 +13976,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.projectedNameModel.accept", "methodParameterSegments": [ { - "$id": "917", + "$id": "934", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "184" + "$ref": "191" }, "location": "Header", "isApiVersion": false, @@ -13738,12 +13997,12 @@ "isExactName": false }, { - "$id": "918", + "$id": "935", "kind": "body", "name": "renamedModel", "serializedName": "renamedModel", "type": { - "$ref": "388" + "$ref": "399" }, "isApiVersion": false, "contentTypes": [ @@ -13757,13 +14016,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.projectedNameModel.body", "methodParameterSegments": [ { - "$id": "919", + "$id": "936", "kind": "method", "name": "otherName", "serializedName": "otherName", "doc": "name of the ModelWithClientName", "type": { - "$id": "920", + "$id": "937", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -13794,7 +14053,7 @@ 200 ], "bodyType": { - "$ref": "388" + "$ref": "399" }, "headers": [], "isErrorResponse": false, @@ -13823,18 +14082,18 @@ }, "parameters": [ { - "$ref": "919" + "$ref": "936" }, { - "$ref": "915" + "$ref": "932" }, { - "$ref": "917" + "$ref": "934" } ], "response": { "type": { - "$ref": "388" + "$ref": "399" } }, "isOverride": false, @@ -13843,7 +14102,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.projectedNameModel" }, { - "$id": "921", + "$id": "938", "kind": "basic", "name": "returnsAnonymousModel", "isExactName": false, @@ -13854,19 +14113,19 @@ ], "doc": "return anonymous model", "operation": { - "$id": "922", + "$id": "939", "name": "returnsAnonymousModel", "isExactName": false, "doc": "return anonymous model", "accessibility": "public", "parameters": [ { - "$id": "923", + "$id": "940", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "186" + "$ref": "193" }, "isApiVersion": false, "optional": false, @@ -13877,12 +14136,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.returnsAnonymousModel.accept", "methodParameterSegments": [ { - "$id": "924", + "$id": "941", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "186" + "$ref": "193" }, "location": "Header", "isApiVersion": false, @@ -13904,7 +14163,7 @@ 200 ], "bodyType": { - "$ref": "391" + "$ref": "402" }, "headers": [], "isErrorResponse": false, @@ -13930,12 +14189,12 @@ }, "parameters": [ { - "$ref": "924" + "$ref": "941" } ], "response": { "type": { - "$ref": "391" + "$ref": "402" } }, "isOverride": false, @@ -13944,7 +14203,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.returnsAnonymousModel" }, { - "$id": "925", + "$id": "942", "kind": "basic", "name": "getUnknownValue", "isExactName": false, @@ -13955,19 +14214,19 @@ ], "doc": "get extensible enum", "operation": { - "$id": "926", + "$id": "943", "name": "getUnknownValue", "isExactName": false, "doc": "get extensible enum", "accessibility": "public", "parameters": [ { - "$id": "927", + "$id": "944", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "188" + "$ref": "195" }, "isApiVersion": false, "optional": false, @@ -13978,12 +14237,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.getUnknownValue.accept", "methodParameterSegments": [ { - "$id": "928", + "$id": "945", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "188" + "$ref": "195" }, "location": "Header", "isApiVersion": false, @@ -14005,7 +14264,7 @@ 200 ], "bodyType": { - "$ref": "87" + "$ref": "94" }, "headers": [], "isErrorResponse": false, @@ -14027,12 +14286,12 @@ }, "parameters": [ { - "$ref": "928" + "$ref": "945" } ], "response": { "type": { - "$ref": "87" + "$ref": "94" } }, "isOverride": false, @@ -14041,7 +14300,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.getUnknownValue" }, { - "$id": "929", + "$id": "946", "kind": "basic", "name": "internalProtocol", "isExactName": false, @@ -14052,20 +14311,20 @@ ], "doc": "When set protocol false and convenient true, then the protocol method should be internal", "operation": { - "$id": "930", + "$id": "947", "name": "internalProtocol", "isExactName": false, "doc": "When set protocol false and convenient true, then the protocol method should be internal", "accessibility": "public", "parameters": [ { - "$id": "931", + "$id": "948", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "190" + "$ref": "197" }, "isApiVersion": false, "optional": false, @@ -14076,13 +14335,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.internalProtocol.contentType", "methodParameterSegments": [ { - "$id": "932", + "$id": "949", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "190" + "$ref": "197" }, "location": "Header", "isApiVersion": false, @@ -14098,12 +14357,12 @@ "isExactName": false }, { - "$id": "933", + "$id": "950", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "192" + "$ref": "199" }, "isApiVersion": false, "optional": false, @@ -14114,12 +14373,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.internalProtocol.accept", "methodParameterSegments": [ { - "$id": "934", + "$id": "951", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "192" + "$ref": "199" }, "location": "Header", "isApiVersion": false, @@ -14135,12 +14394,12 @@ "isExactName": false }, { - "$id": "935", + "$id": "952", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "294" + "$ref": "305" }, "isApiVersion": false, "contentTypes": [ @@ -14154,12 +14413,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.internalProtocol.body", "methodParameterSegments": [ { - "$id": "936", + "$id": "953", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "294" + "$ref": "305" }, "location": "Body", "isApiVersion": false, @@ -14186,7 +14445,7 @@ 200 ], "bodyType": { - "$ref": "294" + "$ref": "305" }, "headers": [], "isErrorResponse": false, @@ -14215,18 +14474,18 @@ }, "parameters": [ { - "$ref": "936" + "$ref": "953" }, { - "$ref": "932" + "$ref": "949" }, { - "$ref": "934" + "$ref": "951" } ], "response": { "type": { - "$ref": "294" + "$ref": "305" } }, "isOverride": false, @@ -14235,7 +14494,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.internalProtocol" }, { - "$id": "937", + "$id": "954", "kind": "basic", "name": "stillConvenient", "isExactName": false, @@ -14246,7 +14505,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": "938", + "$id": "955", "name": "stillConvenient", "isExactName": false, "doc": "When set protocol false and convenient true, the convenient method should be generated even it has the same signature as protocol one", @@ -14280,7 +14539,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.stillConvenient" }, { - "$id": "939", + "$id": "956", "kind": "basic", "name": "headAsBoolean", "isExactName": false, @@ -14291,19 +14550,19 @@ ], "doc": "Check whether a resource exists: return true for success, false for 404, and throw for unexpected responses.", "operation": { - "$id": "940", + "$id": "957", "name": "headAsBoolean", "isExactName": false, "doc": "Check whether a resource exists: return true for success, false for 404, and throw for unexpected responses.", "accessibility": "public", "parameters": [ { - "$id": "941", + "$id": "958", "kind": "path", "name": "id", "serializedName": "id", "type": { - "$id": "942", + "$id": "959", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -14321,12 +14580,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.headAsBoolean.id", "methodParameterSegments": [ { - "$id": "943", + "$id": "960", "kind": "method", "name": "id", "serializedName": "id", "type": { - "$id": "944", + "$id": "961", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -14377,12 +14636,12 @@ }, "parameters": [ { - "$ref": "943" + "$ref": "960" } ], "response": { "type": { - "$id": "945", + "$id": "962", "kind": "boolean", "name": "boolean", "crossLanguageDefinitionId": "TypeSpec.boolean", @@ -14395,7 +14654,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.headAsBoolean" }, { - "$id": "946", + "$id": "963", "kind": "basic", "name": "WithApiVersion", "isExactName": false, @@ -14406,19 +14665,19 @@ ], "doc": "Return hi again", "operation": { - "$id": "947", + "$id": "964", "name": "WithApiVersion", "isExactName": false, "doc": "Return hi again", "accessibility": "public", "parameters": [ { - "$id": "948", + "$id": "965", "kind": "header", "name": "p1", "serializedName": "p1", "type": { - "$id": "949", + "$id": "966", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -14433,12 +14692,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.WithApiVersion.p1", "methodParameterSegments": [ { - "$id": "950", + "$id": "967", "kind": "method", "name": "p1", "serializedName": "p1", "type": { - "$id": "951", + "$id": "968", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -14458,12 +14717,12 @@ "isExactName": false }, { - "$id": "952", + "$id": "969", "kind": "query", "name": "apiVersion", "serializedName": "apiVersion", "type": { - "$id": "953", + "$id": "970", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -14473,7 +14732,7 @@ "explode": false, "defaultValue": { "type": { - "$id": "954", + "$id": "971", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string" @@ -14487,12 +14746,12 @@ "readOnly": false, "methodParameterSegments": [ { - "$id": "955", + "$id": "972", "kind": "method", "name": "apiVersion", "serializedName": "apiVersion", "type": { - "$id": "956", + "$id": "973", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -14502,7 +14761,7 @@ "isApiVersion": true, "defaultValue": { "type": { - "$id": "957", + "$id": "974", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string" @@ -14543,7 +14802,7 @@ }, "parameters": [ { - "$ref": "950" + "$ref": "967" } ], "response": {}, @@ -14553,7 +14812,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.WithApiVersion" }, { - "$id": "958", + "$id": "975", "kind": "paging", "name": "ListWithNextLink", "isExactName": false, @@ -14564,19 +14823,19 @@ ], "doc": "List things with nextlink", "operation": { - "$id": "959", + "$id": "976", "name": "ListWithNextLink", "isExactName": false, "doc": "List things with nextlink", "accessibility": "public", "parameters": [ { - "$id": "960", + "$id": "977", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "194" + "$ref": "201" }, "isApiVersion": false, "optional": false, @@ -14587,12 +14846,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ListWithNextLink.accept", "methodParameterSegments": [ { - "$id": "961", + "$id": "978", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "194" + "$ref": "201" }, "location": "Header", "isApiVersion": false, @@ -14614,7 +14873,7 @@ 200 ], "bodyType": { - "$ref": "392" + "$ref": "403" }, "headers": [], "isErrorResponse": false, @@ -14640,12 +14899,12 @@ }, "parameters": [ { - "$ref": "961" + "$ref": "978" } ], "response": { "type": { - "$ref": "394" + "$ref": "405" }, "resultSegments": [ "things" @@ -14670,7 +14929,7 @@ } }, { - "$id": "962", + "$id": "979", "kind": "paging", "name": "ListWithStringNextLink", "isExactName": false, @@ -14681,19 +14940,19 @@ ], "doc": "List things with nextlink", "operation": { - "$id": "963", + "$id": "980", "name": "ListWithStringNextLink", "isExactName": false, "doc": "List things with nextlink", "accessibility": "public", "parameters": [ { - "$id": "964", + "$id": "981", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "196" + "$ref": "203" }, "isApiVersion": false, "optional": false, @@ -14704,12 +14963,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ListWithStringNextLink.accept", "methodParameterSegments": [ { - "$id": "965", + "$id": "982", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "196" + "$ref": "203" }, "location": "Header", "isApiVersion": false, @@ -14731,7 +14990,7 @@ 200 ], "bodyType": { - "$ref": "397" + "$ref": "408" }, "headers": [], "isErrorResponse": false, @@ -14757,12 +15016,12 @@ }, "parameters": [ { - "$ref": "965" + "$ref": "982" } ], "response": { "type": { - "$ref": "394" + "$ref": "405" }, "resultSegments": [ "things" @@ -14787,7 +15046,7 @@ } }, { - "$id": "966", + "$id": "983", "kind": "paging", "name": "ListWithContinuationToken", "isExactName": false, @@ -14798,19 +15057,19 @@ ], "doc": "List things with continuation token", "operation": { - "$id": "967", + "$id": "984", "name": "ListWithContinuationToken", "isExactName": false, "doc": "List things with continuation token", "accessibility": "public", "parameters": [ { - "$id": "968", + "$id": "985", "kind": "query", "name": "token", "serializedName": "token", "type": { - "$id": "969", + "$id": "986", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -14825,12 +15084,12 @@ "readOnly": false, "methodParameterSegments": [ { - "$id": "970", + "$id": "987", "kind": "method", "name": "token", "serializedName": "token", "type": { - "$id": "971", + "$id": "988", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -14850,12 +15109,12 @@ "isExactName": false }, { - "$id": "972", + "$id": "989", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "198" + "$ref": "205" }, "isApiVersion": false, "optional": false, @@ -14866,12 +15125,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ListWithContinuationToken.accept", "methodParameterSegments": [ { - "$id": "973", + "$id": "990", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "198" + "$ref": "205" }, "location": "Header", "isApiVersion": false, @@ -14893,7 +15152,7 @@ 200 ], "bodyType": { - "$ref": "401" + "$ref": "412" }, "headers": [], "isErrorResponse": false, @@ -14919,15 +15178,15 @@ }, "parameters": [ { - "$ref": "970" + "$ref": "987" }, { - "$ref": "973" + "$ref": "990" } ], "response": { "type": { - "$ref": "394" + "$ref": "405" }, "resultSegments": [ "things" @@ -14943,7 +15202,7 @@ ], "continuationToken": { "parameter": { - "$ref": "968" + "$ref": "985" }, "responseSegments": [ "nextToken" @@ -14954,7 +15213,7 @@ } }, { - "$id": "974", + "$id": "991", "kind": "paging", "name": "ListWithContinuationTokenHeaderResponse", "isExactName": false, @@ -14965,19 +15224,19 @@ ], "doc": "List things with continuation token header response", "operation": { - "$id": "975", + "$id": "992", "name": "ListWithContinuationTokenHeaderResponse", "isExactName": false, "doc": "List things with continuation token header response", "accessibility": "public", "parameters": [ { - "$id": "976", + "$id": "993", "kind": "query", "name": "token", "serializedName": "token", "type": { - "$id": "977", + "$id": "994", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -14992,12 +15251,12 @@ "readOnly": false, "methodParameterSegments": [ { - "$id": "978", + "$id": "995", "kind": "method", "name": "token", "serializedName": "token", "type": { - "$id": "979", + "$id": "996", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -15017,12 +15276,12 @@ "isExactName": false }, { - "$id": "980", + "$id": "997", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "200" + "$ref": "207" }, "isApiVersion": false, "optional": false, @@ -15033,12 +15292,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ListWithContinuationTokenHeaderResponse.accept", "methodParameterSegments": [ { - "$id": "981", + "$id": "998", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "200" + "$ref": "207" }, "location": "Header", "isApiVersion": false, @@ -15060,14 +15319,14 @@ 200 ], "bodyType": { - "$ref": "405" + "$ref": "416" }, "headers": [ { "name": "nextToken", "nameInResponse": "next-token", "type": { - "$id": "982", + "$id": "999", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -15098,15 +15357,15 @@ }, "parameters": [ { - "$ref": "978" + "$ref": "995" }, { - "$ref": "981" + "$ref": "998" } ], "response": { "type": { - "$ref": "394" + "$ref": "405" }, "resultSegments": [ "things" @@ -15122,7 +15381,7 @@ ], "continuationToken": { "parameter": { - "$ref": "976" + "$ref": "993" }, "responseSegments": [ "next-token" @@ -15133,7 +15392,7 @@ } }, { - "$id": "983", + "$id": "1000", "kind": "paging", "name": "ListWithPaging", "isExactName": false, @@ -15144,19 +15403,19 @@ ], "doc": "List things with paging", "operation": { - "$id": "984", + "$id": "1001", "name": "ListWithPaging", "isExactName": false, "doc": "List things with paging", "accessibility": "public", "parameters": [ { - "$id": "985", + "$id": "1002", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "202" + "$ref": "209" }, "isApiVersion": false, "optional": false, @@ -15167,12 +15426,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ListWithPaging.accept", "methodParameterSegments": [ { - "$id": "986", + "$id": "1003", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "202" + "$ref": "209" }, "location": "Header", "isApiVersion": false, @@ -15194,7 +15453,7 @@ 200 ], "bodyType": { - "$ref": "407" + "$ref": "418" }, "headers": [], "isErrorResponse": false, @@ -15220,12 +15479,12 @@ }, "parameters": [ { - "$ref": "986" + "$ref": "1003" } ], "response": { "type": { - "$ref": "394" + "$ref": "405" }, "resultSegments": [ "items" @@ -15243,7 +15502,7 @@ } }, { - "$id": "987", + "$id": "1004", "kind": "basic", "name": "EmbeddedParameters", "isExactName": false, @@ -15254,20 +15513,20 @@ ], "doc": "An operation with embedded parameters within the body", "operation": { - "$id": "988", + "$id": "1005", "name": "EmbeddedParameters", "isExactName": false, "doc": "An operation with embedded parameters within the body", "accessibility": "public", "parameters": [ { - "$id": "989", + "$id": "1006", "kind": "header", "name": "requiredHeader", "serializedName": "required-header", "doc": "required header parameter", "type": { - "$id": "990", + "$id": "1007", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -15282,12 +15541,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ModelWithEmbeddedNonBodyParameters.requiredHeader", "methodParameterSegments": [ { - "$id": "991", + "$id": "1008", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "409" + "$ref": "420" }, "location": "Body", "isApiVersion": false, @@ -15300,13 +15559,13 @@ "isExactName": false }, { - "$id": "992", + "$id": "1009", "kind": "method", "name": "requiredHeader", "serializedName": "requiredHeader", "doc": "required header parameter", "type": { - "$ref": "413" + "$ref": "424" }, "location": "", "isApiVersion": false, @@ -15322,13 +15581,13 @@ "isExactName": false }, { - "$id": "993", + "$id": "1010", "kind": "header", "name": "optionalHeader", "serializedName": "optional-header", "doc": "optional header parameter", "type": { - "$id": "994", + "$id": "1011", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -15343,16 +15602,16 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ModelWithEmbeddedNonBodyParameters.optionalHeader", "methodParameterSegments": [ { - "$ref": "991" + "$ref": "1008" }, { - "$id": "995", + "$id": "1012", "kind": "method", "name": "optionalHeader", "serializedName": "optionalHeader", "doc": "optional header parameter", "type": { - "$ref": "415" + "$ref": "426" }, "location": "", "isApiVersion": false, @@ -15368,13 +15627,13 @@ "isExactName": false }, { - "$id": "996", + "$id": "1013", "kind": "query", "name": "requiredQuery", "serializedName": "requiredQuery", "doc": "required query parameter", "type": { - "$id": "997", + "$id": "1014", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -15389,16 +15648,16 @@ "readOnly": false, "methodParameterSegments": [ { - "$ref": "991" + "$ref": "1008" }, { - "$id": "998", + "$id": "1015", "kind": "method", "name": "requiredQuery", "serializedName": "requiredQuery", "doc": "required query parameter", "type": { - "$ref": "417" + "$ref": "428" }, "location": "", "isApiVersion": false, @@ -15414,13 +15673,13 @@ "isExactName": false }, { - "$id": "999", + "$id": "1016", "kind": "query", "name": "optionalQuery", "serializedName": "optionalQuery", "doc": "optional query parameter", "type": { - "$id": "1000", + "$id": "1017", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -15435,16 +15694,16 @@ "readOnly": false, "methodParameterSegments": [ { - "$ref": "991" + "$ref": "1008" }, { - "$id": "1001", + "$id": "1018", "kind": "method", "name": "optionalQuery", "serializedName": "optionalQuery", "doc": "optional query parameter", "type": { - "$ref": "419" + "$ref": "430" }, "location": "", "isApiVersion": false, @@ -15460,13 +15719,13 @@ "isExactName": false }, { - "$id": "1002", + "$id": "1019", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "204" + "$ref": "211" }, "isApiVersion": false, "optional": false, @@ -15477,13 +15736,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.EmbeddedParameters.contentType", "methodParameterSegments": [ { - "$id": "1003", + "$id": "1020", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "204" + "$ref": "211" }, "location": "Header", "isApiVersion": false, @@ -15499,12 +15758,12 @@ "isExactName": false }, { - "$id": "1004", + "$id": "1021", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "409" + "$ref": "420" }, "isApiVersion": false, "contentTypes": [ @@ -15518,7 +15777,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.EmbeddedParameters.body", "methodParameterSegments": [ { - "$ref": "991" + "$ref": "1008" } ], "isExactName": false, @@ -15554,10 +15813,10 @@ }, "parameters": [ { - "$ref": "991" + "$ref": "1008" }, { - "$ref": "1003" + "$ref": "1020" } ], "response": {}, @@ -15567,7 +15826,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.EmbeddedParameters" }, { - "$id": "1005", + "$id": "1022", "kind": "basic", "name": "DynamicModelOperation", "isExactName": false, @@ -15578,20 +15837,20 @@ ], "doc": "An operation with a dynamic model", "operation": { - "$id": "1006", + "$id": "1023", "name": "DynamicModelOperation", "isExactName": false, "doc": "An operation with a dynamic model", "accessibility": "public", "parameters": [ { - "$id": "1007", + "$id": "1024", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "206" + "$ref": "213" }, "isApiVersion": false, "optional": false, @@ -15602,13 +15861,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.DynamicModelOperation.contentType", "methodParameterSegments": [ { - "$id": "1008", + "$id": "1025", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "206" + "$ref": "213" }, "location": "Header", "isApiVersion": false, @@ -15624,12 +15883,12 @@ "isExactName": false }, { - "$id": "1009", + "$id": "1026", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "420" + "$ref": "431" }, "isApiVersion": false, "contentTypes": [ @@ -15643,12 +15902,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.DynamicModelOperation.body", "methodParameterSegments": [ { - "$id": "1010", + "$id": "1027", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "420" + "$ref": "431" }, "location": "Body", "isApiVersion": false, @@ -15700,10 +15959,10 @@ }, "parameters": [ { - "$ref": "1010" + "$ref": "1027" }, { - "$ref": "1008" + "$ref": "1025" } ], "response": {}, @@ -15713,7 +15972,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.DynamicModelOperation" }, { - "$id": "1011", + "$id": "1028", "kind": "basic", "name": "GetXmlAdvancedModel", "isExactName": false, @@ -15724,19 +15983,19 @@ ], "doc": "Get an advanced XML model with various property types", "operation": { - "$id": "1012", + "$id": "1029", "name": "GetXmlAdvancedModel", "isExactName": false, "doc": "Get an advanced XML model with various property types", "accessibility": "public", "parameters": [ { - "$id": "1013", + "$id": "1030", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "208" + "$ref": "215" }, "isApiVersion": false, "optional": false, @@ -15747,12 +16006,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.GetXmlAdvancedModel.accept", "methodParameterSegments": [ { - "$id": "1014", + "$id": "1031", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "208" + "$ref": "215" }, "location": "Header", "isApiVersion": false, @@ -15774,14 +16033,14 @@ 200 ], "bodyType": { - "$ref": "458" + "$ref": "469" }, "headers": [ { "name": "contentType", "nameInResponse": "content-type", "type": { - "$ref": "210" + "$ref": "217" } } ], @@ -15808,12 +16067,12 @@ }, "parameters": [ { - "$ref": "1014" + "$ref": "1031" } ], "response": { "type": { - "$ref": "458" + "$ref": "469" } }, "isOverride": false, @@ -15822,7 +16081,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.GetXmlAdvancedModel" }, { - "$id": "1015", + "$id": "1032", "kind": "basic", "name": "UpdateXmlAdvancedModel", "isExactName": false, @@ -15833,19 +16092,19 @@ ], "doc": "Update an advanced XML model with various property types", "operation": { - "$id": "1016", + "$id": "1033", "name": "UpdateXmlAdvancedModel", "isExactName": false, "doc": "Update an advanced XML model with various property types", "accessibility": "public", "parameters": [ { - "$id": "1017", + "$id": "1034", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "212" + "$ref": "219" }, "isApiVersion": false, "optional": false, @@ -15856,12 +16115,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.UpdateXmlAdvancedModel.contentType", "methodParameterSegments": [ { - "$id": "1018", + "$id": "1035", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "212" + "$ref": "219" }, "location": "Header", "isApiVersion": false, @@ -15877,12 +16136,12 @@ "isExactName": false }, { - "$id": "1019", + "$id": "1036", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "216" + "$ref": "223" }, "isApiVersion": false, "optional": false, @@ -15893,12 +16152,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.UpdateXmlAdvancedModel.accept", "methodParameterSegments": [ { - "$id": "1020", + "$id": "1037", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "216" + "$ref": "223" }, "location": "Header", "isApiVersion": false, @@ -15914,12 +16173,12 @@ "isExactName": false }, { - "$id": "1021", + "$id": "1038", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "458" + "$ref": "469" }, "isApiVersion": false, "contentTypes": [ @@ -15933,12 +16192,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.UpdateXmlAdvancedModel.body", "methodParameterSegments": [ { - "$id": "1022", + "$id": "1039", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "458" + "$ref": "469" }, "location": "Body", "isApiVersion": false, @@ -15965,14 +16224,14 @@ 200 ], "bodyType": { - "$ref": "458" + "$ref": "469" }, "headers": [ { "name": "contentType", "nameInResponse": "content-type", "type": { - "$ref": "218" + "$ref": "225" } } ], @@ -16002,18 +16261,18 @@ }, "parameters": [ { - "$ref": "1022" + "$ref": "1039" }, { - "$ref": "1018" + "$ref": "1035" }, { - "$ref": "1020" + "$ref": "1037" } ], "response": { "type": { - "$ref": "458" + "$ref": "469" } }, "isOverride": false, @@ -16022,7 +16281,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.UpdateXmlAdvancedModel" }, { - "$id": "1023", + "$id": "1040", "kind": "basic", "name": "uploadCat", "isExactName": false, @@ -16032,18 +16291,18 @@ "2024-08-16-preview" ], "operation": { - "$id": "1024", + "$id": "1041", "name": "uploadCat", "isExactName": false, "accessibility": "public", "parameters": [ { - "$id": "1025", + "$id": "1042", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "220" + "$ref": "227" }, "isApiVersion": false, "optional": false, @@ -16054,12 +16313,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.uploadCat.contentType", "methodParameterSegments": [ { - "$id": "1026", + "$id": "1043", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "220" + "$ref": "227" }, "location": "Header", "isApiVersion": false, @@ -16075,12 +16334,12 @@ "isExactName": false }, { - "$id": "1027", + "$id": "1044", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$ref": "554" + "$ref": "565" }, "isApiVersion": false, "contentTypes": [ @@ -16094,12 +16353,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.uploadCat.body", "methodParameterSegments": [ { - "$id": "1028", + "$id": "1045", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "554" + "$ref": "565" }, "location": "Body", "isApiVersion": false, @@ -16141,10 +16400,10 @@ }, "parameters": [ { - "$ref": "1026" + "$ref": "1043" }, { - "$ref": "1028" + "$ref": "1045" } ], "response": {}, @@ -16154,7 +16413,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.uploadCat" }, { - "$id": "1029", + "$id": "1046", "kind": "basic", "name": "sendJsonLines", "isExactName": false, @@ -16164,18 +16423,18 @@ "2024-08-16-preview" ], "operation": { - "$id": "1030", + "$id": "1047", "name": "sendJsonLines", "isExactName": false, "accessibility": "public", "parameters": [ { - "$id": "1031", + "$id": "1048", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "224" + "$ref": "231" }, "isApiVersion": false, "optional": false, @@ -16186,16 +16445,16 @@ "crossLanguageDefinitionId": "TypeSpec.Http.Streams.JsonlStream.contentType", "methodParameterSegments": [ { - "$id": "1032", + "$id": "1049", "kind": "method", "name": "stream", "serializedName": "stream", "type": { - "$id": "1033", + "$id": "1050", "kind": "streaming", "name": "JsonlStreamStreamingItem", "valueType": { - "$ref": "599" + "$ref": "610" }, "streamKind": "jsonl", "contentTypes": [ @@ -16214,12 +16473,12 @@ "isExactName": false }, { - "$id": "1034", + "$id": "1051", "kind": "method", "name": "contentType", "serializedName": "contentType", "type": { - "$ref": "226" + "$ref": "233" }, "location": "", "isApiVersion": false, @@ -16235,16 +16494,16 @@ "isExactName": false }, { - "$id": "1035", + "$id": "1052", "kind": "body", "name": "body", "serializedName": "body", "type": { - "$id": "1036", + "$id": "1053", "kind": "streaming", "name": "JsonlStreamStreamingItem", "valueType": { - "$ref": "599" + "$ref": "610" }, "streamKind": "jsonl", "contentTypes": [ @@ -16264,15 +16523,15 @@ "crossLanguageDefinitionId": "TypeSpec.Http.Streams.JsonlStream.body", "methodParameterSegments": [ { - "$ref": "1032" + "$ref": "1049" }, { - "$id": "1037", + "$id": "1054", "kind": "method", "name": "body", "serializedName": "body", "type": { - "$ref": "759" + "$ref": "776" }, "location": "", "isApiVersion": false, @@ -16318,7 +16577,7 @@ }, "parameters": [ { - "$ref": "1032" + "$ref": "1049" } ], "response": {}, @@ -16328,7 +16587,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.sendJsonLines" }, { - "$id": "1038", + "$id": "1055", "kind": "basic", "name": "receiveJsonLines", "isExactName": false, @@ -16338,18 +16597,18 @@ "2024-08-16-preview" ], "operation": { - "$id": "1039", + "$id": "1056", "name": "receiveJsonLines", "isExactName": false, "accessibility": "public", "parameters": [ { - "$id": "1040", + "$id": "1057", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "228" + "$ref": "235" }, "isApiVersion": false, "optional": false, @@ -16360,12 +16619,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.receiveJsonLines.accept", "methodParameterSegments": [ { - "$id": "1041", + "$id": "1058", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "228" + "$ref": "235" }, "location": "Header", "isApiVersion": false, @@ -16387,11 +16646,11 @@ 200 ], "bodyType": { - "$id": "1042", + "$id": "1059", "kind": "streaming", "name": "JsonlStreamStreamingItem", "valueType": { - "$ref": "599" + "$ref": "610" }, "streamKind": "jsonl", "contentTypes": [ @@ -16404,7 +16663,7 @@ "name": "contentType", "nameInResponse": "content-type", "type": { - "$ref": "230" + "$ref": "237" } } ], @@ -16431,16 +16690,16 @@ }, "parameters": [ { - "$ref": "1041" + "$ref": "1058" } ], "response": { "type": { - "$id": "1043", + "$id": "1060", "kind": "streaming", "name": "JsonlStreamStreamingItem", "valueType": { - "$ref": "599" + "$ref": "610" }, "streamKind": "jsonl", "contentTypes": [ @@ -16455,7 +16714,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.receiveJsonLines" }, { - "$id": "1044", + "$id": "1061", "kind": "basic", "name": "receiveSse", "isExactName": false, @@ -16465,18 +16724,18 @@ "2024-08-16-preview" ], "operation": { - "$id": "1045", + "$id": "1062", "name": "receiveSse", "isExactName": false, "accessibility": "public", "parameters": [ { - "$id": "1046", + "$id": "1063", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "232" + "$ref": "239" }, "isApiVersion": false, "optional": false, @@ -16487,12 +16746,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.receiveSse.accept", "methodParameterSegments": [ { - "$id": "1047", + "$id": "1064", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "232" + "$ref": "239" }, "location": "Header", "isApiVersion": false, @@ -16514,19 +16773,19 @@ 200 ], "bodyType": { - "$id": "1048", + "$id": "1065", "kind": "streaming", "name": "SSEStreamSampleEvents", "valueType": { - "$id": "1049", + "$id": "1066", "kind": "union", "name": "SampleEvents", "variantTypes": [ { - "$ref": "599" + "$ref": "610" }, { - "$ref": "234" + "$ref": "241" } ], "namespace": "SampleTypeSpec", @@ -16545,7 +16804,7 @@ "name": "contentType", "nameInResponse": "content-type", "type": { - "$ref": "236" + "$ref": "243" } } ], @@ -16568,16 +16827,16 @@ }, "parameters": [ { - "$ref": "1047" + "$ref": "1064" } ], "response": { "type": { - "$id": "1050", + "$id": "1067", "kind": "streaming", "name": "SSEStreamSampleEvents", "valueType": { - "$ref": "1049" + "$ref": "1066" }, "streamKind": "sse", "contentTypes": [ @@ -16593,7 +16852,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.receiveSse" }, { - "$id": "1051", + "$id": "1068", "kind": "basic", "name": "receiveExperimentalJsonLines", "isExactName": false, @@ -16603,18 +16862,18 @@ "2024-08-16-preview" ], "operation": { - "$id": "1052", + "$id": "1069", "name": "receiveExperimentalJsonLines", "isExactName": false, "accessibility": "public", "parameters": [ { - "$id": "1053", + "$id": "1070", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "238" + "$ref": "245" }, "isApiVersion": false, "optional": false, @@ -16625,12 +16884,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.receiveExperimentalJsonLines.accept", "methodParameterSegments": [ { - "$id": "1054", + "$id": "1071", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "238" + "$ref": "245" }, "location": "Header", "isApiVersion": false, @@ -16652,11 +16911,11 @@ 200 ], "bodyType": { - "$id": "1055", + "$id": "1072", "kind": "streaming", "name": "JsonlStreamPreviewDetails", "valueType": { - "$ref": "602" + "$ref": "613" }, "streamKind": "jsonl", "contentTypes": [ @@ -16669,7 +16928,7 @@ "name": "contentType", "nameInResponse": "content-type", "type": { - "$ref": "240" + "$ref": "247" } } ], @@ -16696,16 +16955,16 @@ }, "parameters": [ { - "$ref": "1054" + "$ref": "1071" } ], "response": { "type": { - "$id": "1056", + "$id": "1073", "kind": "streaming", "name": "JsonlStreamPreviewDetails", "valueType": { - "$ref": "602" + "$ref": "613" }, "streamKind": "jsonl", "contentTypes": [ @@ -16720,7 +16979,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.receiveExperimentalJsonLines" }, { - "$id": "1057", + "$id": "1074", "kind": "basic", "name": "getAcronymParameters", "isExactName": false, @@ -16731,19 +16990,19 @@ ], "doc": "Send acronym-named path, query, and header parameters.", "operation": { - "$id": "1058", + "$id": "1075", "name": "getAcronymParameters", "isExactName": false, "doc": "Send acronym-named path, query, and header parameters.", "accessibility": "public", "parameters": [ { - "$id": "1059", + "$id": "1076", "kind": "path", "name": "targetDbName", "serializedName": "targetDbName", "type": { - "$id": "1060", + "$id": "1077", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -16761,12 +17020,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.getAcronymParameters.targetDbName", "methodParameterSegments": [ { - "$id": "1061", + "$id": "1078", "kind": "method", "name": "targetDbName", "serializedName": "targetDbName", "type": { - "$id": "1062", + "$id": "1079", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -16786,12 +17045,12 @@ "isExactName": false }, { - "$id": "1063", + "$id": "1080", "kind": "query", "name": "sourceIpAddress", "serializedName": "sourceIpAddress", "type": { - "$id": "1064", + "$id": "1081", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -16806,12 +17065,12 @@ "readOnly": false, "methodParameterSegments": [ { - "$id": "1065", + "$id": "1082", "kind": "method", "name": "sourceIpAddress", "serializedName": "sourceIpAddress", "type": { - "$id": "1066", + "$id": "1083", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -16831,12 +17090,12 @@ "isExactName": false }, { - "$id": "1067", + "$id": "1084", "kind": "header", "name": "guestOsType", "serializedName": "X-Guest-OS-Type", "type": { - "$id": "1068", + "$id": "1085", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -16851,12 +17110,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.getAcronymParameters.guestOsType", "methodParameterSegments": [ { - "$id": "1069", + "$id": "1086", "kind": "method", "name": "guestOsType", "serializedName": "X-Guest-OS-Type", "type": { - "$id": "1070", + "$id": "1087", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -16898,13 +17157,13 @@ }, "parameters": [ { - "$ref": "1061" + "$ref": "1078" }, { - "$ref": "1065" + "$ref": "1082" }, { - "$ref": "1069" + "$ref": "1086" } ], "response": {}, @@ -16914,7 +17173,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.getAcronymParameters" }, { - "$id": "1071", + "$id": "1088", "kind": "basic", "name": "setAcronymAddresses", "isExactName": false, @@ -16925,19 +17184,19 @@ ], "doc": "Send parameters with leading IP version acronyms.", "operation": { - "$id": "1072", + "$id": "1089", "name": "setAcronymAddresses", "isExactName": false, "doc": "Send parameters with leading IP version acronyms.", "accessibility": "public", "parameters": [ { - "$id": "1073", + "$id": "1090", "kind": "query", "name": "ipV4Address", "serializedName": "ipV4Address", "type": { - "$id": "1074", + "$id": "1091", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -16952,12 +17211,12 @@ "readOnly": false, "methodParameterSegments": [ { - "$id": "1075", + "$id": "1092", "kind": "method", "name": "ipV4Address", "serializedName": "ipV4Address", "type": { - "$id": "1076", + "$id": "1093", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -16977,12 +17236,12 @@ "isExactName": false }, { - "$id": "1077", + "$id": "1094", "kind": "query", "name": "ipV6Address", "serializedName": "ipV6Address", "type": { - "$id": "1078", + "$id": "1095", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -16997,12 +17256,12 @@ "readOnly": false, "methodParameterSegments": [ { - "$id": "1079", + "$id": "1096", "kind": "method", "name": "ipV6Address", "serializedName": "ipV6Address", "type": { - "$id": "1080", + "$id": "1097", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -17044,10 +17303,10 @@ }, "parameters": [ { - "$ref": "1075" + "$ref": "1092" }, { - "$ref": "1079" + "$ref": "1096" } ], "response": {}, @@ -17059,12 +17318,12 @@ ], "parameters": [ { - "$id": "1081", + "$id": "1098", "kind": "endpoint", "name": "sampleTypeSpecUrl", "serializedName": "sampleTypeSpecUrl", "type": { - "$id": "1082", + "$id": "1099", "kind": "url", "name": "endpoint", "crossLanguageDefinitionId": "TypeSpec.url" @@ -17080,7 +17339,7 @@ "isExactName": false }, { - "$ref": "955" + "$ref": "972" } ], "initializedBy": 1, @@ -17092,14 +17351,14 @@ ], "children": [ { - "$id": "1083", + "$id": "1100", "kind": "client", "name": "ExperimentalSamples", "isExactName": false, "namespace": "SampleTypeSpec", "methods": [ { - "$id": "1084", + "$id": "1101", "kind": "basic", "name": "read", "isExactName": false, @@ -17109,18 +17368,18 @@ "2024-08-16-preview" ], "operation": { - "$id": "1085", + "$id": "1102", "name": "read", "isExactName": false, "accessibility": "public", "parameters": [ { - "$id": "1086", + "$id": "1103", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "242" + "$ref": "249" }, "isApiVersion": false, "optional": false, @@ -17131,12 +17390,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ExperimentalSamples.read.accept", "methodParameterSegments": [ { - "$id": "1087", + "$id": "1104", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "242" + "$ref": "249" }, "location": "Header", "isApiVersion": false, @@ -17158,7 +17417,7 @@ 200 ], "bodyType": { - "$ref": "604" + "$ref": "615" }, "headers": [], "isErrorResponse": false, @@ -17184,12 +17443,12 @@ }, "parameters": [ { - "$ref": "1087" + "$ref": "1104" } ], "response": { "type": { - "$ref": "604" + "$ref": "615" } }, "isOverride": false, @@ -17198,7 +17457,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ExperimentalSamples.read" }, { - "$id": "1088", + "$id": "1105", "kind": "paging", "name": "list", "isExactName": false, @@ -17208,18 +17467,18 @@ "2024-08-16-preview" ], "operation": { - "$id": "1089", + "$id": "1106", "name": "list", "isExactName": false, "accessibility": "public", "parameters": [ { - "$id": "1090", + "$id": "1107", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "244" + "$ref": "251" }, "isApiVersion": false, "optional": false, @@ -17230,12 +17489,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.ExperimentalSamples.list.accept", "methodParameterSegments": [ { - "$id": "1091", + "$id": "1108", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "244" + "$ref": "251" }, "location": "Header", "isApiVersion": false, @@ -17257,7 +17516,7 @@ 200 ], "bodyType": { - "$ref": "607" + "$ref": "618" }, "headers": [], "isErrorResponse": false, @@ -17283,12 +17542,12 @@ }, "parameters": [ { - "$ref": "1091" + "$ref": "1108" } ], "response": { "type": { - "$ref": "609" + "$ref": "620" }, "resultSegments": [ "items" @@ -17308,12 +17567,12 @@ ], "parameters": [ { - "$id": "1092", + "$id": "1109", "kind": "endpoint", "name": "sampleTypeSpecUrl", "serializedName": "sampleTypeSpecUrl", "type": { - "$id": "1093", + "$id": "1110", "kind": "url", "name": "endpoint", "crossLanguageDefinitionId": "TypeSpec.url" @@ -17337,7 +17596,7 @@ "2024-08-16-preview" ], "parent": { - "$ref": "760" + "$ref": "777" }, "isMultiServiceClient": false, "experimental": { @@ -17346,14 +17605,14 @@ } }, { - "$id": "1094", + "$id": "1111", "kind": "client", "name": "AnimalOperations", "isExactName": false, "namespace": "SampleTypeSpec", "methods": [ { - "$id": "1095", + "$id": "1112", "kind": "basic", "name": "updatePetAsAnimal", "isExactName": false, @@ -17364,20 +17623,20 @@ ], "doc": "Update a pet as an animal", "operation": { - "$id": "1096", + "$id": "1113", "name": "updatePetAsAnimal", "isExactName": false, "doc": "Update a pet as an animal", "accessibility": "public", "parameters": [ { - "$id": "1097", + "$id": "1114", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "246" + "$ref": "253" }, "isApiVersion": false, "optional": false, @@ -17388,13 +17647,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal.contentType", "methodParameterSegments": [ { - "$id": "1098", + "$id": "1115", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "246" + "$ref": "253" }, "location": "Header", "isApiVersion": false, @@ -17410,12 +17669,12 @@ "isExactName": false }, { - "$id": "1099", + "$id": "1116", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "248" + "$ref": "255" }, "isApiVersion": false, "optional": false, @@ -17426,12 +17685,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal.accept", "methodParameterSegments": [ { - "$id": "1100", + "$id": "1117", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "248" + "$ref": "255" }, "location": "Header", "isApiVersion": false, @@ -17447,12 +17706,12 @@ "isExactName": false }, { - "$id": "1101", + "$id": "1118", "kind": "body", "name": "animal", "serializedName": "animal", "type": { - "$ref": "610" + "$ref": "621" }, "isApiVersion": false, "contentTypes": [ @@ -17466,12 +17725,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal.animal", "methodParameterSegments": [ { - "$id": "1102", + "$id": "1119", "kind": "method", "name": "animal", "serializedName": "animal", "type": { - "$ref": "610" + "$ref": "621" }, "location": "Body", "isApiVersion": false, @@ -17498,7 +17757,7 @@ 200 ], "bodyType": { - "$ref": "610" + "$ref": "621" }, "headers": [], "isErrorResponse": false, @@ -17527,18 +17786,18 @@ }, "parameters": [ { - "$ref": "1102" + "$ref": "1119" }, { - "$ref": "1098" + "$ref": "1115" }, { - "$ref": "1100" + "$ref": "1117" } ], "response": { "type": { - "$ref": "610" + "$ref": "621" } }, "isOverride": false, @@ -17547,7 +17806,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updatePetAsAnimal" }, { - "$id": "1103", + "$id": "1120", "kind": "basic", "name": "updateDogAsAnimal", "isExactName": false, @@ -17558,20 +17817,20 @@ ], "doc": "Update a dog as an animal", "operation": { - "$id": "1104", + "$id": "1121", "name": "updateDogAsAnimal", "isExactName": false, "doc": "Update a dog as an animal", "accessibility": "public", "parameters": [ { - "$id": "1105", + "$id": "1122", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "250" + "$ref": "257" }, "isApiVersion": false, "optional": false, @@ -17582,13 +17841,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal.contentType", "methodParameterSegments": [ { - "$id": "1106", + "$id": "1123", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "250" + "$ref": "257" }, "location": "Header", "isApiVersion": false, @@ -17604,12 +17863,12 @@ "isExactName": false }, { - "$id": "1107", + "$id": "1124", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "252" + "$ref": "259" }, "isApiVersion": false, "optional": false, @@ -17620,12 +17879,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal.accept", "methodParameterSegments": [ { - "$id": "1108", + "$id": "1125", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "252" + "$ref": "259" }, "location": "Header", "isApiVersion": false, @@ -17641,12 +17900,12 @@ "isExactName": false }, { - "$id": "1109", + "$id": "1126", "kind": "body", "name": "animal", "serializedName": "animal", "type": { - "$ref": "610" + "$ref": "621" }, "isApiVersion": false, "contentTypes": [ @@ -17660,12 +17919,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.AnimalOperations.updateDogAsAnimal.animal", "methodParameterSegments": [ { - "$id": "1110", + "$id": "1127", "kind": "method", "name": "animal", "serializedName": "animal", "type": { - "$ref": "610" + "$ref": "621" }, "location": "Body", "isApiVersion": false, @@ -17692,7 +17951,7 @@ 200 ], "bodyType": { - "$ref": "610" + "$ref": "621" }, "headers": [], "isErrorResponse": false, @@ -17721,18 +17980,18 @@ }, "parameters": [ { - "$ref": "1110" + "$ref": "1127" }, { - "$ref": "1106" + "$ref": "1123" }, { - "$ref": "1108" + "$ref": "1125" } ], "response": { "type": { - "$ref": "610" + "$ref": "621" } }, "isOverride": false, @@ -17743,12 +18002,12 @@ ], "parameters": [ { - "$id": "1111", + "$id": "1128", "kind": "endpoint", "name": "sampleTypeSpecUrl", "serializedName": "sampleTypeSpecUrl", "type": { - "$id": "1112", + "$id": "1129", "kind": "url", "name": "endpoint", "crossLanguageDefinitionId": "TypeSpec.url" @@ -17772,19 +18031,19 @@ "2024-08-16-preview" ], "parent": { - "$ref": "760" + "$ref": "777" }, "isMultiServiceClient": false }, { - "$id": "1113", + "$id": "1130", "kind": "client", "name": "PetOperations", "isExactName": false, "namespace": "SampleTypeSpec", "methods": [ { - "$id": "1114", + "$id": "1131", "kind": "basic", "name": "updatePetAsPet", "isExactName": false, @@ -17795,20 +18054,20 @@ ], "doc": "Update a pet as a pet", "operation": { - "$id": "1115", + "$id": "1132", "name": "updatePetAsPet", "isExactName": false, "doc": "Update a pet as a pet", "accessibility": "public", "parameters": [ { - "$id": "1116", + "$id": "1133", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "254" + "$ref": "261" }, "isApiVersion": false, "optional": false, @@ -17819,13 +18078,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet.contentType", "methodParameterSegments": [ { - "$id": "1117", + "$id": "1134", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "254" + "$ref": "261" }, "location": "Header", "isApiVersion": false, @@ -17841,12 +18100,12 @@ "isExactName": false }, { - "$id": "1118", + "$id": "1135", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "256" + "$ref": "263" }, "isApiVersion": false, "optional": false, @@ -17857,12 +18116,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet.accept", "methodParameterSegments": [ { - "$id": "1119", + "$id": "1136", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "256" + "$ref": "263" }, "location": "Header", "isApiVersion": false, @@ -17878,12 +18137,12 @@ "isExactName": false }, { - "$id": "1120", + "$id": "1137", "kind": "body", "name": "pet", "serializedName": "pet", "type": { - "$ref": "615" + "$ref": "626" }, "isApiVersion": false, "contentTypes": [ @@ -17897,12 +18156,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet.pet", "methodParameterSegments": [ { - "$id": "1121", + "$id": "1138", "kind": "method", "name": "pet", "serializedName": "pet", "type": { - "$ref": "615" + "$ref": "626" }, "location": "Body", "isApiVersion": false, @@ -17929,7 +18188,7 @@ 200 ], "bodyType": { - "$ref": "615" + "$ref": "626" }, "headers": [], "isErrorResponse": false, @@ -17958,18 +18217,18 @@ }, "parameters": [ { - "$ref": "1121" + "$ref": "1138" }, { - "$ref": "1117" + "$ref": "1134" }, { - "$ref": "1119" + "$ref": "1136" } ], "response": { "type": { - "$ref": "615" + "$ref": "626" } }, "isOverride": false, @@ -17978,7 +18237,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updatePetAsPet" }, { - "$id": "1122", + "$id": "1139", "kind": "basic", "name": "updateDogAsPet", "isExactName": false, @@ -17989,20 +18248,20 @@ ], "doc": "Update a dog as a pet", "operation": { - "$id": "1123", + "$id": "1140", "name": "updateDogAsPet", "isExactName": false, "doc": "Update a dog as a pet", "accessibility": "public", "parameters": [ { - "$id": "1124", + "$id": "1141", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "258" + "$ref": "265" }, "isApiVersion": false, "optional": false, @@ -18013,13 +18272,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet.contentType", "methodParameterSegments": [ { - "$id": "1125", + "$id": "1142", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "258" + "$ref": "265" }, "location": "Header", "isApiVersion": false, @@ -18035,12 +18294,12 @@ "isExactName": false }, { - "$id": "1126", + "$id": "1143", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "260" + "$ref": "267" }, "isApiVersion": false, "optional": false, @@ -18051,12 +18310,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet.accept", "methodParameterSegments": [ { - "$id": "1127", + "$id": "1144", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "260" + "$ref": "267" }, "location": "Header", "isApiVersion": false, @@ -18072,12 +18331,12 @@ "isExactName": false }, { - "$id": "1128", + "$id": "1145", "kind": "body", "name": "pet", "serializedName": "pet", "type": { - "$ref": "615" + "$ref": "626" }, "isApiVersion": false, "contentTypes": [ @@ -18091,12 +18350,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PetOperations.updateDogAsPet.pet", "methodParameterSegments": [ { - "$id": "1129", + "$id": "1146", "kind": "method", "name": "pet", "serializedName": "pet", "type": { - "$ref": "615" + "$ref": "626" }, "location": "Body", "isApiVersion": false, @@ -18123,7 +18382,7 @@ 200 ], "bodyType": { - "$ref": "615" + "$ref": "626" }, "headers": [], "isErrorResponse": false, @@ -18152,18 +18411,18 @@ }, "parameters": [ { - "$ref": "1129" + "$ref": "1146" }, { - "$ref": "1125" + "$ref": "1142" }, { - "$ref": "1127" + "$ref": "1144" } ], "response": { "type": { - "$ref": "615" + "$ref": "626" } }, "isOverride": false, @@ -18174,12 +18433,12 @@ ], "parameters": [ { - "$id": "1130", + "$id": "1147", "kind": "endpoint", "name": "sampleTypeSpecUrl", "serializedName": "sampleTypeSpecUrl", "type": { - "$id": "1131", + "$id": "1148", "kind": "url", "name": "endpoint", "crossLanguageDefinitionId": "TypeSpec.url" @@ -18203,19 +18462,19 @@ "2024-08-16-preview" ], "parent": { - "$ref": "760" + "$ref": "777" }, "isMultiServiceClient": false }, { - "$id": "1132", + "$id": "1149", "kind": "client", "name": "DogOperations", "isExactName": false, "namespace": "SampleTypeSpec", "methods": [ { - "$id": "1133", + "$id": "1150", "kind": "basic", "name": "updateDogAsDog", "isExactName": false, @@ -18226,20 +18485,20 @@ ], "doc": "Update a dog as a dog", "operation": { - "$id": "1134", + "$id": "1151", "name": "updateDogAsDog", "isExactName": false, "doc": "Update a dog as a dog", "accessibility": "public", "parameters": [ { - "$id": "1135", + "$id": "1152", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "262" + "$ref": "269" }, "isApiVersion": false, "optional": false, @@ -18250,13 +18509,13 @@ "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog.contentType", "methodParameterSegments": [ { - "$id": "1136", + "$id": "1153", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "doc": "Body parameter's content type. Known values are application/json", "type": { - "$ref": "262" + "$ref": "269" }, "location": "Header", "isApiVersion": false, @@ -18272,12 +18531,12 @@ "isExactName": false }, { - "$id": "1137", + "$id": "1154", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "264" + "$ref": "271" }, "isApiVersion": false, "optional": false, @@ -18288,12 +18547,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog.accept", "methodParameterSegments": [ { - "$id": "1138", + "$id": "1155", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "264" + "$ref": "271" }, "location": "Header", "isApiVersion": false, @@ -18309,12 +18568,12 @@ "isExactName": false }, { - "$id": "1139", + "$id": "1156", "kind": "body", "name": "dog", "serializedName": "dog", "type": { - "$ref": "619" + "$ref": "630" }, "isApiVersion": false, "contentTypes": [ @@ -18328,12 +18587,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.DogOperations.updateDogAsDog.dog", "methodParameterSegments": [ { - "$id": "1140", + "$id": "1157", "kind": "method", "name": "dog", "serializedName": "dog", "type": { - "$ref": "619" + "$ref": "630" }, "location": "Body", "isApiVersion": false, @@ -18360,7 +18619,7 @@ 200 ], "bodyType": { - "$ref": "619" + "$ref": "630" }, "headers": [], "isErrorResponse": false, @@ -18389,18 +18648,18 @@ }, "parameters": [ { - "$ref": "1140" + "$ref": "1157" }, { - "$ref": "1136" + "$ref": "1153" }, { - "$ref": "1138" + "$ref": "1155" } ], "response": { "type": { - "$ref": "619" + "$ref": "630" } }, "isOverride": false, @@ -18411,12 +18670,12 @@ ], "parameters": [ { - "$id": "1141", + "$id": "1158", "kind": "endpoint", "name": "sampleTypeSpecUrl", "serializedName": "sampleTypeSpecUrl", "type": { - "$id": "1142", + "$id": "1159", "kind": "url", "name": "endpoint", "crossLanguageDefinitionId": "TypeSpec.url" @@ -18440,19 +18699,19 @@ "2024-08-16-preview" ], "parent": { - "$ref": "760" + "$ref": "777" }, "isMultiServiceClient": false }, { - "$id": "1143", + "$id": "1160", "kind": "client", "name": "PlantOperations", "isExactName": false, "namespace": "SampleTypeSpec", "methods": [ { - "$id": "1144", + "$id": "1161", "kind": "basic", "name": "getTree", "isExactName": false, @@ -18463,19 +18722,19 @@ ], "doc": "Get a tree as a plant", "operation": { - "$id": "1145", + "$id": "1162", "name": "getTree", "isExactName": false, "doc": "Get a tree as a plant", "accessibility": "public", "parameters": [ { - "$id": "1146", + "$id": "1163", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "266" + "$ref": "273" }, "isApiVersion": false, "optional": false, @@ -18486,12 +18745,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.getTree.accept", "methodParameterSegments": [ { - "$id": "1147", + "$id": "1164", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "266" + "$ref": "273" }, "location": "Header", "isApiVersion": false, @@ -18513,14 +18772,14 @@ 200 ], "bodyType": { - "$ref": "623" + "$ref": "634" }, "headers": [ { "name": "contentType", "nameInResponse": "content-type", "type": { - "$ref": "268" + "$ref": "275" } } ], @@ -18547,12 +18806,12 @@ }, "parameters": [ { - "$ref": "1147" + "$ref": "1164" } ], "response": { "type": { - "$ref": "623" + "$ref": "634" } }, "isOverride": false, @@ -18561,7 +18820,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.getTree" }, { - "$id": "1148", + "$id": "1165", "kind": "basic", "name": "getTreeAsJson", "isExactName": false, @@ -18572,19 +18831,19 @@ ], "doc": "Get a tree as a plant", "operation": { - "$id": "1149", + "$id": "1166", "name": "getTreeAsJson", "isExactName": false, "doc": "Get a tree as a plant", "accessibility": "public", "parameters": [ { - "$id": "1150", + "$id": "1167", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "270" + "$ref": "277" }, "isApiVersion": false, "optional": false, @@ -18595,12 +18854,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.getTreeAsJson.accept", "methodParameterSegments": [ { - "$id": "1151", + "$id": "1168", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "270" + "$ref": "277" }, "location": "Header", "isApiVersion": false, @@ -18622,14 +18881,14 @@ 200 ], "bodyType": { - "$ref": "623" + "$ref": "634" }, "headers": [ { "name": "contentType", "nameInResponse": "content-type", "type": { - "$ref": "272" + "$ref": "279" } } ], @@ -18656,12 +18915,12 @@ }, "parameters": [ { - "$ref": "1151" + "$ref": "1168" } ], "response": { "type": { - "$ref": "623" + "$ref": "634" } }, "isOverride": false, @@ -18670,7 +18929,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.getTreeAsJson" }, { - "$id": "1152", + "$id": "1169", "kind": "basic", "name": "updateTree", "isExactName": false, @@ -18681,19 +18940,19 @@ ], "doc": "Update a tree as a plant", "operation": { - "$id": "1153", + "$id": "1170", "name": "updateTree", "isExactName": false, "doc": "Update a tree as a plant", "accessibility": "public", "parameters": [ { - "$id": "1154", + "$id": "1171", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "274" + "$ref": "281" }, "isApiVersion": false, "optional": false, @@ -18704,12 +18963,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.updateTree.contentType", "methodParameterSegments": [ { - "$id": "1155", + "$id": "1172", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "274" + "$ref": "281" }, "location": "Header", "isApiVersion": false, @@ -18725,12 +18984,12 @@ "isExactName": false }, { - "$id": "1156", + "$id": "1173", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "278" + "$ref": "285" }, "isApiVersion": false, "optional": false, @@ -18741,12 +19000,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.updateTree.accept", "methodParameterSegments": [ { - "$id": "1157", + "$id": "1174", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "278" + "$ref": "285" }, "location": "Header", "isApiVersion": false, @@ -18762,12 +19021,12 @@ "isExactName": false }, { - "$id": "1158", + "$id": "1175", "kind": "body", "name": "tree", "serializedName": "tree", "type": { - "$ref": "623" + "$ref": "634" }, "isApiVersion": false, "contentTypes": [ @@ -18781,12 +19040,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.updateTree.tree", "methodParameterSegments": [ { - "$id": "1159", + "$id": "1176", "kind": "method", "name": "tree", "serializedName": "tree", "type": { - "$ref": "623" + "$ref": "634" }, "location": "Body", "isApiVersion": false, @@ -18813,14 +19072,14 @@ 200 ], "bodyType": { - "$ref": "623" + "$ref": "634" }, "headers": [ { "name": "contentType", "nameInResponse": "content-type", "type": { - "$ref": "280" + "$ref": "287" } } ], @@ -18850,18 +19109,18 @@ }, "parameters": [ { - "$ref": "1159" + "$ref": "1176" }, { - "$ref": "1155" + "$ref": "1172" }, { - "$ref": "1157" + "$ref": "1174" } ], "response": { "type": { - "$ref": "623" + "$ref": "634" } }, "isOverride": false, @@ -18870,7 +19129,7 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.updateTree" }, { - "$id": "1160", + "$id": "1177", "kind": "basic", "name": "updateTreeAsJson", "isExactName": false, @@ -18881,19 +19140,19 @@ ], "doc": "Update a tree as a plant", "operation": { - "$id": "1161", + "$id": "1178", "name": "updateTreeAsJson", "isExactName": false, "doc": "Update a tree as a plant", "accessibility": "public", "parameters": [ { - "$id": "1162", + "$id": "1179", "kind": "header", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "282" + "$ref": "289" }, "isApiVersion": false, "optional": false, @@ -18904,12 +19163,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.updateTreeAsJson.contentType", "methodParameterSegments": [ { - "$id": "1163", + "$id": "1180", "kind": "method", "name": "contentType", "serializedName": "Content-Type", "type": { - "$ref": "282" + "$ref": "289" }, "location": "Header", "isApiVersion": false, @@ -18925,12 +19184,12 @@ "isExactName": false }, { - "$id": "1164", + "$id": "1181", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "286" + "$ref": "293" }, "isApiVersion": false, "optional": false, @@ -18941,12 +19200,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.updateTreeAsJson.accept", "methodParameterSegments": [ { - "$id": "1165", + "$id": "1182", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "286" + "$ref": "293" }, "location": "Header", "isApiVersion": false, @@ -18962,12 +19221,12 @@ "isExactName": false }, { - "$id": "1166", + "$id": "1183", "kind": "body", "name": "tree", "serializedName": "tree", "type": { - "$ref": "623" + "$ref": "634" }, "isApiVersion": false, "contentTypes": [ @@ -18981,12 +19240,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.PlantOperations.updateTreeAsJson.tree", "methodParameterSegments": [ { - "$id": "1167", + "$id": "1184", "kind": "method", "name": "tree", "serializedName": "tree", "type": { - "$ref": "623" + "$ref": "634" }, "location": "Body", "isApiVersion": false, @@ -19013,14 +19272,14 @@ 200 ], "bodyType": { - "$ref": "623" + "$ref": "634" }, "headers": [ { "name": "contentType", "nameInResponse": "content-type", "type": { - "$ref": "288" + "$ref": "295" } } ], @@ -19050,18 +19309,18 @@ }, "parameters": [ { - "$ref": "1167" + "$ref": "1184" }, { - "$ref": "1163" + "$ref": "1180" }, { - "$ref": "1165" + "$ref": "1182" } ], "response": { "type": { - "$ref": "623" + "$ref": "634" } }, "isOverride": false, @@ -19072,12 +19331,12 @@ ], "parameters": [ { - "$id": "1168", + "$id": "1185", "kind": "endpoint", "name": "sampleTypeSpecUrl", "serializedName": "sampleTypeSpecUrl", "type": { - "$id": "1169", + "$id": "1186", "kind": "url", "name": "endpoint", "crossLanguageDefinitionId": "TypeSpec.url" @@ -19101,19 +19360,19 @@ "2024-08-16-preview" ], "parent": { - "$ref": "760" + "$ref": "777" }, "isMultiServiceClient": false }, { - "$id": "1170", + "$id": "1187", "kind": "client", "name": "Metrics", "isExactName": false, "namespace": "SampleTypeSpec", "methods": [ { - "$id": "1171", + "$id": "1188", "kind": "basic", "name": "getWidgetMetrics", "isExactName": false, @@ -19124,19 +19383,19 @@ ], "doc": "Get Widget metrics for given day of week", "operation": { - "$id": "1172", + "$id": "1189", "name": "getWidgetMetrics", "isExactName": false, "doc": "Get Widget metrics for given day of week", "accessibility": "public", "parameters": [ { - "$id": "1173", + "$id": "1190", "kind": "path", "name": "metricsNamespace", "serializedName": "metricsNamespace", "type": { - "$id": "1174", + "$id": "1191", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -19154,12 +19413,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.metricsNamespace", "methodParameterSegments": [ { - "$id": "1175", + "$id": "1192", "kind": "method", "name": "metricsNamespace", "serializedName": "metricsNamespace", "type": { - "$id": "1176", + "$id": "1193", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -19179,12 +19438,12 @@ "isExactName": false }, { - "$id": "1177", + "$id": "1194", "kind": "path", "name": "day", "serializedName": "day", "type": { - "$ref": "87" + "$ref": "94" }, "isApiVersion": false, "explode": false, @@ -19198,12 +19457,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.day", "methodParameterSegments": [ { - "$id": "1178", + "$id": "1195", "kind": "method", "name": "day", "serializedName": "day", "type": { - "$ref": "87" + "$ref": "94" }, "location": "Path", "isApiVersion": false, @@ -19219,12 +19478,12 @@ "isExactName": false }, { - "$id": "1179", + "$id": "1196", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "290" + "$ref": "297" }, "isApiVersion": false, "optional": false, @@ -19235,12 +19494,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.Metrics.getWidgetMetrics.accept", "methodParameterSegments": [ { - "$id": "1180", + "$id": "1197", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "290" + "$ref": "297" }, "location": "Header", "isApiVersion": false, @@ -19262,7 +19521,7 @@ 200 ], "bodyType": { - "$ref": "639" + "$ref": "650" }, "headers": [], "isErrorResponse": false, @@ -19288,15 +19547,15 @@ }, "parameters": [ { - "$ref": "1178" + "$ref": "1195" }, { - "$ref": "1180" + "$ref": "1197" } ], "response": { "type": { - "$ref": "639" + "$ref": "650" } }, "isOverride": false, @@ -19307,12 +19566,12 @@ ], "parameters": [ { - "$id": "1181", + "$id": "1198", "kind": "endpoint", "name": "sampleTypeSpecUrl", "serializedName": "sampleTypeSpecUrl", "type": { - "$id": "1182", + "$id": "1199", "kind": "url", "name": "endpoint", "crossLanguageDefinitionId": "TypeSpec.url" @@ -19328,7 +19587,7 @@ "isExactName": false }, { - "$ref": "1175" + "$ref": "1192" } ], "initializedBy": 3, @@ -19339,19 +19598,19 @@ "2024-08-16-preview" ], "parent": { - "$ref": "760" + "$ref": "777" }, "isMultiServiceClient": false }, { - "$id": "1183", + "$id": "1200", "kind": "client", "name": "Notebooks", "isExactName": false, "namespace": "SampleTypeSpec", "methods": [ { - "$id": "1184", + "$id": "1201", "kind": "basic", "name": "getNotebook", "isExactName": false, @@ -19362,19 +19621,19 @@ ], "doc": "Get a notebook by name", "operation": { - "$id": "1185", + "$id": "1202", "name": "getNotebook", "isExactName": false, "doc": "Get a notebook by name", "accessibility": "public", "parameters": [ { - "$id": "1186", + "$id": "1203", "kind": "path", "name": "notebookName", "serializedName": "notebookName", "type": { - "$id": "1187", + "$id": "1204", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -19392,12 +19651,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.Notebooks.getNotebook.notebookName", "methodParameterSegments": [ { - "$id": "1188", + "$id": "1205", "kind": "method", "name": "notebook", "serializedName": "notebook", "type": { - "$id": "1189", + "$id": "1206", "kind": "string", "name": "string", "crossLanguageDefinitionId": "TypeSpec.string", @@ -19418,12 +19677,12 @@ "isExactName": false }, { - "$id": "1190", + "$id": "1207", "kind": "header", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "292" + "$ref": "299" }, "isApiVersion": false, "optional": false, @@ -19434,12 +19693,12 @@ "crossLanguageDefinitionId": "SampleTypeSpec.Notebooks.getNotebook.accept", "methodParameterSegments": [ { - "$id": "1191", + "$id": "1208", "kind": "method", "name": "accept", "serializedName": "Accept", "type": { - "$ref": "292" + "$ref": "299" }, "location": "Header", "isApiVersion": false, @@ -19461,7 +19720,7 @@ 200 ], "bodyType": { - "$ref": "644" + "$ref": "655" }, "headers": [], "isErrorResponse": false, @@ -19487,12 +19746,12 @@ }, "parameters": [ { - "$ref": "1191" + "$ref": "1208" } ], "response": { "type": { - "$ref": "644" + "$ref": "655" } }, "isOverride": false, @@ -19503,12 +19762,12 @@ ], "parameters": [ { - "$id": "1192", + "$id": "1209", "kind": "endpoint", "name": "sampleTypeSpecUrl", "serializedName": "sampleTypeSpecUrl", "type": { - "$id": "1193", + "$id": "1210", "kind": "url", "name": "endpoint", "crossLanguageDefinitionId": "TypeSpec.url" @@ -19524,7 +19783,7 @@ "isExactName": false }, { - "$ref": "1188" + "$ref": "1205" } ], "initializedBy": 3, @@ -19535,7 +19794,249 @@ "2024-08-16-preview" ], "parent": { - "$ref": "760" + "$ref": "777" + }, + "isMultiServiceClient": false + }, + { + "$id": "1211", + "kind": "client", + "name": "DeprecationSamples", + "isExactName": false, + "namespace": "SampleTypeSpec", + "methods": [ + { + "$id": "1212", + "kind": "basic", + "name": "legacy", + "isExactName": false, + "accessibility": "public", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "operation": { + "$id": "1213", + "name": "legacy", + "isExactName": false, + "deprecated": "Use \"read\" instead.\nSee C:\\sdk.", + "accessibility": "public", + "parameters": [ + { + "$id": "1214", + "kind": "header", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "301" + }, + "isApiVersion": false, + "optional": false, + "isContentType": false, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.DeprecationSamples.legacy.accept", + "methodParameterSegments": [ + { + "$id": "1215", + "kind": "method", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "301" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.DeprecationSamples.legacy.accept", + "readOnly": false, + "access": "public", + "decorators": [], + "isExactName": false + } + ], + "isExactName": false + } + ], + "responses": [ + { + "statusCodes": [ + 200 + ], + "bodyType": { + "$ref": "660" + }, + "headers": [], + "isErrorResponse": false, + "contentTypes": [ + "application/json" + ], + "serializationOptions": { + "json": { + "name": "" + } + } + } + ], + "httpMethod": "GET", + "uri": "{sampleTypeSpecUrl}", + "path": "/deprecated", + "bufferResponse": true, + "generateProtocolMethod": true, + "generateConvenienceMethod": true, + "crossLanguageDefinitionId": "SampleTypeSpec.DeprecationSamples.legacy", + "decorators": [], + "namespace": "SampleTypeSpec" + }, + "parameters": [ + { + "$ref": "1215" + } + ], + "response": { + "type": { + "$ref": "660" + } + }, + "isOverride": false, + "generateConvenient": true, + "generateProtocol": true, + "crossLanguageDefinitionId": "SampleTypeSpec.DeprecationSamples.legacy" + }, + { + "$id": "1216", + "kind": "basic", + "name": "read", + "isExactName": false, + "accessibility": "public", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "operation": { + "$id": "1217", + "name": "read", + "isExactName": false, + "accessibility": "public", + "parameters": [ + { + "$id": "1218", + "kind": "header", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "303" + }, + "isApiVersion": false, + "optional": false, + "isContentType": false, + "scope": "Constant", + "readOnly": false, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.DeprecationSamples.read.accept", + "methodParameterSegments": [ + { + "$id": "1219", + "kind": "method", + "name": "accept", + "serializedName": "Accept", + "type": { + "$ref": "303" + }, + "location": "Header", + "isApiVersion": false, + "optional": false, + "scope": "Constant", + "crossLanguageDefinitionId": "SampleTypeSpec.DeprecationSamples.read.accept", + "readOnly": false, + "access": "public", + "decorators": [], + "isExactName": false + } + ], + "isExactName": false + } + ], + "responses": [ + { + "statusCodes": [ + 200 + ], + "bodyType": { + "$ref": "663" + }, + "headers": [], + "isErrorResponse": false, + "contentTypes": [ + "application/json" + ], + "serializationOptions": { + "json": { + "name": "" + } + } + } + ], + "httpMethod": "GET", + "uri": "{sampleTypeSpecUrl}", + "path": "/deprecated/current", + "bufferResponse": true, + "generateProtocolMethod": true, + "generateConvenienceMethod": true, + "crossLanguageDefinitionId": "SampleTypeSpec.DeprecationSamples.read", + "decorators": [], + "namespace": "SampleTypeSpec" + }, + "parameters": [ + { + "$ref": "1219" + } + ], + "response": { + "type": { + "$ref": "663" + } + }, + "isOverride": false, + "generateConvenient": true, + "generateProtocol": true, + "crossLanguageDefinitionId": "SampleTypeSpec.DeprecationSamples.read" + } + ], + "parameters": [ + { + "$id": "1220", + "kind": "endpoint", + "name": "sampleTypeSpecUrl", + "serializedName": "sampleTypeSpecUrl", + "type": { + "$id": "1221", + "kind": "url", + "name": "endpoint", + "crossLanguageDefinitionId": "TypeSpec.url" + }, + "isApiVersion": false, + "optional": false, + "scope": "Client", + "isEndpoint": true, + "serverUrlTemplate": "{sampleTypeSpecUrl}", + "skipUrlEncoding": false, + "readOnly": false, + "crossLanguageDefinitionId": "SampleTypeSpec.DeprecationSamples.sampleTypeSpecUrl", + "isExactName": false + } + ], + "initializedBy": 0, + "decorators": [], + "crossLanguageDefinitionId": "SampleTypeSpec.DeprecationSamples", + "apiVersions": [ + "2024-07-16-preview", + "2024-08-16-preview" + ], + "parent": { + "$ref": "777" }, "isMultiServiceClient": false } From b32c6bfbc58c2dd1d7218bd7e9a23234b209fd23 Mon Sep 17 00:00:00 2001 From: Josh Love Date: Fri, 23 Oct 2026 14:21:28 -0700 Subject: [PATCH 2/9] fix(http-client-csharp): deduplicate obsolete partial attributes Keep customization-owned Obsolete attributes on the defining declaration in the shared partial-signature builder, covering non-client methods as well as operation methods. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../Providers/ScmMethodProviderCollection.cs | 8 ++---- .../Providers/PartialMethodCustomization.cs | 5 +++- ...MethodsKeepObsoleteOnDeclaration(False).cs | 24 +++++++++++++++++ ...lMethodsKeepObsoleteOnDeclaration(True).cs | 15 +++++++++++ .../Custom.cs | 18 +++++++++++++ .../test/Providers/TypeProviderTests.cs | 26 +++++++++++++++++++ 6 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration(False).cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration(True).cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration/Custom.cs diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs index 2387bf32f90..36feabadb45 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs @@ -1157,12 +1157,8 @@ private static void ApplyExperimentalAttributes( private void ApplyDeprecationAttribute(MethodSignature signature, MethodSignature? customSignature) { - if (customSignature?.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) == true) - { - // Attributes on the defining partial declaration also apply to the implementation. - signature.Update(attributes: [.. signature.Attributes.Where(a => !DeprecationApiHelpers.IsObsoleteAttribute(a))]); - } - else if (!signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) + if (customSignature?.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) != true + && !signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) && Client.BackCompatProvider.LastContractView?.Methods.Any(previous => MethodSignatureHelper.IsPublicApi(previous.Signature) && MethodSignatureBase.SignatureComparer.Equals(previous.Signature, signature) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PartialMethodCustomization.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PartialMethodCustomization.cs index 5dbcb7f0aa1..07b9636bbee 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PartialMethodCustomization.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PartialMethodCustomization.cs @@ -3,7 +3,9 @@ using System; using System.Collections.Generic; +using System.Linq; using Microsoft.TypeSpec.Generator.Primitives; +using Microsoft.TypeSpec.Generator.Utilities; namespace Microsoft.TypeSpec.Generator.Providers { @@ -162,6 +164,7 @@ public static IReadOnlyList RenameAndCloneParameters( /// (modifiers, name, return type, attributes, and /// other signature metadata) and the supplied . /// The result has applied. + /// Custom obsolete attributes remain on the defining declaration to avoid duplicate attributes. /// /// The customer's partial declaration signature. /// The parameters to use for the implementation. @@ -203,7 +206,7 @@ public static MethodSignature BuildPartialSignature( returnType ?? customSignature.ReturnType, customSignature.ReturnDescription, implementationParameters, - customSignature.Attributes, + [.. customSignature.Attributes.Where(attribute => !DeprecationApiHelpers.IsObsoleteAttribute(attribute))], customSignature.GenericArguments, customSignature.GenericParameterConstraints, customSignature.ExplicitInterface, diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration(False).cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration(False).cs new file mode 100644 index 00000000000..2a04768d00d --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration(False).cs @@ -0,0 +1,24 @@ +// + +#nullable disable + +namespace Test +{ + public partial class CustomPartialMethodType + { + public partial int Legacy() + { + return 1; + } + + public partial int WithoutMessage() + { + return 1; + } + + public partial int Current() + { + return 1; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration(True).cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration(True).cs new file mode 100644 index 00000000000..f8b525bf0b0 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration(True).cs @@ -0,0 +1,15 @@ +// + +#nullable disable + +namespace Test +{ + public partial class CustomPartialMethodType + { + public partial int Legacy() => 1; + + public partial int WithoutMessage() => 1; + + public partial int Current() => 1; + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration/Custom.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration/Custom.cs new file mode 100644 index 00000000000..73b2053e4a0 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepObsoleteOnDeclaration/Custom.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Test +{ + public partial class CustomPartialMethodType + { + [Obsolete("Use \"Current\" instead.\nSee C:\\sdk.")] + public partial int Legacy(); + + [Obsolete] + public partial int WithoutMessage(); + + public partial int Current(); + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs index 186093e042f..7fe5835a710 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs @@ -2179,6 +2179,32 @@ public async Task CustomPartialMethodImplementationUsesGeneratorReturnType() $"Partial implementation wrote a return type with no namespace:\n{result}"); } + [TestCase(false)] + [TestCase(true)] + public async Task CustomPartialMethodsKeepObsoleteOnDeclaration(bool expressionBody) + { + await MockHelpers.LoadMockGeneratorAsync(compilation: () => Helpers.GetCompilationFromDirectoryAsync()); + var typeProvider = new TestTypeProvider(name: "CustomPartialMethodType"); + var methods = new[] { "Legacy", "WithoutMessage", "Current" }.Select(name => + { + var signature = new MethodSignature(name, null, MethodSignatureModifiers.Public, typeof(int), null, []); + return expressionBody + ? new MethodProvider(signature, Snippet.Literal(1), typeProvider) + : new MethodProvider(signature, Snippet.Return(Snippet.Literal(1)), typeProvider); + }); + typeProvider.Update(methods: methods); + + Assert.AreEqual(3, typeProvider.Methods.Count); + Assert.IsTrue(typeProvider.Methods.All(method => method.IsPartialMethod)); + Assert.IsTrue(typeProvider.Methods.All(method => !method.Signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute))); + var customMethods = typeProvider.CustomCodeView!.Methods; + Assert.AreEqual("\"Use \\\"Current\\\" instead.\\nSee C:\\\\sdk.\"", + customMethods.Single(method => method.Signature.Name == "Legacy").Signature.Attributes.Single().Arguments.Single().ToDisplayString()); + Assert.IsEmpty(customMethods.Single(method => method.Signature.Name == "WithoutMessage").Signature.Attributes.Single().Arguments); + Assert.IsEmpty(customMethods.Single(method => method.Signature.Name == "Current").Signature.Attributes); + Assert.AreEqual(Helpers.GetExpectedFromFile(expressionBody.ToString()), new TypeProviderWriter(typeProvider).Write().Content); + } + [Test] public async Task TestSpecViewReturnsAllPropertiesEvenWhenSuppressed() { From fb5bf9564c3119e74012eb3d77c43fda7511ce43 Mon Sep 17 00:00:00 2001 From: Josh Love Date: Fri, 23 Oct 2026 15:13:37 -0700 Subject: [PATCH 3/9] fix(http-client-csharp): preserve combined deprecation metadata Suppress all experimental and obsolete diagnostics on generated model registrations. Defer GA method filtering until after compatibility overload restoration so previously obsolete overloads retain the current message. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../ModelReaderWriterContextDefinition.cs | 37 +++++++-------- .../Providers/ScmMethodProviderCollection.cs | 4 -- ...ModelReaderWriterContextDefinitionTests.cs | 46 +++++++++++++++++++ ...ntalDeprecatedModelsHaveAllSuppressions.cs | 24 ++++++++++ .../CustomCombinedModel.cs | 14 ++++++ ...soleteFrameworkTypesHaveAllSuppressions.cs | 20 ++++++++ .../ScmMethodProviderCollectionTests.cs | 38 +++++++++++++++ .../TestClient.cs | 34 ++++++++++++++ .../src/Statements/SuppressionStatement.cs | 3 +- .../Local.Tests/CustomizationTests.cs | 1 + .../Local/Sample-TypeSpec/Sample-TypeSpec.tsp | 4 ++ .../DeprecationSamples.RestClient.cs | 2 + .../src/Generated/DeprecationSamples.cs | 8 ++++ .../Models/CurrentDetails.Serialization.cs | 2 + .../src/Generated/Models/CurrentDetails.cs | 2 + .../src/Generated/Models/LegacyDetails.cs | 2 + .../Generated/Models/SampleTypeSpecContext.cs | 2 + .../Generated/SampleTypeSpecModelFactory.cs | 3 ++ .../Local/Sample-TypeSpec/tspCodeModel.json | 6 ++- 19 files changed, 226 insertions(+), 26 deletions(-) create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalDeprecatedModelsHaveAllSuppressions.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalDeprecatedModelsHaveAllSuppressions/CustomCombinedModel.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalObsoleteFrameworkTypesHaveAllSuppressions.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecationPreservesObsoleteOverloadsBesideStableSignatures/TestClient.cs diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelReaderWriterContextDefinition.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelReaderWriterContextDefinition.cs index c803920de00..618143591ad 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelReaderWriterContextDefinition.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelReaderWriterContextDefinition.cs @@ -618,23 +618,21 @@ private static void AddAttributeForType( TypeProvider typeProvider, string key) { - AttributeStatement? experimentalOrObsoleteAttribute = typeProvider.CanonicalView.Attributes - .FirstOrDefault(a => ExperimentalApiHelpers.IsExperimentalAttribute(a) || a.Type.Equals(typeof(ObsoleteAttribute))); - - if (experimentalOrObsoleteAttribute is not null && ExperimentalApiHelpers.IsExperimentalAttribute(experimentalOrObsoleteAttribute)) - { - string justification = $"{typeProvider.Type} is experimental and may change in future versions."; - attributes.Add(key, new SuppressionStatement(attributeStatement, experimentalOrObsoleteAttribute.Arguments[0], justification)); - } - else if (experimentalOrObsoleteAttribute?.Type.Equals(typeof(ObsoleteAttribute)) == true) - { - string justification = $"{typeProvider.Type} is obsolete and may be removed in future versions."; - attributes.Add(key, new SuppressionStatement(attributeStatement, Literal(DefaultObsoleteDiagnosticId), justification)); - } - else + var suppressions = new List(); + foreach (var attribute in typeProvider.CanonicalView.Attributes) { - attributes.Add(key, attributeStatement); + if (ExperimentalApiHelpers.IsExperimentalAttribute(attribute)) + { + string justification = $"{typeProvider.Type} is experimental and may change in future versions."; + suppressions.Add(new SuppressionStatement(null, attribute.Arguments[0], justification)); + } + else if (attribute.Type.Equals(typeof(ObsoleteAttribute))) + { + string justification = $"{typeProvider.Type} is obsolete and may be removed in future versions."; + suppressions.Add(new SuppressionStatement(null, Literal(DefaultObsoleteDiagnosticId), justification)); + } } + attributes.Add(key, ExperimentalApiHelpers.Suppress(attributeStatement, suppressions)); } private static void AddAttributeForType( @@ -645,6 +643,7 @@ private static void AddAttributeForType( string obsoleteTypeJustification) { var key = frameworkType.FullName ?? frameworkType.Name; + var suppressions = new List(); // Match [Experimental] by attribute type full name rather than runtime identity. Dependencies that // target netstandard2.0 polyfill their own System.Diagnostics.CodeAnalysis.ExperimentalAttribute, @@ -658,8 +657,7 @@ private static void AddAttributeForType( var diagnosticId = experimentalData.ConstructorArguments.Count > 0 ? experimentalData.ConstructorArguments[0].Value as string : null; - attributes.Add(key, new SuppressionStatement(attributeStatement, Literal(diagnosticId), experimentalTypeJustification)); - return; + suppressions.Add(new SuppressionStatement(null, Literal(diagnosticId), experimentalTypeJustification)); } var obsoleteAttr = frameworkType.GetCustomAttributes(typeof(ObsoleteAttribute), false) @@ -668,11 +666,10 @@ private static void AddAttributeForType( { var diagnosticId = obsoleteAttr.GetType().GetProperty("DiagnosticId")?.GetValue(obsoleteAttr) ?? DefaultObsoleteDiagnosticId; - attributes.Add(key, new SuppressionStatement(attributeStatement, Literal(diagnosticId), obsoleteTypeJustification)); - return; + suppressions.Add(new SuppressionStatement(null, Literal(diagnosticId), obsoleteTypeJustification)); } - attributes.Add(key, attributeStatement); + attributes.Add(key, ExperimentalApiHelpers.Suppress(attributeStatement, suppressions)); } /// diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs index 36feabadb45..7e3273c17f1 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs @@ -1159,10 +1159,6 @@ private void ApplyDeprecationAttribute(MethodSignature signature, MethodSignatur { if (customSignature?.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) != true && !signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) - && Client.BackCompatProvider.LastContractView?.Methods.Any(previous => - MethodSignatureHelper.IsPublicApi(previous.Signature) - && MethodSignatureBase.SignatureComparer.Equals(previous.Signature, signature) - && !previous.Signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)) != true && DeprecationApiHelpers.BuildAttribute(ServiceMethod.Operation.Deprecated) is { } attribute) { signature.Update(attributes: [.. signature.Attributes, attribute]); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/ModelReaderWriterContextDefinitionTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/ModelReaderWriterContextDefinitionTests.cs index 3b3b64c4efe..ed4178d5dcd 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/ModelReaderWriterContextDefinitionTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/ModelReaderWriterContextDefinitionTests.cs @@ -612,6 +612,43 @@ public void ExperimentalModelsHaveAttributeSuppression() Assert.AreEqual(Helpers.GetExpectedFromFile(), file.Content); } + [Test] + public async Task ExperimentalDeprecatedModelsHaveAllSuppressions() + { + var generated = InputFactory.Experimental( + InputFactory.Model("GeneratedCombinedModel", deprecation: "Use CurrentModel instead."), + "GENERATED001"); + var customized = InputFactory.Model("CustomCombinedModel"); + await MockHelpers.LoadMockGeneratorAsync( + inputModels: () => [generated, customized, InputFactory.Model("RegularModel")], + compilation: () => Helpers.GetCompilationFromDirectoryAsync()); + var context = new ModelReaderWriterContextDefinition(); + + Assert.AreEqual(3, GetBuildableAttributes(context).Count); + Assert.AreEqual(Helpers.GetExpectedFromFile(), new TypeProviderWriter(context).Write().Content); + Assert.AreEqual(3, context.Attributes.Count); + } + + [Test] + public void ExperimentalObsoleteFrameworkTypesHaveAllSuppressions() + { + var model = InputFactory.Model("ParentModel", properties: + [InputFactory.Property("Value", InputPrimitiveType.String)]); + MockHelpers.LoadMockGenerator(inputModels: () => [model], + createCSharpTypeCore: input => + { +#pragma warning disable FRAMEWORK001, CS0618 + return input == InputPrimitiveType.String + ? new CSharpType(typeof(ExperimentalObsoleteFrameworkType)) + : ScmCodeModelGenerator.Instance.TypeFactory.CreateCSharpType(input)!; +#pragma warning restore FRAMEWORK001, CS0618 + }); + var context = new ModelReaderWriterContextDefinition(); + + Assert.AreEqual(2, context.Attributes.Count); + Assert.AreEqual(Helpers.GetExpectedFromFile(), new TypeProviderWriter(context).Write().Content); + } + [Test] public async Task NullableValueTypesAreHandledCorrectly() { @@ -1423,6 +1460,15 @@ protected internal override PropertyProvider[] BuildProperties() } } + [Experimental("FRAMEWORK001")] + [Obsolete("Use CurrentModel instead.")] + public class ExperimentalObsoleteFrameworkType : IPersistableModel + { + public object Create(BinaryData data, ModelReaderWriterOptions options) => throw new NotImplementedException(); + public string GetFormatFromOptions(ModelReaderWriterOptions options) => throw new NotImplementedException(); + public BinaryData Write(ModelReaderWriterOptions options) => throw new NotImplementedException(); + } + public class FrameworkModelWithMRW : IJsonModel, IPersistableModel { public string Value { get; set; } = string.Empty; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalDeprecatedModelsHaveAllSuppressions.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalDeprecatedModelsHaveAllSuppressions.cs new file mode 100644 index 00000000000..5090a3dd156 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalDeprecatedModelsHaveAllSuppressions.cs @@ -0,0 +1,24 @@ +// + +#nullable disable + +using System.ClientModel.Primitives; +using Sample.Models; + +namespace Sample +{ +#pragma warning disable CS0618 // global::Sample.Models.CustomCombinedModel is obsolete and may be removed in future versions. +#pragma warning disable CUSTOM001 // global::Sample.Models.CustomCombinedModel is experimental and may change in future versions. + [global::System.ClientModel.Primitives.ModelReaderWriterBuildableAttribute(typeof(global::Sample.Models.CustomCombinedModel))] +#pragma warning restore CUSTOM001 // global::Sample.Models.CustomCombinedModel is experimental and may change in future versions. +#pragma warning restore CS0618 // global::Sample.Models.CustomCombinedModel is obsolete and may be removed in future versions. +#pragma warning disable GENERATED001 // global::Sample.Models.GeneratedCombinedModel is experimental and may change in future versions. +#pragma warning disable CS0618 // global::Sample.Models.GeneratedCombinedModel is obsolete and may be removed in future versions. + [global::System.ClientModel.Primitives.ModelReaderWriterBuildableAttribute(typeof(global::Sample.Models.GeneratedCombinedModel))] +#pragma warning restore CS0618 // global::Sample.Models.GeneratedCombinedModel is obsolete and may be removed in future versions. +#pragma warning restore GENERATED001 // global::Sample.Models.GeneratedCombinedModel is experimental and may change in future versions. + [global::System.ClientModel.Primitives.ModelReaderWriterBuildableAttribute(typeof(global::Sample.Models.RegularModel))] + public partial class SampleContext : global::System.ClientModel.Primitives.ModelReaderWriterContext + { + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalDeprecatedModelsHaveAllSuppressions/CustomCombinedModel.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalDeprecatedModelsHaveAllSuppressions/CustomCombinedModel.cs new file mode 100644 index 00000000000..78550fd7dd0 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalDeprecatedModelsHaveAllSuppressions/CustomCombinedModel.cs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Sample.Models +{ + [Obsolete("Use CurrentModel instead.")] + [Experimental("CUSTOM001")] + public partial class CustomCombinedModel + { + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalObsoleteFrameworkTypesHaveAllSuppressions.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalObsoleteFrameworkTypesHaveAllSuppressions.cs new file mode 100644 index 00000000000..65708baf808 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/ExperimentalObsoleteFrameworkTypesHaveAllSuppressions.cs @@ -0,0 +1,20 @@ +// + +#nullable disable + +using System.ClientModel.Primitives; +using Microsoft.TypeSpec.Generator.ClientModel.Tests.Providers.Definitions; +using Sample.Models; + +namespace Sample +{ +#pragma warning disable FRAMEWORK001 // global::Microsoft.TypeSpec.Generator.ClientModel.Tests.Providers.Definitions.ModelReaderWriterContextDefinitionTests.ExperimentalObsoleteFrameworkType is experimental and may change in future versions. +#pragma warning disable CS0618 // global::Microsoft.TypeSpec.Generator.ClientModel.Tests.Providers.Definitions.ModelReaderWriterContextDefinitionTests.ExperimentalObsoleteFrameworkType is obsolete and may be removed in future versions. + [global::System.ClientModel.Primitives.ModelReaderWriterBuildableAttribute(typeof(global::Microsoft.TypeSpec.Generator.ClientModel.Tests.Providers.Definitions.ModelReaderWriterContextDefinitionTests.ExperimentalObsoleteFrameworkType))] +#pragma warning restore CS0618 // global::Microsoft.TypeSpec.Generator.ClientModel.Tests.Providers.Definitions.ModelReaderWriterContextDefinitionTests.ExperimentalObsoleteFrameworkType is obsolete and may be removed in future versions. +#pragma warning restore FRAMEWORK001 // global::Microsoft.TypeSpec.Generator.ClientModel.Tests.Providers.Definitions.ModelReaderWriterContextDefinitionTests.ExperimentalObsoleteFrameworkType is experimental and may change in future versions. + [global::System.ClientModel.Primitives.ModelReaderWriterBuildableAttribute(typeof(global::Sample.Models.ParentModel))] + public partial class SampleContext : global::System.ClientModel.Primitives.ModelReaderWriterContext + { + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs index ce2e5b0b2a5..deea604668d 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs @@ -115,6 +115,44 @@ await MockHelpers.LoadMockGeneratorAsync(clients: () => [inputClient], } } + [Test] + public async Task DeprecationPreservesObsoleteOverloadsBesideStableSignatures() + { + var operation = InputFactory.Operation("Read", deprecated: "Current message", + parameters: + [ + InputFactory.QueryParameter("value", InputPrimitiveType.Int32, isRequired: true), + InputFactory.QueryParameter("added", InputPrimitiveType.Boolean) + ]); + var serviceMethod = InputFactory.BasicServiceMethod("Read", operation, parameters: + [ + InputFactory.MethodParameter("value", InputPrimitiveType.Int32, isRequired: true, location: InputRequestLocation.Query), + InputFactory.MethodParameter("added", InputPrimitiveType.Boolean, location: InputRequestLocation.Query) + ]); + var inputClient = InputFactory.Client("TestClient", methods: [serviceMethod]); + await MockHelpers.LoadMockGeneratorAsync(clients: () => [inputClient], + lastContractCompilation: () => Helpers.GetCompilationFromDirectoryAsync()); + var client = ScmCodeModelGenerator.Instance.TypeFactory.CreateClient(inputClient)!; + client.ProcessTypeForBackCompatibility(); + + Assert.AreEqual(6, client.Methods.Count); + Assert.AreEqual(2, client.Methods.Count(method => method.Signature.Parameters.Count == 2)); + foreach (var method in client.Methods) + { + var obsolete = method.Signature.Attributes.SingleOrDefault(a => a.Type.Equals(typeof(ObsoleteAttribute))); + if (method.Signature.Parameters.Count == 2) + { + Assert.IsNotNull(obsolete, method.Signature.Name); + Assert.AreEqual("\"Current message\"", obsolete!.Arguments.Single().ToDisplayString()); + } + else + { + Assert.AreEqual(3, method.Signature.Parameters.Count); + Assert.IsNull(obsolete, method.Signature.Name); + } + } + } + [TestCase(true)] [TestCase(false)] public void HeadResponseAsBoolReturnsTypedResults(bool responseAsBool) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecationPreservesObsoleteOverloadsBesideStableSignatures/TestClient.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecationPreservesObsoleteOverloadsBesideStableSignatures/TestClient.cs new file mode 100644 index 00000000000..1ca2b9bdb5b --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/DeprecationPreservesObsoleteOverloadsBesideStableSignatures/TestClient.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading; +using System.Threading.Tasks; + +namespace Sample +{ + public class TestClient + { + [Obsolete("Previous message")] + public ClientResult Read(int value, CancellationToken cancellationToken = default) => throw null; + + [Obsolete("Previous message")] + public Task ReadAsync(int value, CancellationToken cancellationToken = default) => throw null; + + [Obsolete("Previous message")] + public ClientResult Read(int value, RequestOptions options) => throw null; + + [Obsolete("Previous message")] + public Task ReadAsync(int value, RequestOptions options) => throw null; + + public ClientResult Read(int value, bool? added = default, CancellationToken cancellationToken = default) => throw null; + + public Task ReadAsync(int value, bool? added = default, CancellationToken cancellationToken = default) => throw null; + + public ClientResult Read(int value, bool? added, RequestOptions options) => throw null; + + public Task ReadAsync(int value, bool? added, RequestOptions options) => throw null; + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Statements/SuppressionStatement.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Statements/SuppressionStatement.cs index ce92824ce5e..f39b404992a 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Statements/SuppressionStatement.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Statements/SuppressionStatement.cs @@ -22,7 +22,8 @@ public SuppressionStatement(MethodBodyStatement? inner, ValueExpression code, st RestoreStatement = new PragmaWarningRestoreStatement(code, justification); } - public T? AsStatement() where T : MethodBodyStatement => Inner as T; + public T? AsStatement() where T : MethodBodyStatement + => Inner as T ?? (Inner as SuppressionStatement)?.AsStatement(); internal override void Write(CodeWriter writer) { diff --git a/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs b/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs index 417e50b8888..f931e589101 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs @@ -84,6 +84,7 @@ public void ModelReaderWriterContextRegistersOnlyPublicModels(string modelName, [TestCase("SampleTypeSpec.PreviewDetails", "SAMPLE0003")] [TestCase("SampleTypeSpec.PreviewChoice", "SAMPLE0004")] [TestCase("SampleTypeSpec.PreviewExtensibleChoice", "SAMPLE0005")] + [TestCase("SampleTypeSpec.LegacyDetails", "SAMPLE0011")] [TestCase("SampleTypeSpec.ExperimentalSamples", "SAMPLE0009")] [TestCase("SampleTypeSpec.LifecycleModel", null)] public void ExperimentalTypeDiagnostics(string typeName, string? diagnosticId) diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/Sample-TypeSpec.tsp b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/Sample-TypeSpec.tsp index 4a5a50f85ff..e0759083ff2 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/Sample-TypeSpec.tsp +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/Sample-TypeSpec.tsp @@ -1133,6 +1133,10 @@ op getAcronymParameters( op setAcronymAddresses(@query ipV4Address: string, @query ipV6Address?: string): void; #deprecated "Use \"CurrentDetails\" instead.\nSee C:\\sdk." +@TypeSpec.HttpClient.experimental(#{ + emitterScope: "@typespec/http-client-csharp", + diagnosticId: "SAMPLE0011", +}) model LegacyDetails { choice: LegacyChoice; extensibleChoice: LegacyExtensibleChoice; diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.RestClient.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.RestClient.cs index 099e5741be9..fcf1f829f4a 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.RestClient.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.RestClient.cs @@ -16,6 +16,7 @@ public partial class DeprecationSamples private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); +#pragma warning disable SAMPLE0011 // This generated code depends on experimental functionality. #pragma warning disable CS0612 // This generated code references obsolete functionality. #pragma warning disable CS0618 // This generated code references obsolete functionality. internal PipelineMessage CreateLegacyRequest(RequestOptions options) @@ -29,6 +30,7 @@ internal PipelineMessage CreateLegacyRequest(RequestOptions options) message.Apply(options); return message; } +#pragma warning restore SAMPLE0011 // This generated code depends on experimental functionality. #pragma warning restore CS0612 // This generated code references obsolete functionality. #pragma warning restore CS0618 // This generated code references obsolete functionality. diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs index df76e478e75..e3975d430ff 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs @@ -46,12 +46,14 @@ internal DeprecationSamples(ClientPipeline pipeline, Uri endpoint) /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// Service returned a non-success status code. /// The response returned from the service. +#pragma warning disable SAMPLE0011 // This generated code depends on experimental functionality. [Obsolete("Use \"read\" instead.\nSee C:\\sdk.")] public virtual ClientResult Legacy(RequestOptions options) { using PipelineMessage message = CreateLegacyRequest(options); return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); } +#pragma warning restore SAMPLE0011 // This generated code depends on experimental functionality. /// /// [Protocol Method] Legacy @@ -64,32 +66,38 @@ public virtual ClientResult Legacy(RequestOptions options) /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// Service returned a non-success status code. /// The response returned from the service. +#pragma warning disable SAMPLE0011 // This generated code depends on experimental functionality. [Obsolete("Use \"read\" instead.\nSee C:\\sdk.")] public virtual async Task LegacyAsync(RequestOptions options) { using PipelineMessage message = CreateLegacyRequest(options); return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } +#pragma warning restore SAMPLE0011 // This generated code depends on experimental functionality. /// Legacy. /// The cancellation token that can be used to cancel the operation. /// Service returned a non-success status code. +#pragma warning disable SAMPLE0011 // This generated code depends on experimental functionality. [Obsolete("Use \"read\" instead.\nSee C:\\sdk.")] public virtual ClientResult Legacy(CancellationToken cancellationToken = default) { ClientResult result = Legacy(cancellationToken.ToRequestOptions()); return ClientResult.FromValue((LegacyDetails)result, result.GetRawResponse()); } +#pragma warning restore SAMPLE0011 // This generated code depends on experimental functionality. /// Legacy. /// The cancellation token that can be used to cancel the operation. /// Service returned a non-success status code. +#pragma warning disable SAMPLE0011 // This generated code depends on experimental functionality. [Obsolete("Use \"read\" instead.\nSee C:\\sdk.")] public virtual async Task> LegacyAsync(CancellationToken cancellationToken = default) { ClientResult result = await LegacyAsync(cancellationToken.ToRequestOptions()).ConfigureAwait(false); return ClientResult.FromValue((LegacyDetails)result, result.GetRawResponse()); } +#pragma warning restore SAMPLE0011 // This generated code depends on experimental functionality. /// /// [Protocol Method] Read diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.Serialization.cs index b5067a47fd8..d2bf503d9de 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.Serialization.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.Serialization.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Text.Json; +#pragma warning disable SAMPLE0011 // This generated code depends on experimental functionality. #pragma warning disable CS0612 // This generated code references obsolete functionality. #pragma warning disable CS0618 // This generated code references obsolete functionality. namespace SampleTypeSpec @@ -166,5 +167,6 @@ internal static CurrentDetails DeserializeCurrentDetails(JsonElement element, Mo } } } +#pragma warning restore SAMPLE0011 // This generated code depends on experimental functionality. #pragma warning restore CS0612 // This generated code references obsolete functionality. #pragma warning restore CS0618 // This generated code references obsolete functionality. diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.cs index 87ecfbe0454..089a56331a9 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/CurrentDetails.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; +#pragma warning disable SAMPLE0011 // This generated code depends on experimental functionality. #pragma warning disable CS0612 // This generated code references obsolete functionality. #pragma warning disable CS0618 // This generated code references obsolete functionality. namespace SampleTypeSpec @@ -37,5 +38,6 @@ internal CurrentDetails(LegacyChoice choice, LegacyExtensibleChoice extensibleCh public IList Previous { get; } } } +#pragma warning restore SAMPLE0011 // This generated code depends on experimental functionality. #pragma warning restore CS0612 // This generated code references obsolete functionality. #pragma warning restore CS0618 // This generated code references obsolete functionality. diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.cs index c9ea9ed544c..b02bcda7f13 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/LegacyDetails.cs @@ -7,10 +7,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace SampleTypeSpec { /// The LegacyDetails. + [Experimental("SAMPLE0011")] [Obsolete("Use \"CurrentDetails\" instead.\nSee C:\\sdk.")] public partial class LegacyDetails { 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 d37e7953c7d..1296cdda53e 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 @@ -22,9 +22,11 @@ namespace SampleTypeSpec [ModelReaderWriterBuildable(typeof(Friend))] [ModelReaderWriterBuildable(typeof(GetNotebookResult))] [ModelReaderWriterBuildable(typeof(GetWidgetMetricsResult))] +#pragma warning disable SAMPLE0011 // global::SampleTypeSpec.LegacyDetails is experimental and may change in future versions. #pragma warning disable CS0618 // global::SampleTypeSpec.LegacyDetails is obsolete and may be removed in future versions. [ModelReaderWriterBuildable(typeof(LegacyDetails))] #pragma warning restore CS0618 // global::SampleTypeSpec.LegacyDetails is obsolete and may be removed in future versions. +#pragma warning restore SAMPLE0011 // global::SampleTypeSpec.LegacyDetails is experimental and may change in future versions. [ModelReaderWriterBuildable(typeof(LifecycleModel))] [ModelReaderWriterBuildable(typeof(ModelWithEmbeddedNonBodyParameters))] [ModelReaderWriterBuildable(typeof(ModelWithRequiredNullableProperties))] 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 5050361f876..ae6856adfeb 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 @@ -559,6 +559,7 @@ public static GetNotebookResult GetNotebookResult(string name = default, string /// A new instance for mocking. #pragma warning disable CS0612 // This generated code references obsolete functionality. #pragma warning disable CS0618 // This generated code references obsolete functionality. + [Experimental("SAMPLE0011")] public static LegacyDetails LegacyDetails(LegacyChoice choice = default, LegacyExtensibleChoice extensibleChoice = default) { return new LegacyDetails(choice, extensibleChoice, additionalBinaryDataProperties: null); @@ -571,6 +572,7 @@ public static LegacyDetails LegacyDetails(LegacyChoice choice = default, LegacyE /// /// /// A new instance for mocking. +#pragma warning disable SAMPLE0011 // This generated code depends on experimental functionality. #pragma warning disable CS0612 // This generated code references obsolete functionality. #pragma warning disable CS0618 // This generated code references obsolete functionality. public static CurrentDetails CurrentDetails(LegacyChoice choice = default, LegacyExtensibleChoice extensibleChoice = default, IEnumerable previous = default) @@ -579,6 +581,7 @@ public static CurrentDetails CurrentDetails(LegacyChoice choice = default, Legac return new CurrentDetails(choice, extensibleChoice, additionalBinaryDataProperties: null, previous.ToList()); } +#pragma warning restore SAMPLE0011 // This generated code depends on experimental functionality. #pragma warning restore CS0612 // This generated code references obsolete functionality. #pragma warning restore CS0618 // This generated code references obsolete functionality. 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 883c0b7a605..091668c699d 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 @@ -9699,7 +9699,11 @@ "isHttpMetadata": false, "isExactName": false } - ] + ], + "experimental": { + "diagnosticId": "SAMPLE0011", + "dependsOn": [] + } }, { "$id": "663", From 6a0f9dccb891d99d9e4c53c1b178a3bc32eda34e Mon Sep 17 00:00:00 2001 From: Josh Love Date: Fri, 23 Oct 2026 19:11:43 -0700 Subject: [PATCH 4/9] fix(http-client-csharp): deduplicate experimental partial attributes Keep custom Experimental and Obsolete attributes on partial declarations through the shared signature builder. Cover non-client block- and expression-bodied methods, and remove the requested emitter documentation changes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- packages/http-client-csharp/docs/emitter.md | 15 --------- .../Providers/ScmMethodProviderCollection.cs | 8 ++--- .../Providers/PartialMethodCustomization.cs | 5 +-- ...odsKeepExperimentalOnDeclaration(False).cs | 24 ++++++++++++++ ...hodsKeepExperimentalOnDeclaration(True).cs | 15 +++++++++ .../Custom.cs | 20 ++++++++++++ .../test/Providers/TypeProviderTests.cs | 31 +++++++++++++++++++ 7 files changed, 95 insertions(+), 23 deletions(-) create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration(False).cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration(True).cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration/Custom.cs diff --git a/packages/http-client-csharp/docs/emitter.md b/packages/http-client-csharp/docs/emitter.md index 73d5d702f22..827da57427a 100644 --- a/packages/http-client-csharp/docs/emitter.md +++ b/packages/http-client-csharp/docs/emitter.md @@ -27,21 +27,6 @@ options: option: value ``` -## Deprecation - -The TypeSpec `#deprecated` directive emits warning-only C# `Obsolete` attributes on -models, enums, and operation methods, including synchronous, asynchronous, protocol, -and convenience methods. The attribute preserves the directive's message. An -`Obsolete` attribute supplied in a custom partial declaration takes precedence. - -When a last released GA contract is available, an API that was not previously -obsolete does not gain an `Obsolete` attribute. Newly added APIs and APIs that were -already obsolete use the current TypeSpec deprecation message. Compatibility -overloads also preserve the published API's non-obsolete status. - -Warnings for references to obsolete APIs are suppressed only within the generated -implementation. Consumers still receive deprecation warnings. - ## Emitter options ### `emitter-output-dir` diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs index 7e3273c17f1..1cffb854726 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs @@ -1144,12 +1144,8 @@ private static void ApplyExperimentalAttributes( MethodSignature? customSignature, IReadOnlyList generatedAttributes) { - if (customSignature?.Attributes.Any(ExperimentalApiHelpers.IsExperimentalAttribute) == true) - { - // The defining partial declaration already carries the custom experiment. - signature.Update(attributes: [.. signature.Attributes.Where(a => !ExperimentalApiHelpers.IsExperimentalAttribute(a))]); - } - else if (generatedAttributes.Count > 0) + if (customSignature?.Attributes.Any(ExperimentalApiHelpers.IsExperimentalAttribute) != true + && generatedAttributes.Count > 0) { signature.Update(attributes: [.. signature.Attributes, .. generatedAttributes]); } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PartialMethodCustomization.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PartialMethodCustomization.cs index 07b9636bbee..7125cd9c4bc 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PartialMethodCustomization.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/PartialMethodCustomization.cs @@ -164,7 +164,7 @@ public static IReadOnlyList RenameAndCloneParameters( /// (modifiers, name, return type, attributes, and /// other signature metadata) and the supplied . /// The result has applied. - /// Custom obsolete attributes remain on the defining declaration to avoid duplicate attributes. + /// Custom experimental and obsolete attributes remain on the defining declaration to avoid duplicate attributes. /// /// The customer's partial declaration signature. /// The parameters to use for the implementation. @@ -206,7 +206,8 @@ public static MethodSignature BuildPartialSignature( returnType ?? customSignature.ReturnType, customSignature.ReturnDescription, implementationParameters, - [.. customSignature.Attributes.Where(attribute => !DeprecationApiHelpers.IsObsoleteAttribute(attribute))], + [.. customSignature.Attributes.Where(attribute => !ExperimentalApiHelpers.IsExperimentalAttribute(attribute) + && !DeprecationApiHelpers.IsObsoleteAttribute(attribute))], customSignature.GenericArguments, customSignature.GenericParameterConstraints, customSignature.ExplicitInterface, diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration(False).cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration(False).cs new file mode 100644 index 00000000000..6b895cea9b1 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration(False).cs @@ -0,0 +1,24 @@ +// + +#nullable disable + +namespace Test +{ + public partial class CustomPartialMethodType + { + public partial int Preview() + { + return 1; + } + + public partial int Combined() + { + return 1; + } + + public partial int Current() + { + return 1; + } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration(True).cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration(True).cs new file mode 100644 index 00000000000..fcf6be899d9 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration(True).cs @@ -0,0 +1,15 @@ +// + +#nullable disable + +namespace Test +{ + public partial class CustomPartialMethodType + { + public partial int Preview() => 1; + + public partial int Combined() => 1; + + public partial int Current() => 1; + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration/Custom.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration/Custom.cs new file mode 100644 index 00000000000..80b03d66c32 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomPartialMethodsKeepExperimentalOnDeclaration/Custom.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Test +{ + public partial class CustomPartialMethodType + { + [Experimental("CUSTOM001")] + public partial int Preview(); + + [Experimental("CUSTOM001")] + [Obsolete("Custom message")] + public partial int Combined(); + + public partial int Current(); + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs index 7fe5835a710..a70674f0d72 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs @@ -2205,6 +2205,37 @@ public async Task CustomPartialMethodsKeepObsoleteOnDeclaration(bool expressionB Assert.AreEqual(Helpers.GetExpectedFromFile(expressionBody.ToString()), new TypeProviderWriter(typeProvider).Write().Content); } + [TestCase(false)] + [TestCase(true)] + public async Task CustomPartialMethodsKeepExperimentalOnDeclaration(bool expressionBody) + { + await MockHelpers.LoadMockGeneratorAsync(compilation: () => Helpers.GetCompilationFromDirectoryAsync()); + var typeProvider = new TestTypeProvider(name: "CustomPartialMethodType"); + var methods = new[] { "Preview", "Combined", "Current" }.Select(name => + { + var signature = new MethodSignature(name, null, MethodSignatureModifiers.Public, typeof(int), null, []); + return expressionBody + ? new MethodProvider(signature, Snippet.Literal(1), typeProvider) + : new MethodProvider(signature, Snippet.Return(Snippet.Literal(1)), typeProvider); + }); + typeProvider.Update(methods: methods); + + Assert.AreEqual(3, typeProvider.Methods.Count); + Assert.IsTrue(typeProvider.Methods.All(method => method.IsPartialMethod)); + Assert.IsTrue(typeProvider.Methods.All(method => method.Signature.Attributes.Count == 0)); + var customMethods = typeProvider.CustomCodeView!.Methods; + foreach (var method in customMethods.Where(method => method.Signature.Name != "Current")) + { + Assert.AreEqual("\"CUSTOM001\"", + method.Signature.Attributes.Single(ExperimentalApiHelpers.IsExperimentalAttribute).Arguments.Single().ToDisplayString()); + } + Assert.AreEqual("\"Custom message\"", + customMethods.Single(method => method.Signature.Name == "Combined").Signature.Attributes + .Single(DeprecationApiHelpers.IsObsoleteAttribute).Arguments.Single().ToDisplayString()); + Assert.IsEmpty(customMethods.Single(method => method.Signature.Name == "Current").Signature.Attributes); + Assert.AreEqual(Helpers.GetExpectedFromFile(expressionBody.ToString()), new TypeProviderWriter(typeProvider).Write().Content); + } + [Test] public async Task TestSpecViewReturnsAllPropertiesEvenWhenSuppressed() { From 96f0a6e35c3d167a12f19cf562be575c638f44d4 Mon Sep 17 00:00:00 2001 From: Josh Love Date: Fri, 23 Oct 2026 20:11:30 -0700 Subject: [PATCH 5/9] fix(http-client-csharp): refresh deprecation after type identity updates Re-evaluate generated obsolete metadata after visitor renames and namespace changes while preserving visitor-added attributes and explicit removals. Prevent stale attribute snapshots from restoring obsolete warnings on non-obsolete GA types. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../src/Providers/TypeProvider.cs | 55 +++++++-- ...ntityUpdatesAreReflectedInGeneratedCode.cs | 14 +++ .../test/Providers/TypeProviderTests.cs | 104 ++++++++++++++++++ 3 files changed, 164 insertions(+), 9 deletions(-) create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationIdentityUpdatesAreReflectedInGeneratedCode.cs diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs index 818f2f0a726..bb57ab4230a 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs @@ -396,8 +396,9 @@ private IReadOnlyList ApplyCustomizationFilter(IEnumerable? _attributes; - // Snapshot of the attributes as they were before the first Update call + // Snapshot before visitor updates, used to distinguish generated attributes from visitor changes. private HashSet? _originalAttributes; + private AttributeStatement? _generatedDeprecationAttribute; public IReadOnlyList Attributes { @@ -769,16 +770,50 @@ protected virtual IReadOnlyList BuildAttributes() { attributes.Add(attribute); } - var obsoleteAttribute = DeprecationApiHelpers.BuildAttribute(Deprecated); - if (obsoleteAttribute is not null - && CustomCodeView?.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) != true - && (LastContractView is null || LastContractView.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute))) + _generatedDeprecationAttribute ??= DeprecationApiHelpers.BuildAttribute(Deprecated); + if (_generatedDeprecationAttribute is not null && ShouldEmitDeprecationAttribute()) { - attributes.Add(obsoleteAttribute); + attributes.Add(_generatedDeprecationAttribute); } return attributes; } + private bool ShouldEmitDeprecationAttribute() + => CustomCodeView?.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) != true + && (LastContractView is null || LastContractView.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)); + + private void RefreshGeneratedDeprecationAttribute() + { + if (_attributes is null || _generatedDeprecationAttribute is not { } attribute) + { + return; + } + bool included = _attributes.Contains(attribute); + if (!included && _originalAttributes?.Contains(attribute) == true) + { + // A visitor explicitly removed or replaced the generated attribute. + return; + } + bool shouldInclude = ShouldEmitDeprecationAttribute() + && !_attributes.OfType().Any(a => + !ReferenceEquals(a, attribute) && DeprecationApiHelpers.IsObsoleteAttribute(a)); + if (included == shouldInclude) + { + return; + } + _attributes = shouldInclude + ? [.. _attributes, attribute] + : [.. _attributes.Where(a => !ReferenceEquals(a, attribute))]; + if (shouldInclude) + { + _originalAttributes?.Add(attribute); + } + else + { + _originalAttributes?.Remove(attribute); + } + } + private CSharpType? _enumUnderlyingType; public CSharpType EnumUnderlyingType => _enumUnderlyingType ??= BuildEnumUnderlyingType(); // Each member in the EnumProvider has to have this type @@ -869,6 +904,7 @@ public virtual void Reset() _enumUnderlyingType = null; _attributes = null; _originalAttributes = null; + _generatedDeprecationAttribute = null; _deprecated = null; _description = null; _type = null; @@ -960,9 +996,8 @@ public void Update( } if (attributes != null) { - // For providers whose generated attributes are rebuilt at write time, remember the attributes - // as they were before the first update so GetAttributesForWrite can preserve the additions. - if (!ShouldAnalyzeAttributesInReferenceMap) + // Preserve visitor changes when generated attributes are refreshed after identity changes or at write time. + if (!ShouldAnalyzeAttributesInReferenceMap || Deprecated is not null) { _originalAttributes ??= [.. Attributes]; } @@ -979,6 +1014,8 @@ public void Update( ResetMembersBasedOnIdentityChange(@namespace: @namespace); } + RefreshGeneratedDeprecationAttribute(); + // Rebuild the canonical view _canonicalView = new(BuildCanonicalView); } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationIdentityUpdatesAreReflectedInGeneratedCode.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationIdentityUpdatesAreReflectedInGeneratedCode.cs new file mode 100644 index 00000000000..873bf6e64f5 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/DeprecationIdentityUpdatesAreReflectedInGeneratedCode.cs @@ -0,0 +1,14 @@ +// + +#nullable disable + +using System; + +namespace Sample.Models +{ + [global::System.SerializableAttribute] + public enum StableEnum + { + One + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs index a70674f0d72..803a19e7d2e 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs @@ -94,6 +94,110 @@ public async Task DeprecationPreservesLastContract(string name, string kind, boo Assert.AreEqual(obsolete, provider.Attributes.Any(a => a.Type.Equals(typeof(ObsoleteAttribute)))); } + [Test] + public async Task DeprecationFollowsUpdatedTypeIdentity( + [Values("model", "fixed", "extensible")] string kind, + [Values] bool changeNamespace, + [Values] bool initiallyPublished) + { + await MockHelpers.LoadMockGeneratorAsync( + lastContractCompilation: () => Helpers.GetCompilationFromDirectoryAsync(method: nameof(DeprecationPreservesLastContract))); + var publishedName = kind switch + { + "model" => "StableModel", + "fixed" => "StableEnum", + _ => "StableChoice" + }; + var initialName = changeNamespace || initiallyPublished ? publishedName : "Unpublished"; + var initialNamespace = changeNamespace && !initiallyPublished ? "Unpublished" : "Sample.Models"; + TypeProvider provider = kind == "model" + ? CodeModelGenerator.Instance.TypeFactory.CreateModel(InputFactory.Model(initialName, + @namespace: initialNamespace, deprecation: "Current message"))! + : CodeModelGenerator.Instance.TypeFactory.CreateEnum(InputFactory.StringEnum(initialName, + [("One", "one")], clientNamespace: initialNamespace, isExtensible: kind == "extensible", deprecation: "Current message"))!; + Assert.AreEqual(!initiallyPublished, provider.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)); + var visitorAttribute = new AttributeStatement(typeof(SerializableAttribute)); + + provider.Update( + attributes: [.. provider.Attributes, visitorAttribute], + name: changeNamespace ? null : initiallyPublished ? "Unpublished" : publishedName, + @namespace: changeNamespace ? initiallyPublished ? "Unpublished" : "Sample.Models" : null); + Assert.AreEqual(initiallyPublished, provider.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)); + Assert.AreSame(visitorAttribute, provider.Attributes.Single(a => a.Type.Equals(typeof(SerializableAttribute)))); + Assert.AreEqual(initiallyPublished, provider.CanonicalView.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)); + Assert.AreEqual(initiallyPublished, + provider.GetAttributesForWrite().OfType().Any(DeprecationApiHelpers.IsObsoleteAttribute)); + + provider.Update(name: initialName, @namespace: initialNamespace); + provider.ProcessTypeForBackCompatibility(); + Assert.AreEqual(!initiallyPublished, provider.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)); + Assert.AreSame(visitorAttribute, provider.Attributes.Single(a => a.Type.Equals(typeof(SerializableAttribute)))); + } + + [TestCase(false)] + [TestCase(true)] + public async Task DeprecationIdentityUpdatesPreserveVisitorAttributeOverrides(bool replaceObsolete) + { + await MockHelpers.LoadMockGeneratorAsync( + lastContractCompilation: () => Helpers.GetCompilationFromDirectoryAsync(method: nameof(DeprecationPreservesLastContract))); + var provider = CodeModelGenerator.Instance.TypeFactory.CreateModel( + InputFactory.Model("Unpublished", deprecation: "Generated message"))!; + Assert.IsTrue(provider.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)); + var visitorAttribute = replaceObsolete + ? new AttributeStatement(typeof(ObsoleteAttribute), [Snippet.Literal("Visitor message")]) + : new AttributeStatement(typeof(SerializableAttribute)); + provider.Update(attributes: [visitorAttribute]); + provider.Update(name: "StableModel"); + provider.Update(name: "UnpublishedAgain"); + + Assert.AreSame(visitorAttribute, provider.Attributes.Single()); + } + + [Test] + public async Task DeprecationIdentityUpdatesHonorCustomAttributes() + { + var input = InputFactory.Model("Unpublished", deprecation: "Generated message"); + await MockHelpers.LoadMockGeneratorAsync(inputModelTypes: [input], + compilation: () => Helpers.GetCompilationFromDirectoryAsync(method: nameof(DeprecatedCustomModelKeepsExistingAttribute))); + var provider = CodeModelGenerator.Instance.TypeFactory.CreateModel(input)!; + Assert.IsTrue(provider.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)); + + provider.Update(name: "Legacy"); + + Assert.IsFalse(provider.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)); + Assert.AreEqual("\"Custom message\"", + provider.CanonicalView.Attributes.Single(DeprecationApiHelpers.IsObsoleteAttribute).Arguments.Single().ToDisplayString()); + } + + [Test] + public async Task DeprecationIdentityUpdatesAreReflectedInGeneratedCode() + { + await MockHelpers.LoadMockGeneratorAsync( + lastContractCompilation: () => Helpers.GetCompilationFromDirectoryAsync(method: nameof(DeprecationPreservesLastContract))); + var provider = CodeModelGenerator.Instance.TypeFactory.CreateEnum( + InputFactory.StringEnum("Unpublished", [("One", "one")], deprecation: "Generated message"))!; + provider.Update(attributes: [.. provider.Attributes, new AttributeStatement(typeof(SerializableAttribute))]); + provider.Update(name: "StableEnum"); + provider.ProcessTypeForBackCompatibility(); + + Assert.AreEqual(Helpers.GetExpectedFromFile(), new TypeProviderWriter(provider).Write().Content); + } + + [Test] + public async Task DeprecationIdentityUpdatesIgnoreStaleAttributeSnapshots() + { + await MockHelpers.LoadMockGeneratorAsync( + lastContractCompilation: () => Helpers.GetCompilationFromDirectoryAsync(method: nameof(DeprecationPreservesLastContract))); + var provider = CodeModelGenerator.Instance.TypeFactory.CreateModel( + InputFactory.Model("Unpublished", deprecation: "Generated message"))!; + var originalAttributes = provider.Attributes; + provider.Update(name: "StableModel"); + var visitorAttribute = new AttributeStatement(typeof(SerializableAttribute)); + provider.Update(attributes: [.. originalAttributes, visitorAttribute]); + + Assert.AreSame(visitorAttribute, provider.Attributes.Single()); + } + [TestCase(false)] [TestCase(true)] public async Task DeprecationPreservesBackCompatOverloads(bool previouslyObsolete) From 7f98cebe187afe1daa122a128969ba1bdabc95a6 Mon Sep 17 00:00:00 2001 From: Josh Love Date: Fri, 23 Oct 2026 21:09:42 -0700 Subject: [PATCH 6/9] fix(http-client-csharp): preserve custom obsolete diagnostic IDs Read named Obsolete DiagnosticId values for generated reference and context suppressions. Preserve custom diagnostics in compatibility forwarding and cover model/enum references, deserialization output, defaults, and invalid identifiers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../ModelReaderWriterContextDefinition.cs | 3 +- .../Providers/ScmMethodProviderCollection.cs | 5 +- ...ModelReaderWriterContextDefinitionTests.cs | 13 +++++ ...ustomObsoleteDiagnosticIdsAreSuppressed.cs | 17 ++++++ .../CustomizedObsoleteModel.cs | 12 ++++ .../MrwSerializationTypeDefinitionTests.cs | 18 ++++++ ...ReferencesHonorCustomObsoleteDiagnostic.cs | 28 +++++++++ .../Legacy.cs | 12 ++++ .../src/Shared/DeprecationApiHelpers.cs | 36 ++++++++++-- .../src/Shared/ExperimentalApiHelpers.cs | 13 +++-- .../src/Utilities/BackCompatHelper.cs | 2 +- .../Custom.cs | 17 ++++++ .../test/Providers/TypeProviderTests.cs | 58 +++++++++++++++++-- 13 files changed, 214 insertions(+), 20 deletions(-) create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/CustomObsoleteDiagnosticIdsAreSuppressed.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/CustomObsoleteDiagnosticIdsAreSuppressed/CustomizedObsoleteModel.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/MrwSerializationTypeDefinitionTests/SerializationReferencesHonorCustomObsoleteDiagnostic.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/MrwSerializationTypeDefinitionTests/SerializationReferencesHonorCustomObsoleteDiagnostic/Legacy.cs create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomObsoleteTypeReferencesUseDiagnosticId/Custom.cs diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelReaderWriterContextDefinition.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelReaderWriterContextDefinition.cs index 618143591ad..33df5e401d0 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelReaderWriterContextDefinition.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelReaderWriterContextDefinition.cs @@ -629,7 +629,8 @@ private static void AddAttributeForType( else if (attribute.Type.Equals(typeof(ObsoleteAttribute))) { string justification = $"{typeProvider.Type} is obsolete and may be removed in future versions."; - suppressions.Add(new SuppressionStatement(null, Literal(DefaultObsoleteDiagnosticId), justification)); + suppressions.Add(new SuppressionStatement(null, + Literal(DeprecationApiHelpers.GetDiagnosticId(attribute) ?? DefaultObsoleteDiagnosticId), justification)); } } attributes.Add(key, ExperimentalApiHelpers.Suppress(attributeStatement, suppressions)); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs index 1cffb854726..11268051f11 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs @@ -300,10 +300,11 @@ .. GetStackVariablesForReturnValueConversion(result, responseBodyType, isAsync, var convenienceMethod = new ScmMethodProvider(methodSignature, methodBody, EnclosingType, ScmMethodKind.Convenience, collectionDefinition: collection, serviceMethod: ServiceMethod); ExperimentalApiHelpers.AddDependencySuppressions(convenienceMethod, ServiceMethod.Operation); - if (protocolMethod.Signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute)) + var obsoleteProtocol = protocolMethod.Signature.Attributes.FirstOrDefault(DeprecationApiHelpers.IsObsoleteAttribute); + if (obsoleteProtocol is not null) { convenienceMethod.Update(suppressions: ExperimentalApiHelpers.MergeSuppressions( - convenienceMethod.Suppressions, DeprecationApiHelpers.GetSuppressions())); + convenienceMethod.Suppressions, DeprecationApiHelpers.GetSuppressions(obsoleteProtocol))); } if (convenienceMethod.XmlDocs != null) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/ModelReaderWriterContextDefinitionTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/ModelReaderWriterContextDefinitionTests.cs index ed4178d5dcd..969c477734f 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/ModelReaderWriterContextDefinitionTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/ModelReaderWriterContextDefinitionTests.cs @@ -1253,6 +1253,19 @@ public async Task ValidateCustomObsoleteTypeHasAttributeSuppression() Assert.AreEqual(Helpers.GetExpectedFromFile(), file.Content); } + [Test] + public async Task CustomObsoleteDiagnosticIdsAreSuppressed() + { + var model = InputFactory.Model("CustomizedObsoleteModel", deprecation: "Generated message"); + await MockHelpers.LoadMockGeneratorAsync( + inputModels: () => [model, InputFactory.Model("RegularModel")], + compilation: () => Helpers.GetCompilationFromDirectoryAsync()); + var context = new ModelReaderWriterContextDefinition(); + + Assert.AreEqual(2, context.Attributes.Count); + Assert.AreEqual(Helpers.GetExpectedFromFile(), new TypeProviderWriter(context).Write().Content); + } + [Test] public void ValidateObsoleteGeneratedTypeHasAttributeSuppression() { diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/CustomObsoleteDiagnosticIdsAreSuppressed.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/CustomObsoleteDiagnosticIdsAreSuppressed.cs new file mode 100644 index 00000000000..97e9c21cba9 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/CustomObsoleteDiagnosticIdsAreSuppressed.cs @@ -0,0 +1,17 @@ +// + +#nullable disable + +using System.ClientModel.Primitives; +using Sample.Models; + +namespace Sample +{ +#pragma warning disable OBS001 // global::Sample.Models.CustomizedObsoleteModel is obsolete and may be removed in future versions. + [global::System.ClientModel.Primitives.ModelReaderWriterBuildableAttribute(typeof(global::Sample.Models.CustomizedObsoleteModel))] +#pragma warning restore OBS001 // global::Sample.Models.CustomizedObsoleteModel is obsolete and may be removed in future versions. + [global::System.ClientModel.Primitives.ModelReaderWriterBuildableAttribute(typeof(global::Sample.Models.RegularModel))] + public partial class SampleContext : global::System.ClientModel.Primitives.ModelReaderWriterContext + { + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/CustomObsoleteDiagnosticIdsAreSuppressed/CustomizedObsoleteModel.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/CustomObsoleteDiagnosticIdsAreSuppressed/CustomizedObsoleteModel.cs new file mode 100644 index 00000000000..6349c96d118 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/Definitions/TestData/ModelReaderWriterContextDefinitionTests/CustomObsoleteDiagnosticIdsAreSuppressed/CustomizedObsoleteModel.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Sample.Models +{ + [Obsolete("Use Current instead.", DiagnosticId = "OBS001")] + public partial class CustomizedObsoleteModel + { + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/MrwSerializationTypeDefinitionTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/MrwSerializationTypeDefinitionTests.cs index 800a7b3e4de..b3136c4a1a4 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/MrwSerializationTypeDefinitionTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/MrwSerializationTypeDefinitionTests.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.Json; +using System.Threading.Tasks; using Microsoft.TypeSpec.Generator.ClientModel.Providers; using Microsoft.TypeSpec.Generator.Expressions; using Microsoft.TypeSpec.Generator.Input; @@ -64,6 +65,23 @@ public void TestBuildImplements() Assert.That(interfaces.Any(i => i.Equals(expectedJsonModelTInterface))); } + [Test] + public async Task SerializationReferencesHonorCustomObsoleteDiagnostic() + { + var legacy = InputFactory.Model("Legacy"); + var envelope = InputFactory.Model("Envelope", properties: + [InputFactory.Property("legacy", legacy)]); + await MockHelpers.LoadMockGeneratorAsync(inputModels: () => [legacy, envelope], + compilation: () => Helpers.GetCompilationFromDirectoryAsync()); + var model = ScmCodeModelGenerator.Instance.TypeFactory.CreateModel(envelope)!; + var serialization = model.SerializationProviders.OfType().Single(); + var method = serialization.Methods.Single(method => method.Signature.Name == "DeserializeEnvelope"); + using var writer = new CodeWriter(); + writer.WriteMethod(method); + + Assert.AreEqual(Helpers.GetExpectedFromFile(), writer.ToString(false)); + } + [TestCase(false, false, false)] [TestCase(true, false, false)] [TestCase(true, true, true)] diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/MrwSerializationTypeDefinitionTests/SerializationReferencesHonorCustomObsoleteDiagnostic.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/MrwSerializationTypeDefinitionTests/SerializationReferencesHonorCustomObsoleteDiagnostic.cs new file mode 100644 index 00000000000..a34972d94f2 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/MrwSerializationTypeDefinitionTests/SerializationReferencesHonorCustomObsoleteDiagnostic.cs @@ -0,0 +1,28 @@ +#pragma warning disable OBS001 // This generated code references obsolete functionality. +internal static global::Sample.Models.Envelope DeserializeEnvelope(global::System.Text.Json.JsonElement element, global::System.ClientModel.Primitives.ModelReaderWriterOptions options) +{ + if ((element.ValueKind == global::System.Text.Json.JsonValueKind.Null)) + { + return null; + } + global::Sample.Models.Legacy legacy = default; + global::System.Collections.Generic.IDictionary additionalBinaryDataProperties = new global::Sample.ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("legacy"u8)) + { + if ((prop.Value.ValueKind == global::System.Text.Json.JsonValueKind.Null)) + { + continue; + } + legacy = global::Sample.Models.Legacy.DeserializeLegacy(prop.Value, options); + continue; + } + if ((options.Format != "W")) + { + additionalBinaryDataProperties.Add(prop.Name, prop.Value.GetUtf8Bytes()); + } + } + return new global::Sample.Models.Envelope(legacy, additionalBinaryDataProperties); +} +#pragma warning restore OBS001 // This generated code references obsolete functionality. diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/MrwSerializationTypeDefinitionTests/SerializationReferencesHonorCustomObsoleteDiagnostic/Legacy.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/MrwSerializationTypeDefinitionTests/SerializationReferencesHonorCustomObsoleteDiagnostic/Legacy.cs new file mode 100644 index 00000000000..78be384a5e1 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/MrwSerializationTypeDefinitionTests/SerializationReferencesHonorCustomObsoleteDiagnostic/Legacy.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Sample.Models +{ + [Obsolete("Use Current instead.", DiagnosticId = "OBS001")] + public partial class Legacy + { + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/DeprecationApiHelpers.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/DeprecationApiHelpers.cs index 05e41f8c90e..d0de65dcc5d 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/DeprecationApiHelpers.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/DeprecationApiHelpers.cs @@ -2,6 +2,9 @@ // Licensed under the MIT License. using System; +using System.Linq; +using Microsoft.TypeSpec.Generator.Expressions; +using Microsoft.TypeSpec.Generator.Snippets; using Microsoft.TypeSpec.Generator.Statements; using static Microsoft.TypeSpec.Generator.Snippets.Snippet; @@ -15,11 +18,32 @@ public static bool IsObsoleteAttribute(AttributeStatement attribute) public static AttributeStatement? BuildAttribute(string? message) => message is null ? null : new AttributeStatement(typeof(ObsoleteAttribute), [Literal(message)]); - public static SuppressionStatement[] GetSuppressions() - => - [ - new(null, Literal("CS0612"), "This generated code references obsolete functionality."), - new(null, Literal("CS0618"), "This generated code references obsolete functionality.") - ]; + public static string? GetDiagnosticId(AttributeStatement attribute) + { + var value = attribute.PositionalArguments.FirstOrDefault(argument => argument.Key == nameof(ObsoleteAttribute.DiagnosticId)).Value; + while (value is ScopedApi scoped) + { + value = scoped.Original; + } + if (value is null or LiteralExpression { Literal: null or "" } or KeywordExpression { Keyword: "null" }) + { + return null; + } + if (value is not LiteralExpression { Literal: string diagnosticId }) + { + throw new InvalidOperationException("Obsolete diagnostic IDs must be constant strings."); + } + ExperimentalApiHelpers.ValidateDiagnosticId(diagnosticId); + return diagnosticId; + } + + public static SuppressionStatement[] GetSuppressions(AttributeStatement? attribute = null) + => attribute is not null && GetDiagnosticId(attribute) is { } diagnosticId + ? [new(null, Literal(diagnosticId), "This generated code references obsolete functionality.")] + : + [ + new(null, Literal("CS0612"), "This generated code references obsolete functionality."), + new(null, Literal("CS0618"), "This generated code references obsolete functionality.") + ]; } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/ExperimentalApiHelpers.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/ExperimentalApiHelpers.cs index 07a75d50a06..f12c65f46db 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/ExperimentalApiHelpers.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/ExperimentalApiHelpers.cs @@ -92,10 +92,13 @@ public static SuppressionStatement[] GetReferenceSuppressions(CSharpType? type) public static SuppressionStatement[] GetAttributeSuppressions(IEnumerable attributes) { var ids = new List(); - bool obsolete = false; + var obsoleteSuppressions = new List(); foreach (var attribute in attributes) { - obsolete |= DeprecationApiHelpers.IsObsoleteAttribute(attribute); + if (DeprecationApiHelpers.IsObsoleteAttribute(attribute)) + { + obsoleteSuppressions.AddRange(DeprecationApiHelpers.GetSuppressions(attribute)); + } if (!IsExperimentalAttribute(attribute)) { continue; @@ -111,7 +114,7 @@ public static SuppressionStatement[] GetAttributeSuppressions(IEnumerable dia return new SuppressionStatement(null, Literal(id), "This generated code depends on experimental functionality."); })]; - private static void ValidateDiagnosticId(string diagnosticId) + internal static void ValidateDiagnosticId(string diagnosticId) { if (!Regex.IsMatch(diagnosticId, @"\A(?:[A-Za-z_][A-Za-z0-9_]*|[0-9]+)\z", RegexOptions.CultureInvariant)) { - throw new ArgumentException("Experimental diagnostic IDs must be single C# warning identifiers or decimal warning numbers.", nameof(diagnosticId)); + throw new ArgumentException("Diagnostic IDs must be single C# warning identifiers or decimal warning numbers.", nameof(diagnosticId)); } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs index 89cb738d9c3..48d4674140e 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/BackCompatHelper.cs @@ -543,7 +543,7 @@ .. overload.Signature.Attributes.Where(a => !ExperimentalApiHelpers.IsExperiment .. obsolete is not null && previousMethod.Signature.Attributes.Any(DeprecationApiHelpers.IsObsoleteAttribute) ? new[] { obsolete } : [] ]); overload.Update(suppressions: ExperimentalApiHelpers.MergeSuppressions(overload.Suppressions, currentMethod.Suppressions, - obsolete is null ? [] : DeprecationApiHelpers.GetSuppressions())); + obsolete is null ? [] : DeprecationApiHelpers.GetSuppressions(obsolete))); } // Returns true when both signatures have the same return type (matched by name); a null return type diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomObsoleteTypeReferencesUseDiagnosticId/Custom.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomObsoleteTypeReferencesUseDiagnosticId/Custom.cs new file mode 100644 index 00000000000..9b6da4c6dc9 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TestData/TypeProviderTests/CustomObsoleteTypeReferencesUseDiagnosticId/Custom.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Sample.Models +{ + [Obsolete("Use Current instead.", DiagnosticId = "OBS001")] + public partial class Legacy + { + } + + [Obsolete("Use CurrentChoice instead.", DiagnosticId = "OBS001")] + public readonly partial struct LegacyChoice + { + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs index 803a19e7d2e..175896f345a 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/TypeProviderTests.cs @@ -74,6 +74,51 @@ await MockHelpers.LoadMockGeneratorAsync(inputModelTypes: [model], Assert.AreEqual("\"Custom message\"", provider.CustomCodeView!.Attributes.Single().Arguments.Single().ToDisplayString()); } + [TestCase(null)] + [TestCase("")] + [TestCase("OBS001")] + public void CustomObsoleteDiagnosticsArePreserved(string? diagnosticId) + { + var attribute = new AttributeStatement(typeof(ObsoleteAttribute), [Snippet.Literal("Custom message")], + [new(nameof(ObsoleteAttribute.DiagnosticId), Snippet.Literal(diagnosticId))]); + var suppressions = ExperimentalApiHelpers.GetAttributeSuppressions([attribute, attribute]); + + CollectionAssert.AreEqual( + (string.IsNullOrEmpty(diagnosticId) ? new[] { "CS0612", "CS0618" } : [diagnosticId]) + .Select(id => Snippet.Literal(id).ToDisplayString()), + suppressions.Select(suppression => suppression.Code.ToDisplayString())); + } + + [TestCase("OBS,001")] + [TestCase("OBS\n#pragma warning disable")] + public void CustomObsoleteDiagnosticsRejectInvalidWarningIdentifiers(string diagnosticId) + { + var attribute = new AttributeStatement(typeof(ObsoleteAttribute), [], + [new(nameof(ObsoleteAttribute.DiagnosticId), Snippet.Literal(diagnosticId))]); + + Assert.Throws(() => ExperimentalApiHelpers.GetAttributeSuppressions([attribute])); + } + + [TestCase("model")] + [TestCase("enum")] + [TestCase("collection")] + public async Task CustomObsoleteTypeReferencesUseDiagnosticId(string shape) + { + var model = InputFactory.Model("Legacy", deprecation: "Generated message"); + var choice = InputFactory.StringEnum("LegacyChoice", [("One", "one")], isExtensible: true); + await MockHelpers.LoadMockGeneratorAsync(inputModelTypes: [model], inputEnumTypes: [choice], + compilation: () => Helpers.GetCompilationFromDirectoryAsync()); + var factory = CodeModelGenerator.Instance.TypeFactory; + var type = shape == "enum" ? factory.CreateEnum(choice)!.Type : factory.CreateModel(model)!.Type; + if (shape == "collection") + { + type = new CSharpType(typeof(IReadOnlyList<>), type); + } + + CollectionAssert.AreEqual(new[] { "\"OBS001\"" }, + ExperimentalApiHelpers.GetReferenceSuppressions(type).Select(suppression => suppression.Code.ToDisplayString())); + } + [TestCase("StableModel", "model", false)] [TestCase("ObsoleteModel", "model", true)] [TestCase("PreviewModel", "model", true)] @@ -198,9 +243,11 @@ await MockHelpers.LoadMockGeneratorAsync( Assert.AreSame(visitorAttribute, provider.Attributes.Single()); } - [TestCase(false)] - [TestCase(true)] - public async Task DeprecationPreservesBackCompatOverloads(bool previouslyObsolete) + [TestCase(false, null)] + [TestCase(true, null)] + [TestCase(false, "OBS001")] + [TestCase(true, "OBS001")] + public async Task DeprecationPreservesBackCompatOverloads(bool previouslyObsolete, string? diagnosticId) { await MockHelpers.LoadMockGeneratorAsync(lastContractCompilation: () => Helpers.GetCompilationFromDirectoryAsync()); var provider = new TestTypeProvider(name: previouslyObsolete ? "ObsoleteClient" : "LegacyClient", ns: "Sample"); @@ -210,7 +257,8 @@ public async Task DeprecationPreservesBackCompatOverloads(bool previouslyObsolet new ParameterProvider("value", $"", typeof(int)), new ParameterProvider("added", $"", typeof(bool), defaultValue: Snippet.Default, location: ParameterLocation.Query) ], - Attributes: [new AttributeStatement(typeof(ObsoleteAttribute), [Snippet.Literal("Current message")])]), + Attributes: [new AttributeStatement(typeof(ObsoleteAttribute), [Snippet.Literal("Current message")], + diagnosticId is null ? [] : [new(nameof(ObsoleteAttribute.DiagnosticId), Snippet.Literal(diagnosticId))])]), MethodBodyStatement.Empty, provider); provider.Update(methods: [method]); provider.ProcessTypeForBackCompatibility(); @@ -223,7 +271,7 @@ public async Task DeprecationPreservesBackCompatOverloads(bool previouslyObsolet { Assert.AreEqual("\"Current message\"", previous.Signature.Attributes.Single(a => a.Type.Equals(typeof(ObsoleteAttribute))).Arguments.Single().ToDisplayString()); } - Assert.IsTrue(previous.Suppressions.Any(s => s.Code.ToDisplayString() == "\"CS0618\"")); + Assert.IsTrue(previous.Suppressions.Any(s => s.Code.ToDisplayString() == Snippet.Literal(diagnosticId ?? "CS0618").ToDisplayString())); } [Test] From 86cd139f9c3118245b6e1348be9199d952607782 Mon Sep 17 00:00:00 2001 From: Josh Love Date: Fri, 23 Oct 2026 22:08:13 -0700 Subject: [PATCH 7/9] fix(http-client-csharp): honor custom protocol diagnostic suppressions Include matching custom protocol declarations when collecting convenience call-site warnings and avoid inheriting partial modifiers onto ordinary convenience overloads. Cover sync/async obsolete, experimental, combined, and stable declarations plus a compiled sample. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../Providers/ScmMethodProviderCollection.cs | 17 ++++--- .../ScmMethodProviderCollectionTests.cs | 39 +++++++++++++++ .../TestClient.cs | 47 +++++++++++++++++++ .../Local.Tests/CustomizationTests.cs | 17 ++++++- .../src/Custom/DeprecationSamples.cs | 19 ++++++++ .../src/Generated/DeprecationSamples.cs | 14 +++--- 6 files changed, 139 insertions(+), 14 deletions(-) create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/CustomProtocolDiagnosticsAreSuppressedByConvenienceMethods/TestClient.cs create mode 100644 packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Custom/DeprecationSamples.cs diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs index 11268051f11..62560ffb104 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ScmMethodProviderCollection.cs @@ -300,12 +300,16 @@ .. GetStackVariablesForReturnValueConversion(result, responseBodyType, isAsync, var convenienceMethod = new ScmMethodProvider(methodSignature, methodBody, EnclosingType, ScmMethodKind.Convenience, collectionDefinition: collection, serviceMethod: ServiceMethod); ExperimentalApiHelpers.AddDependencySuppressions(convenienceMethod, ServiceMethod.Operation); - var obsoleteProtocol = protocolMethod.Signature.Attributes.FirstOrDefault(DeprecationApiHelpers.IsObsoleteAttribute); - if (obsoleteProtocol is not null) - { - convenienceMethod.Update(suppressions: ExperimentalApiHelpers.MergeSuppressions( - convenienceMethod.Suppressions, DeprecationApiHelpers.GetSuppressions(obsoleteProtocol))); - } + var customProtocol = client.CustomCodeView?.Methods.FirstOrDefault(method => + MethodSignatureBase.SignatureComparer.Equals(method.Signature, protocolMethod.Signature)); + var declarationSuppressions = ExperimentalApiHelpers.GetAttributeSuppressions( + methodSignature.Attributes.Concat(customSignature?.Attributes ?? [])); + convenienceMethod.Update(suppressions: ExperimentalApiHelpers.MergeSuppressions( + convenienceMethod.Suppressions, + ExperimentalApiHelpers.GetAttributeSuppressions( + protocolMethod.Signature.Attributes.Concat(customProtocol?.Signature.Attributes ?? [])) + .ExceptBy(declarationSuppressions.Select(suppression => suppression.Code.ToDisplayString()), + suppression => suppression.Code.ToDisplayString()))); if (convenienceMethod.XmlDocs != null) { @@ -321,6 +325,7 @@ private MethodSignatureModifiers GetConvenienceMethodModifiers( MethodSignatureModifiers modifiers, IReadOnlyList signatureParameters) { + modifiers &= ~MethodSignatureModifiers.Partial; // The convenience method's public/internal accessibility follows the service method's // accessibility, independent of the protocol method. The protocol method may be internal // (e.g. when `@protocolAPI(false)` sets GenerateProtocolMethod to false) while the diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs index deea604668d..9cac5def7d2 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ScmMethodProviderCollectionTests.cs @@ -82,6 +82,45 @@ await MockHelpers.LoadMockGeneratorAsync(clients: () => [inputClient], m.Signature.Attributes.Single().Arguments.Single().ToDisplayString() == "\"Custom message\"")); } + [TestCase("Custom", "OBS001", "OBS002")] + [TestCase("WithoutMessage", null, null)] + [TestCase("Preview", "EXP001", "EXP002")] + [TestCase("Combined", "OBS001", "OBS002")] + [TestCase("Current", "", "")] + public async Task CustomProtocolDiagnosticsAreSuppressedByConvenienceMethods(string name, string? syncId, string? asyncId) + { + var operation = InputFactory.Operation(name); + var serviceMethod = InputFactory.BasicServiceMethod(name, operation); + var inputClient = InputFactory.Client("TestClient", methods: [serviceMethod]); + await MockHelpers.LoadMockGeneratorAsync(clients: () => [inputClient], + compilation: () => Helpers.GetCompilationFromDirectoryAsync()); + var client = ScmCodeModelGenerator.Instance.TypeFactory.CreateClient(inputClient)!; + var methods = new ScmMethodProviderCollection(serviceMethod, client); + + Assert.AreEqual(4, methods.Count); + foreach (var protocol in methods.Where(method => method.Kind == ScmMethodKind.Protocol)) + { + Assert.IsTrue(protocol.IsPartialMethod); + Assert.IsEmpty(protocol.Signature.Attributes); + } + foreach (var method in methods.Where(method => method.Kind == ScmMethodKind.Convenience)) + { + var isAsync = method.Signature.Name.EndsWith("Async", StringComparison.Ordinal); + var diagnosticId = isAsync ? asyncId : syncId; + string[] expected = diagnosticId switch + { + null => ["CS0612", "CS0618"], + "" => [], + _ when name == "Combined" => [isAsync ? "EXP002" : "EXP001", diagnosticId], + _ => [diagnosticId] + }; + Assert.IsEmpty(method.Signature.Attributes); + CollectionAssert.AreEqual(expected.Select(id => Snippet.Literal(id).ToDisplayString()), + method.Suppressions.Select(suppression => suppression.Code.ToDisplayString())); + Assert.IsFalse(method.IsPartialMethod); + } + } + [Test] public async Task DeprecationPreservesLastContractMethods() { diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/CustomProtocolDiagnosticsAreSuppressedByConvenienceMethods/TestClient.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/CustomProtocolDiagnosticsAreSuppressedByConvenienceMethods/TestClient.cs new file mode 100644 index 00000000000..1187ce0edda --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/TestData/ScmMethodProviderCollectionTests/CustomProtocolDiagnosticsAreSuppressedByConvenienceMethods/TestClient.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; + +namespace Sample +{ + public partial class TestClient + { + [Obsolete("Unrelated overload.", DiagnosticId = "OTHER001")] + public ClientResult Current(int value) => throw new NotSupportedException(); + + [Obsolete("Use Current instead.", DiagnosticId = "OBS001")] + public partial ClientResult Custom(RequestOptions customOptions); + + [Obsolete("Use CurrentAsync instead.", DiagnosticId = "OBS002")] + public partial Task CustomAsync(RequestOptions customOptions); + + [Obsolete] + public partial ClientResult WithoutMessage(RequestOptions customOptions); + + [Obsolete] + public partial Task WithoutMessageAsync(RequestOptions customOptions); + + [Experimental("EXP001")] + public partial ClientResult Preview(RequestOptions customOptions); + + [Experimental("EXP002")] + public partial Task PreviewAsync(RequestOptions customOptions); + + [Experimental("EXP001")] + [Obsolete("Use Current instead.", DiagnosticId = "OBS001")] + public partial ClientResult Combined(RequestOptions customOptions); + + [Experimental("EXP002")] + [Obsolete("Use CurrentAsync instead.", DiagnosticId = "OBS002")] + public partial Task CombinedAsync(RequestOptions customOptions); + + public partial ClientResult Current(RequestOptions customOptions); + + public partial Task CurrentAsync(RequestOptions customOptions); + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs b/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs index f931e589101..2f7b2b6c9b4 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local.Tests/CustomizationTests.cs @@ -31,8 +31,6 @@ public void DeprecatedTypesPreserveWarningOnlyMessages(string typeName, string? [TestCase("Legacy", "Use \"read\" instead.\nSee C:\\sdk.")] [TestCase("LegacyAsync", "Use \"read\" instead.\nSee C:\\sdk.")] - [TestCase("Read", null)] - [TestCase("ReadAsync", null)] public void DeprecatedOperationsPreserveWarningOnlyMessages(string methodName, string? message) { var methods = typeof(SampleTypeSpecClient).Assembly.GetType("SampleTypeSpec.DeprecationSamples")! @@ -49,6 +47,21 @@ public void DeprecatedOperationsPreserveWarningOnlyMessages(string methodName, s } } + [TestCase("Read", "OBS001")] + [TestCase("ReadAsync", "OBS002")] + public void CustomProtocolDeprecationDoesNotDeprecateConvenienceOverload(string methodName, string diagnosticId) + { + var methods = typeof(DeprecationSamples).GetMethods().Where(method => method.Name == methodName).ToArray(); + Assert.AreEqual(2, methods.Length); + var protocol = methods.Single(method => method.GetParameters().Last().ParameterType == typeof(RequestOptions)); + var obsolete = protocol.GetCustomAttribute(); + Assert.IsNotNull(obsolete); + Assert.AreEqual(diagnosticId, obsolete!.DiagnosticId); + Assert.AreEqual("Use the convenience overload instead.", obsolete.Message); + Assert.IsFalse(obsolete.IsError); + Assert.IsNull(methods.Single(method => method != protocol).GetCustomAttribute()); + } + [TestCase("GetNotebookResult", "GetNotebookResponse", true)] [TestCase("GetWidgetMetricsResult", "GetWidgetMetricsResponse", true)] [TestCase("ListWithContinuationTokenHeaderResponseResult", "ListWithContinuationTokenHeaderResponseResponse", false)] diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Custom/DeprecationSamples.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Custom/DeprecationSamples.cs new file mode 100644 index 00000000000..21e84858584 --- /dev/null +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Custom/DeprecationSamples.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading.Tasks; + +namespace SampleTypeSpec +{ + public partial class DeprecationSamples + { + [Obsolete("Use the convenience overload instead.", DiagnosticId = "OBS001")] + public partial ClientResult Read(RequestOptions options); + + [Obsolete("Use the convenience overload instead.", DiagnosticId = "OBS002")] + public partial Task ReadAsync(RequestOptions options); + } +} diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs index e3975d430ff..163742f29b3 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/DeprecationSamples.cs @@ -109,8 +109,7 @@ public virtual async Task> LegacyAsync(CancellationT /// /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// Service returned a non-success status code. - /// The response returned from the service. - public virtual ClientResult Read(RequestOptions options) + public partial ClientResult Read(RequestOptions options) { using PipelineMessage message = CreateReadRequest(options); return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options)); @@ -126,8 +125,7 @@ public virtual ClientResult Read(RequestOptions options) /// /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// Service returned a non-success status code. - /// The response returned from the service. - public virtual async Task ReadAsync(RequestOptions options) + public partial async Task ReadAsync(RequestOptions options) { using PipelineMessage message = CreateReadRequest(options); return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); @@ -136,19 +134,23 @@ public virtual async Task ReadAsync(RequestOptions options) /// Read. /// The cancellation token that can be used to cancel the operation. /// Service returned a non-success status code. - public virtual ClientResult Read(CancellationToken cancellationToken = default) +#pragma warning disable OBS001 // This generated code references obsolete functionality. + public ClientResult Read(CancellationToken cancellationToken = default) { ClientResult result = Read(cancellationToken.ToRequestOptions()); return ClientResult.FromValue((CurrentDetails)result, result.GetRawResponse()); } +#pragma warning restore OBS001 // This generated code references obsolete functionality. /// Read. /// The cancellation token that can be used to cancel the operation. /// Service returned a non-success status code. - public virtual async Task> ReadAsync(CancellationToken cancellationToken = default) +#pragma warning disable OBS002 // This generated code references obsolete functionality. + public async Task> ReadAsync(CancellationToken cancellationToken = default) { ClientResult result = await ReadAsync(cancellationToken.ToRequestOptions()).ConfigureAwait(false); return ClientResult.FromValue((CurrentDetails)result, result.GetRawResponse()); } +#pragma warning restore OBS002 // This generated code references obsolete functionality. } } From 9b34b26015efd1791414738b0d766ea74df1ce59 Mon Sep 17 00:00:00 2001 From: Josh Love Date: Fri, 23 Oct 2026 23:02:10 -0700 Subject: [PATCH 8/9] fix(http-client-csharp): reindex providers after identity changes Remove mutable type-map keys before name or namespace updates and reinsert owned mappings afterward. Refresh serialization caches so renamed enum helpers retain warning suppressions and final identities. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../ClientProviders/ClientProviderTests.cs | 15 +++++ .../EnumProviderSerializationTests.cs | 20 +++++++ ...FixedEnumKeepsSerializationSuppressions.cs | 34 ++++++++++++ .../src/Providers/TypeProvider.cs | 2 +- .../src/TypeFactory.cs | 35 ++++++++++++ .../test/TypeFactoryTests.cs | 55 +++++++++++++++++++ 6 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/EnumProvider/TestData/EnumProviderSerializationTests/RenamedDeprecatedFixedEnumKeepsSerializationSuppressions.cs diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderTests.cs index 2ed8a130065..ddbaa636d59 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderTests.cs @@ -32,6 +32,21 @@ namespace Microsoft.TypeSpec.Generator.ClientModel.Tests.Providers.ClientProvide { public class ClientProviderTests { + [Test] + public void ClientProviderLookupFollowsIdentityUpdates() + { + var input = InputFactory.Client("OriginalClient"); + MockHelpers.LoadMockGenerator(clients: () => [input]); + var factory = ScmCodeModelGenerator.Instance.TypeFactory; + var client = factory.CreateClient(input)!; + var originalIdentity = client.Type.WithNullable(true); + + client.Update(name: "RenamedClient", @namespace: "Renamed"); + + Assert.IsFalse(factory.CSharpTypeMap.ContainsKey(originalIdentity)); + Assert.AreSame(client, factory.CSharpTypeMap[client.Type.WithNullable(true)]); + } + [TestCase(false)] [TestCase(true)] public async Task ExperimentalPolyfilledCustomDeclarationsCompile(bool sourceAnnotated) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/EnumProvider/EnumProviderSerializationTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/EnumProvider/EnumProviderSerializationTests.cs index 39ab108a297..b0a08642101 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/EnumProvider/EnumProviderSerializationTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/EnumProvider/EnumProviderSerializationTests.cs @@ -6,6 +6,7 @@ using System.Linq; using Microsoft.TypeSpec.Generator.Expressions; using Microsoft.TypeSpec.Generator.Input; +using Microsoft.TypeSpec.Generator.Primitives; using Microsoft.TypeSpec.Generator.Providers; using Microsoft.TypeSpec.Generator.Statements; using Microsoft.TypeSpec.Generator.Tests.Common; @@ -21,6 +22,25 @@ public void Setup() MockHelpers.LoadMockGenerator(); } + [TestCase(false)] + [TestCase(true)] + public void RenamedDeprecatedFixedEnumKeepsSerializationSuppressions(bool buildBeforeRename) + { + var input = InputFactory.StringEnum("LegacyChoice", [("One", "one")], deprecation: "Use CurrentChoice instead."); + MockHelpers.LoadMockGenerator(inputEnums: () => [input]); + var provider = ScmCodeModelGenerator.Instance.TypeFactory.CreateEnum(input)!; + if (buildBeforeRename) + { + provider.EnsureBuilt(); + _ = new TypeProviderWriter(provider.SerializationProviders.Single()).Write(); + } + + provider.Update(name: "RenamedChoice", @namespace: "Renamed.Models"); + provider.ProcessTypeForBackCompatibility(); + + Assert.AreEqual(Helpers.GetExpectedFromFile(), new TypeProviderWriter(provider.SerializationProviders.Single()).Write().Content); + } + private static object[] ValidateTypes(bool isExtensible) { var intType = InputFactory.Int32Enum( diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/EnumProvider/TestData/EnumProviderSerializationTests/RenamedDeprecatedFixedEnumKeepsSerializationSuppressions.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/EnumProvider/TestData/EnumProviderSerializationTests/RenamedDeprecatedFixedEnumKeepsSerializationSuppressions.cs new file mode 100644 index 00000000000..5d40e05aaa3 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/EnumProvider/TestData/EnumProviderSerializationTests/RenamedDeprecatedFixedEnumKeepsSerializationSuppressions.cs @@ -0,0 +1,34 @@ +// + +#nullable disable + +using System; + +namespace Renamed.Models +{ + internal static partial class RenamedChoiceExtensions + { +#pragma warning disable CS0612 // This generated code references obsolete functionality. +#pragma warning disable CS0618 // This generated code references obsolete functionality. + public static string ToSerialString(this global::Renamed.Models.RenamedChoice value) => value switch + { + global::Renamed.Models.RenamedChoice.One => "one", + _ => throw new global::System.ArgumentOutOfRangeException(nameof(value), value, "Unknown RenamedChoice value.") + }; +#pragma warning restore CS0612 // This generated code references obsolete functionality. +#pragma warning restore CS0618 // This generated code references obsolete functionality. + +#pragma warning disable CS0612 // This generated code references obsolete functionality. +#pragma warning disable CS0618 // This generated code references obsolete functionality. + public static global::Renamed.Models.RenamedChoice ToRenamedChoice(this string value) + { + if (global::System.StringComparer.OrdinalIgnoreCase.Equals(value, "one")) + { + return global::Renamed.Models.RenamedChoice.One; + } + throw new global::System.ArgumentOutOfRangeException(nameof(value), value, "Unknown RenamedChoice value."); + } +#pragma warning restore CS0612 // This generated code references obsolete functionality. +#pragma warning restore CS0618 // This generated code references obsolete functionality. + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs index bb57ab4230a..e1a53bfacd1 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs @@ -1040,7 +1040,7 @@ private void ResetMembersBasedOnIdentityChange(string? name = null, string? @nam ResetConstructors(); // serialization providers need to reflect the new type name/namespace _serializationProviders = null; - Type.Update(name: name, @namespace: @namespace); + CodeModelGenerator.Instance.TypeFactory.UpdateTypeIdentity(this, _inputType, name, @namespace); if (Type.Name != previousName || Type.Namespace != previousNamespace) { OnIdentityUpdated(previousName, previousNamespace); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs index 36de7c6666b..a3afa4bcb82 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs @@ -52,6 +52,41 @@ protected internal TypeFactory() { } + internal void UpdateTypeIdentity(TypeProvider provider, InputType? inputType, string name, string @namespace) + { + var type = provider.Type; + if (type.Name == name && type.Namespace == @namespace) + { + return; + } + var mappedType = CSharpTypeMap.TryGetValue(type, out var mappedProvider) && ReferenceEquals(mappedProvider, provider); + var mappedName = TypeProvidersByName.TryGetValue(type.Name, out var namedProvider) && ReferenceEquals(namedProvider, provider); + // Remove mutable keys before changing their hash or lookup identity. + if (mappedType) + { + CSharpTypeMap.Remove(type); + } + if (mappedName) + { + TypeProvidersByName.Remove(type.Name); + } + + type.Update(name: name, @namespace: @namespace); + + if (mappedType) + { + CSharpTypeMap[type] = provider; + } + if (mappedName) + { + TypeProvidersByName[type.Name] = provider; + } + if (inputType is not null) + { + SerializationsCache.Remove(inputType); + } + } + internal CSharpType? CreateLastContractModelBase(CSharpType previousBase, InputModelType currentModel) => CreateLastContractModelBaseCore(previousBase, currentModel); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs index ab522763a9c..707ea30e923 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs @@ -22,6 +22,61 @@ public void SetUp() MockHelpers.LoadMockGenerator(); } + [Test] + public void ProviderLookupFollowsIdentityUpdates( + [Values("model", "fixed", "extensible")] string kind, + [Values] bool changeNamespace) + { + var factory = CodeModelGenerator.Instance.TypeFactory; + TypeProvider provider = kind == "model" + ? factory.CreateModel(InputFactory.Model("Original"))! + : factory.CreateEnum(InputFactory.StringEnum("Original", [("One", "one")], isExtensible: kind == "extensible"))!; + var unrelated = factory.CreateModel(InputFactory.Model("Unrelated"))!; + var originalIdentity = provider.Type.WithNullable(true); + var count = factory.CSharpTypeMap.Count; + Assert.AreSame(provider, factory.CSharpTypeMap[provider.Type]); + + provider.Update( + name: changeNamespace ? null : "Renamed", + @namespace: changeNamespace ? "Renamed.Models" : null); + + Assert.AreEqual(count, factory.CSharpTypeMap.Count); + Assert.IsFalse(factory.CSharpTypeMap.ContainsKey(originalIdentity)); + Assert.AreSame(provider, factory.CSharpTypeMap[provider.Type]); + Assert.AreSame(provider, factory.CSharpTypeMap[provider.Type.WithNullable(true)]); + Assert.AreSame(provider, factory.TypeProvidersByName[provider.Name]); + Assert.AreSame(unrelated, factory.CSharpTypeMap[unrelated.Type]); + Assert.AreSame(unrelated, factory.TypeProvidersByName[unrelated.Name]); + if (!changeNamespace) + { + Assert.IsFalse(factory.TypeProvidersByName.ContainsKey("Original")); + } + + provider.Update(name: "Final", @namespace: "Final.Models"); + + Assert.AreEqual(count, factory.CSharpTypeMap.Count); + Assert.AreSame(provider, factory.CSharpTypeMap[provider.Type.WithNullable(true)]); + Assert.IsFalse(factory.TypeProvidersByName.ContainsKey(changeNamespace ? "Original" : "Renamed")); + Assert.AreSame(provider, factory.TypeProvidersByName["Final"]); + } + + [Test] + public void UnregisteredIdentityUpdatesDoNotReplaceMappedProviders() + { + var factory = CodeModelGenerator.Instance.TypeFactory; + var registered = factory.CreateModel(InputFactory.Model("Original", @namespace: "Test"))!; + var unregistered = new TestTypeProvider(name: "Original"); + var count = factory.CSharpTypeMap.Count; + + unregistered.Update(name: "Renamed", @namespace: "Renamed.Models"); + + Assert.AreEqual(count, factory.CSharpTypeMap.Count); + Assert.AreSame(registered, factory.CSharpTypeMap[registered.Type]); + Assert.AreSame(registered, factory.TypeProvidersByName[registered.Name]); + Assert.IsFalse(factory.CSharpTypeMap.ContainsKey(unregistered.Type)); + Assert.IsFalse(factory.TypeProvidersByName.ContainsKey(unregistered.Name)); + } + [Test] public void ExtensibleStringEnumType() { From 60343df6a2c0f4c05a4f959f9d44616d8dc0555a Mon Sep 17 00:00:00 2001 From: Josh Love Date: Fri, 23 Oct 2026 23:55:29 -0700 Subject: [PATCH 9/9] fix(http-client-csharp): apply type identity changes atomically Resolve name and namespace together so provider reindexing never overwrites an unrelated intermediate identity. Cover models and both enum forms with retained warning lookup. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../src/Providers/TypeProvider.cs | 9 ++---- .../test/TypeFactoryTests.cs | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs index e1a53bfacd1..9229f859942 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs @@ -1004,14 +1004,9 @@ public void Update( _attributes = [.. attributes]; } - if (name != null) + if (name != null || @namespace != null) { - ResetMembersBasedOnIdentityChange(name); - } - - if (@namespace != null) - { - ResetMembersBasedOnIdentityChange(@namespace: @namespace); + ResetMembersBasedOnIdentityChange(name, @namespace); } RefreshGeneratedDeprecationAttribute(); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs index 707ea30e923..385c4fec39e 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net; using System.Text.Json; using System.Threading.Tasks; @@ -10,6 +11,7 @@ using Microsoft.TypeSpec.Generator.Primitives; using Microsoft.TypeSpec.Generator.Providers; using Microsoft.TypeSpec.Generator.Tests.Common; +using Microsoft.TypeSpec.Generator.Utilities; using NUnit.Framework; namespace Microsoft.TypeSpec.Generator.Tests @@ -77,6 +79,36 @@ public void UnregisteredIdentityUpdatesDoNotReplaceMappedProviders() Assert.IsFalse(factory.TypeProvidersByName.ContainsKey(unregistered.Name)); } + [TestCase("model")] + [TestCase("fixed")] + [TestCase("extensible")] + public void CombinedIdentityUpdateDoesNotReplaceIntermediateProvider(string kind) + { + var factory = CodeModelGenerator.Instance.TypeFactory; + TypeProvider CreateProvider(string name) => kind == "model" + ? factory.CreateModel(InputFactory.Model(name, @namespace: "Alpha.Models", deprecation: "Use Current instead."))! + : factory.CreateEnum(InputFactory.StringEnum(name, [("One", "one")], + clientNamespace: "Alpha.Models", isExtensible: kind == "extensible", deprecation: "Use Current instead."))!; + var moving = CreateProvider("Original"); + var untouched = CreateProvider("Existing"); + var originalIdentity = moving.Type.WithNullable(true); + var untouchedIdentity = untouched.Type.WithNullable(true); + var count = factory.CSharpTypeMap.Count; + + moving.Update(name: "Existing", @namespace: "Beta.Models"); + + Assert.AreEqual(count, factory.CSharpTypeMap.Count); + Assert.AreSame(moving, factory.CSharpTypeMap[moving.Type.WithNullable(true)]); + Assert.AreSame(untouched, factory.CSharpTypeMap[untouchedIdentity]); + Assert.IsFalse(factory.CSharpTypeMap.ContainsKey(originalIdentity)); + Assert.AreEqual("Alpha.Models", untouched.Type.Namespace); + Assert.AreEqual("Existing", untouched.Name); + CollectionAssert.AreEqual(new[] { "\"CS0612\"", "\"CS0618\"" }, + ExperimentalApiHelpers.GetReferenceSuppressions(untouchedIdentity).Select(suppression => suppression.Code.ToDisplayString())); + CollectionAssert.AreEqual(new[] { "\"CS0612\"", "\"CS0618\"" }, + ExperimentalApiHelpers.GetReferenceSuppressions(moving.Type).Select(suppression => suppression.Code.ToDisplayString())); + } + [Test] public void ExtensibleStringEnumType() {